Description
Sender.send_message writes message["From"] directly onto the caller-supplied EmailMessage when the header is absent. EmailMessage.__setitem__ appends a header rather than replacing it, so a second call with the same message object yields an RFC 5322 message with two From lines, which many SMTP servers reject. Even on the first call, the side effect violates the principle of least surprise: passing a message to send_message should not modify it.
Location
email_profile/clients/smtp/sender.py line ~82
Current Behavior
def send_message(self, message: EmailMessage, *, save_to_sent: bool = True) -> None:
if not message.get("From"):
message["From"] = self._session.user
...
Reusing the same message instance (e.g. retrying a failed send) produces:
From: original@example.com
From: account@example.com
Expected Behavior
The function should not mutate its input. Either copy the message before adding headers, or refuse to send when From is missing.
Suggested Fix
import copy
def send_message(self, message: EmailMessage, *, save_to_sent: bool = True) -> None:
if not message.get("From"):
message = copy.deepcopy(message)
message["From"] = self._session.user
...
Or, more strictly:
if not message.get("From"):
raise ValueError("EmailMessage requires a 'From' header.")
Impact
- Retries after transient SMTP failures duplicate the
From header and may be rejected as malformed.
- Callers cannot safely reuse
EmailMessage instances across calls or persist them between sends.
- Hidden mutation makes the function harder to compose.
Priority
High
Description
Sender.send_messagewritesmessage["From"]directly onto the caller-suppliedEmailMessagewhen the header is absent.EmailMessage.__setitem__appends a header rather than replacing it, so a second call with the same message object yields an RFC 5322 message with twoFromlines, which many SMTP servers reject. Even on the first call, the side effect violates the principle of least surprise: passing a message tosend_messageshould not modify it.Location
email_profile/clients/smtp/sender.pyline ~82Current Behavior
Reusing the same
messageinstance (e.g. retrying a failed send) produces:Expected Behavior
The function should not mutate its input. Either copy the message before adding headers, or refuse to send when
Fromis missing.Suggested Fix
Or, more strictly:
Impact
Fromheader and may be rejected as malformed.EmailMessageinstances across calls or persist them between sends.Priority
High