Skip to content

Named tuple's _replace() method should raise TypeError for unexpected keyword arguments #110275

Closed

Description

@serhiy-storchaka

Bug report

When you call a function with incorrect key arguments, you get a TypeError. But it is not always so with the _replace() method of a named tuple class created by collections.namedtuple().

>>> from collections import namedtuple
>>> P = namedtuple('P', 'x y')
>>> p = P(1, 2)
>>> p._replace(z=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/serhiy/py/cpython/Lib/collections/__init__.py", line 460, in _replace
    raise ValueError(f'Got unexpected field names: {list(kwds)!r}')
ValueError: Got unexpected field names: ['z']

It is not even consistent with constructor which raises TypeError:

>>> P(x=1, y=2, z=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: P.__new__() got an unexpected keyword argument 'z'

I think that _replace() also should raise TypeError for unexpected keyword arguments.

cc @rhettinger

Linked PRs

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    type-bugAn unexpected behavior, bug, or error
    on Oct 3, 2023
  2. rhettinger commented on Oct 3, 2023

    @rhettinger
    Contributor

    Let's leave these APIs alone. They are old, stable, and have never caused an issue for real users.

  3. added a commit that references this issue on Oct 3, 2023
  4. serhiy-storchaka commented on Oct 3, 2023

    @serhiy-storchaka
    MemberAuthor

    Well, then I'll only change __replace__().

  5. rhettinger commented on Oct 4, 2023

    @rhettinger
    Contributor

    Well, then I'll only change replace().

    I wish you would just make the new code consistent with the existing replace implementations. Aim for the least invasive and least disruptive way to add your new function.

    But if you're going to persist forcing through a TypeError, then go ahead and change _replace() as well. Better to have the two be harmonious and not introduce a permanent wart.

  6. serhiy-storchaka commented on Oct 9, 2023

    @serhiy-storchaka
    MemberAuthor

    What do you think about other changes that I took the opportunity to do in __replace__?

    1. Rename **kwds to **changes.
    2. Only include the first unexpected keyword argument name in the error message instead of the list. "Got unexpected field name: 'z'" instead of "Got unexpected field names: ['z']".

    They are less important, so I do not persist.

  7. added a commit that references this issue on Dec 4, 2023
  8. added a commit that references this issue on Feb 11, 2024
  9. added a commit that references this issue on Sep 2, 2024
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/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions