From 86d93a26bd6807b3c58e793e6c53d8a9d70473b6 Mon Sep 17 00:00:00 2001 From: TheMuffinMan1320 <76186189+TheMuffinMan1320@users.noreply.github.com> Date: Thu, 13 Aug 2026 14:48:29 -0500 Subject: [PATCH] Fix crash on dataclass field assigned a functional namedtuple() call (#21583) When a dataclass field's default value is a `namedtuple('Name', ...)` call, the semantic analyzer treats the assignment as a NamedTuple class definition and binds the field's name to a TypeInfo instead of a Var, regardless of any type annotation on the left-hand side. The dataclass plugin's collect_attributes() assumed every non-alias, non-decorator symbol table node was a Var and asserted so, crashing when it encountered this TypeInfo. Skip such fields the same way TypeAlias/Decorator nodes are already skipped, since they aren't valid dataclass fields. Fixes #21583 --- mypy/plugins/dataclasses.py | 4 ++++ test-data/unit/check-dataclasses.test | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/mypy/plugins/dataclasses.py b/mypy/plugins/dataclasses.py index a511e714ac6b4..09341bc453c23 100644 --- a/mypy/plugins/dataclasses.py +++ b/mypy/plugins/dataclasses.py @@ -599,6 +599,10 @@ def collect_attributes(self) -> list[DataclassAttribute] | None: # This might be a property / field name clash. # We will issue an error later. continue + if isinstance(node, TypeInfo): + # The declared type is shadowed by a class created from a call like + # `x: Foo = namedtuple('Foo', [...])`, so there is no dataclass field here. + continue assert isinstance(node, Var), node diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index f43ac255373e6..1a81750e3e01f 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -2746,6 +2746,19 @@ class B2(B1): # E: A NamedTuple cannot be a dataclass [builtins fixtures/tuple.pyi] +[case testNoCrashForDataclassFieldAssignedFunctionalNamedTuple] +from collections import namedtuple +from dataclasses import dataclass + +@dataclass +class C: + p: "Point" = namedtuple("Point", ["x", "y"]) # E: First argument to namedtuple() should be "p", not "Point" + +@dataclass +class D: + Point: "Point" = namedtuple("Point", ["x", "y"]) +[builtins fixtures/tuple.pyi] + [case testDataclassesTypeGuard] import dataclasses