Skip to content

Fix TypeError from unconditional strict= kwarg on old Python patch releases#162

Open
mkilijanek wants to merge 1 commit into
SpamScope:developfrom
mkilijanek:fix/getaddresses-strict-kwarg-compat
Open

Fix TypeError from unconditional strict= kwarg on old Python patch releases#162
mkilijanek wants to merge 1 commit into
SpamScope:developfrom
mkilijanek:fix/getaddresses-strict-kwarg-compat

Conversation

@mkilijanek

Copy link
Copy Markdown

Summary

get_addresses() unconditionally passes strict=True to email.utils.getaddresses(). That keyword only exists as part of the CVE-2023-27043 hardening, and CPython backported it to patch releases >=3.10.15, >=3.11.10, >=3.12.6 — not to every release within those minor versions. On an older patch release (e.g. 3.11.3), calling get_addresses() for any address header raises:

TypeError: getaddresses() got an unexpected keyword argument 'strict'

which breaks address parsing entirely on that interpreter (and, transitively, any project depending on mail-parser to parse address headers on such a host).

Reported via a downstream consumer (parsedmarc): domainaware/parsedmarc#808

Fix

email.utils.supports_strict_parsing is the stdlib's own capability flag for this hardening (present and True on the patched releases above). get_addresses() now checks it and only passes strict=True when the running interpreter actually supports it, falling back to the pre-hardening call signature (getaddresses([raw_header])) otherwise. Everything else — the existing regex fallback for RFC-non-compliant display names, Header handling, etc. — is unaffected on interpreters that do support strict parsing, which is the common case in CI and production.

Test plan

  • Added test_get_addresses_omits_strict_kwarg_when_unsupported and test_get_addresses_uses_strict_kwarg_when_supported to tests/test_utils.py, both mocking email.utils.getaddresses/email.utils.supports_strict_parsing to assert the exact call signature used in each case.
  • uv run pytest tests/ — 212 passed (full suite, including the outlook extra).
  • uv run ruff check . / uv run ruff format --check . — clean.
  • pre-commit run --all-files on the touched files — all hooks pass, including the pyright hook.

…support it

email.utils.getaddresses() only gained the strict= keyword as part of
the CVE-2023-27043 hardening, and it was backported to patch releases
>=3.10.15, >=3.11.10, >=3.12.6 rather than to every release across
those minor versions. get_addresses() passed strict=True
unconditionally, so on an older patch release within an otherwise
supported minor version this raised:

    TypeError: getaddresses() got an unexpected keyword argument
    'strict'

for every address header, breaking mail-parser entirely on those
interpreters. email.utils.supports_strict_parsing is the stdlib's own
capability flag for this hardening; get_addresses() now checks it and
only passes strict= when the running interpreter actually supports it,
falling back to the pre-hardening call signature otherwise. The
existing regex fallback for RFC-non-compliant display names, and every
other code path, is unaffected on interpreters that do support strict
parsing (the common case in CI and production).

Reported via a downstream consumer, parsedmarc:
domainaware/parsedmarc#808
mkilijanek added a commit to mkilijanek/parsedmarc-core that referenced this pull request Jul 14, 2026
mailparser.parse_from_string() unconditionally passes strict=True to
email.utils.getaddresses(), which only exists on Python patch releases
>=3.10.15, >=3.11.10, >=3.12.6 (the CVE-2023-27043 backports). On an
older patch release within an otherwise-supported minor version, this
raises TypeError: getaddresses() got an unexpected keyword argument
'strict' -- and parsedmarc's existing broad exception handlers silently
turned that into a generic "invalid report" error, with nothing
indicating the real cause was an outdated Python patch release rather
than a bad report.

_mailparser_parse_from_string() now catches this specific TypeError,
gated on email.utils.supports_strict_parsing so unrelated TypeErrors
still pass through untouched, and re-raises as EmailParserError naming
the required Python versions. The existing catch-alls in
parse_report_email() and parse_failure_report() already embed the
inner exception's message into their own, so the clearer text reaches
operators with no other control-flow changes.

The real fix belongs upstream in mail-parser: filed as
SpamScope/mail-parser#162 (open, not yet merged as of this commit).
This is a workaround for parsedmarc users in the meantime.

Fixes domainaware#808.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mkilijanek mkilijanek force-pushed the fix/getaddresses-strict-kwarg-compat branch from 027b747 to 8fc164d Compare July 14, 2026 10:41
@seanthegeek

Copy link
Copy Markdown

Someone beat you to it. #161

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants