Skip to content

Commit 1882ed7

Browse files
authored
Have namedtuple __replace__ return Self (#17475)
1 parent cb7b96d commit 1882ed7

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

mypy/semanal_namedtuple.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
TYPED_NAMEDTUPLE_NAMES,
5858
AnyType,
5959
CallableType,
60+
Instance,
6061
LiteralType,
6162
TupleType,
6263
Type,
@@ -631,9 +632,10 @@ def add_method(
631632
args=[Argument(var, var.type, EllipsisExpr(), ARG_NAMED_OPT) for var in vars],
632633
)
633634
if self.options.python_version >= (3, 13):
635+
type_vars = [tv for tv in info.defn.type_vars]
634636
add_method(
635637
"__replace__",
636-
ret=None,
638+
ret=Instance(info, type_vars),
637639
args=[Argument(var, var.type, EllipsisExpr(), ARG_NAMED_OPT) for var in vars],
638640
)
639641

test-data/unit/check-namedtuple.test

+15-1
Original file line numberDiff line numberDiff line change
@@ -1407,9 +1407,23 @@ from typing import NamedTuple
14071407
class A(NamedTuple):
14081408
x: int
14091409

1410-
A(x=0).__replace__(x=1)
1410+
replaced = A(x=0).__replace__(x=1)
1411+
reveal_type(replaced) # N: Revealed type is "__main__.A"
1412+
14111413
A(x=0).__replace__(x="asdf") # E: Argument "x" to "__replace__" of "A" has incompatible type "str"; expected "int"
14121414
A(x=0).__replace__(y=1) # E: Unexpected keyword argument "y" for "__replace__" of "A"
1415+
1416+
from typing import TypeVar, Generic
1417+
1418+
T = TypeVar("T")
1419+
1420+
class GenericA(NamedTuple, Generic[T]):
1421+
x: T
1422+
1423+
replaced_2 = GenericA(x=0).__replace__(x=1)
1424+
reveal_type(replaced_2) # N: Revealed type is "__main__.GenericA"
1425+
GenericA(x=0).__replace__(x="abc") # E: Argument "x" to "__replace__" of "GenericA" has incompatible type "str"; expected "int"
1426+
14131427
[builtins fixtures/tuple.pyi]
14141428
[typing fixtures/typing-namedtuple.pyi]
14151429

0 commit comments

Comments
 (0)