Skip to content

Detect attempts to override prohibited NamedTuple attributes #1684

@AlexWaygood

Description

@AlexWaygood

For example:

>>> from typing import NamedTuple
>>> class F(NamedTuple):
...     _asdict = 42
...     
Traceback (most recent call last):
  File "<python-input-5>", line 1, in <module>
    class F(NamedTuple):
        _asdict = 42
  File "/Users/alexw/Library/Application Support/uv/python/cpython-3.14.0-macos-aarch64-none/lib/python3.14/typing.py", line 3004, in __new__
    raise AttributeError("Cannot overwrite NamedTuple attribute " + key)
AttributeError: Cannot overwrite NamedTuple attribute _asdict

This is separate to the check being added in astral-sh/ruff#21697 because _asdict here is not considered a NamedTuple field either by ty or at runtime (it doesn't have a type annotation). Most assignments in NamedTuple class bodies work fine, even if the assigned symbol has a leading underscore, as long as they don't have type annotations:

>>> from typing import NamedTuple
>>> class G(NamedTuple):
...     _whatever = 42
...     
>>> 

_asdict, however, is a synthesized method present on all NamedTuple classes, and users are not allowed to override it. The full list of prohibited overrides is at https://github.com/python/cpython/blob/77399436bfc87663f9058b749b6cb598bab273f9/Lib/typing.py#L2939-L2942.

Mypy detects this, though pyright and pyrefly do not at time of writing.

Metadata

Metadata

Assignees

Labels

namedtuplesruntime semanticsAccurate modeling of how Python's semantics work at runtime

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions