python / python/cpython

email.message.Message.add_header behavior differs from Message[header]=v

Open
#151,454 14 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Bug report

Bug description:

Attempting to copy headers from an existing message to a new (to-be-cleaned copy of the original) message, I iterated over the old message, using something like

for h, v in oldmsg.items():
    newmsg.add_header(h, v)

which works for many of the test-messages in my test Maildir folder, but errors out on certain messages with

    newmsg.add_header(h, v)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/local/lib/python3.13/email/message.py", line 587, in add_header
    self[_name] = SEMISPACE.join(parts)
                  ~~~~~~~~~~~~~~^^^^^^^
TypeError: sequence item 0: expected str instance, Header found

It appears that elements in msg.items() can produce a mixed-content list containing both (str, str) and (str, Header) elements; but add_header doesn't like receiving a Header object as a value, only str.

If I change it to use the .__setitem__() method function:

for h, v in oldmsg.items():
    newmsg[h] = v

it appears to work fine, appending the header that .items() gave me.

According to the .add_header() documentation, it should behave similar to the .__setitem__() method:

This method is similar to __setitem__() except that additional header parameters can be provided as keyword arguments. _name is the header field to add and _value is the primary value for the header.

The fix would involve making add_header accept the same sorts of Header values as __setitem__, or at least align the output of msg.items() with the types that msg.set_header() accepts. If not aligned, at a bare minimum, the documentation should reflect the difference in accepted value types (str vs Header)

This may also have tie-ins with similar Issues here:

  • #65294
  • #91957
  • #101090

(manifested on 3.13 on OpenBSD, but it's standard-library stuff that would likely manifest on any OS)

CPython versions tested on:

3.13

Operating systems tested on:

Other

Linked PRs
  • gh-151458

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

Review linked PR gh-151458 first, then inspect email/message.py around Message.add_header and compare it with Message.setitem and items(). Reproduce the mixed str/Header case from the report; done means the behavior is aligned or the accepted value-type difference is documented.

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
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.