python / python/cpython

EmailMessage().add_attachment() doesn't work for html files

Open
#91,863 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

stdlib topic-email type-bug
Dominant language
Python
Stars
77.2k
Forks
36k
PR merge metrics
PR metrics pending

Description

Bug report

I am trying to send a 1.5 MB .html file using from email.message import EmailMessage through the add_attachment method. If the filename ends in ".html", the email will not be sent, nor any warning/exception is raised.

This is the code that I am using:

message["From"] = sender_email
message["To"] = ", ".join(receiver_email)
message.set_content(text)

context = ssl.create_default_context()

for i, fn in enumerate([filename, mapname]):
    print("Processing filename", fn)
    with open(fn, "rb") as attachment:
        content = attachment.read()
        ctype, encoding = mimetypes.guess_type(fn)
        maintype, subtype = ctype.split("/", 1)
        message.add_attachment(
            content,
            maintype=maintype,
            subtype=subtype,
            filename=f"{i}_{fn}",
        )

with smtplib.SMTP_SSL("smtp.gmail.com", port, context=context) as server:
    server.login(sender_email, password)
    server.send_message(message)
    print("Sent!")

You see that I have two filenames, one is filename and the other one is mapname. filename is a csv file and mapname is an html file. If I only use the filename, the mail is sent. If I add mapname, the mail is not sent. If I only use mapname, the email is not sent either.

If the filename is changed: f"{i}_{fn.split('.')[0]}", so that the extension is removed, the email is sent! This shows that the HTML is not corrupt, it's just because of the extension! Also, I tried sending a simple html such as this one:

msg_content = """
<html><body>
  Hello world
</body></html>"""
content = bytes(msg_content, "utf-8")
ctype, encoding = mimetypes.guess_type("second.html")
maintype, subtype = ctype.split("/", 1)
message.add_attachment(
    content,
    maintype=maintype,
    subtype=subtype,
    filename="second.html",
)

And it still does not work.

Your environment

I'm using a virtual environment with Python version Python 3.9.10. The architecture is arm64. pip freeze shows:

absl-py==1.0.0
alembic==1.7.6
anyio==3.5.0
appnope==0.1.2
argon2-cffi==21.3.0
argon2-cffi-bindings==21.2.0
asttokens==2.0.5
attrs==21.4.0
autopage==0.5.0
Babel==2.9.1
backcall==0.2.0
beautifulsoup4==4.10.0
beniget==0.4.1
black==22.1.0
bleach==4.1.0
bokeh==2.4.2
certifi==2021.10.8
cffi==1.15.0
charset-normalizer==2.0.12
chex==0.1.1
click==8.0.4
cliff==3.10.1
cmaes==0.8.2
cmd2==2.4.0
colorlog==6.6.0
cycler==0.11.0
Cython==0.29.28
debugpy==1.5.1
decorator==5.1.1
defusedxml==0.7.1
dm-tree==0.1.6
dnspython==2.2.1
entrypoints==0.4
executing==0.8.3
flatbuffers==2.0
flax==0.4.0
fonttools==4.30.0
gast==0.5.3
idna==3.3
ipykernel==6.9.1
ipython==8.1.1
ipython-genutils==0.2.0
jedi==0.18.1
Jinja2==3.1.1
joblib==1.1.0
json5==0.9.6
jsonschema==4.4.0
jupyter-client==7.1.2
jupyter-core==4.9.2
jupyter-server==1.16.0
jupyterlab==3.3.2
jupyterlab-pygments==0.1.2
jupyterlab-server==2.12.0
kiwisolver==1.3.2
lightgbm==3.3.2
Mako==1.2.0
MarkupSafe==2.1.0
matplotlib==3.5.1
matplotlib-inline==0.1.3
miceforest==5.3.0
mistune==0.8.4
msgpack==1.0.3
mypy-extensions==0.4.3
nbclassic==0.3.7
nbclient==0.5.13
nbconvert==6.4.5
nbformat==5.2.0
nest-asyncio==1.5.4
notebook==6.4.10
notebook-shim==0.1.0
numpy==1.22.3
opt-einsum==3.3.0
optax==0.1.1
optuna==2.10.0
packaging==21.3
pandas==1.3.5
pandocfilters==1.5.0
parso==0.8.3
pathspec==0.9.0
pbr==5.8.1
pexpect==4.8.0
pickleshare==0.7.5
Pillow==9.0.1
platformdirs==2.5.1
ply==3.11
prettytable==3.2.0
prometheus-client==0.13.1
prompt-toolkit==3.0.28
ptyprocess==0.7.0
pure-eval==0.2.2
pybind11==2.9.1
pycparser==2.21
Pygments==2.11.2
pymongo==4.0.1
pyparsing==3.0.7
pyperclip==1.8.2
pyrsistent==0.18.1
python-dateutil==2.8.2
pythran==0.11.0
pytz==2021.3
PyYAML==6.0
pyzmq==22.3.0
requests==2.27.1
scipy==1.9.0.dev0+1659.2656ccb
Send2Trash==1.8.0
six==1.16.0
sniffio==1.2.0
soupsieve==2.3.1
SQLAlchemy==1.4.32
stack-data==0.2.0
stevedore==3.5.0
terminado==0.13.3
testpath==0.6.0
threadpoolctl==3.1.0
tomli==2.0.1
toolz==0.11.2
tornado==6.1
tqdm==4.63.0
traitlets==5.1.1
typing_extensions==4.1.1
urllib3==1.26.9
wcwidth==0.2.5
webencodings==0.5.1
websocket-client==1.3.2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the email.message.EmailMessage.add_attachment entry point and reproduce the report using the minimal HTML example, checking the filename and MIME type handling. Confirm the intended behavior for HTML attachments, then add regression coverage showing that an .html attachment is sent successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.