cpython icon indicating copy to clipboard operation
cpython copied to clipboard

`UnboundLocalError` in `email.message.Message.get_payload`

Open thib-d opened this issue 7 months ago • 6 comments

Bug report

Bug description:

    html_body = part.get_payload(decode=True).decode()
  File "/usr/local/lib/python3.8/email/message.py", line 282, in get_payload
    return quopri.decodestring(bpayload)

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

  • gh-136071

thib-d avatar May 26 '25 23:05 thib-d

The error is here: https://github.com/python/cpython/blob/96905bdd273d2e5724d2c1b6b0f95ecb0daeaabe/Lib/email/message.py#L316-L317

cc @bitdancer

picnixz avatar May 26 '25 23:05 picnixz

hi, can i work on this?

makridenko avatar May 27 '25 08:05 makridenko

Hello! I would like to work on it but did not work with CPython at all. Will it be a problem? If not where I should start with?

skv0zsneg avatar May 27 '25 08:05 skv0zsneg

Hi, @skv0zsneg and @makridenko! Thanks a lot for your interest.

@makridenko since you were first, you can surely work on this. Because it looks like that no one else has started yet.

@skv0zsneg we value new contributors, please, don't feel left out :) You can pick any other issue from the opened ones 🤝

sobolevn avatar May 27 '25 08:05 sobolevn

Hey everyone!

Trying to reproduce this bug UnboundLocalError but it want falling.

What I'm doing in REPL:

>>> raw_email = """Content-Type: text/plain; charset="utf-8"
... Content-Transfer-Encoding: quoted-printable
... 
... Hey!"""
>>> from email import message_from_string
>>> msg = message_from_string(raw_email)
>>> msg.get_payload(decode=True).decode()
'Hey!'
>>> msg._headers
[('Content-Type', 'text/plain; charset="utf-8"'), ('Content-Transfer-Encoding', 'quoted-printable')]

As mentioned by @picnixz, the error must be on line 317. To get here I use email message with quoted-printable encoding and body message surely get into quopri.decodestring but (luckly?) it does not fall. Am I miss something?

OS: Linux (Ubuntu 24.04.2 LTS) Python: Python 3.15.0a0

skv0zsneg avatar Jun 27 '25 19:06 skv0zsneg

The "bad" code path is only taken when payload is not a string, cte == 'quoted-printable' and decode is True. Considering there is

        if i is not None and not isinstance(self._payload, list):

We can't just use a list because if is_multipart() would return true and we would early exit. So we need to use a bytes payload with decode = True (I think).

picnixz avatar Jun 27 '25 21:06 picnixz