Skip to content

email.utils.collapse_rfc2231_value raises AttributeError on non-3-tuples #145824

Open

Description

@stefanzetzsche

Bug report

Bug description:

Issue

collapse_rfc2231_value raises AttributeError: 'tuple' object has no attribute 'startswith' when passed a tuple whose length is not 3. The guard if not isinstance(value, tuple) or len(value) != 3 is meant to handle this case, but falls through to unquote(value) which expects a string.

Reproducer

from email.utils import collapse_rfc2231_value
collapse_rfc2231_value(('a', 'b'))
# AttributeError: 'tuple' object has no attribute 'startswith'

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Linked PRs

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Mar 11, 2026
  2. picnixz commented on Mar 11, 2026

    @picnixz
    Member

    I don't think we should change the behavior here. First, it's not a crash but rather a GIGO case (garbage in, garbage out). The documentation says:

    For convenience, if the value passed to collapse_rfc2231_value() is not a tuple, it should be a string and it is returned unquoted.

    So returning the stringification of the tuple may not necessarily be correct. Instead, a TypeError should be raised if AttributeError is too cryptic IMO.

  3. changed the title [-]email.utils.collapse_rfc2231_value crashes with AttributeError on non-3-tuples[/-] [+]email.utils.collapse_rfc2231_value raises AttributeError on non-3-tuples[/+] on Mar 11, 2026
  4. stefanzetzsche commented on Mar 11, 2026

    @stefanzetzsche
    ContributorAuthor

    Thanks for the feedback! I appreciate this is a minor issue. I agree that a TypeError would be better than the AttributeError here.

    As for the documentation:

    (...) may return a 3-tuple (...) :func:collapse_rfc2231_value turns this into a unicode string.

    For convenience, if the value passed to collapse_rfc2231_value() is not a tuple, it should be a string and it is returned unquoted.

    It currently leaves implicit/undefined the case when the value passed is a tuple, but not a 3-tuple. I'm assuming "not a tuple" already means "not a 3-tuple" given the context, but making it explicit wouldn't hurt.

    I'll revise the PR accordingly.

  5. picnixz commented on Mar 11, 2026

    @picnixz
    Member

    Yeah, for me it was obvious that the "this" in "this into a unicode string" referred to "a 3-tuple" returned by the other function. I'd be more in favor of (1) having a TypeError (2) and a doc clarification if necessary.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-emailtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions