Skip to content

Commit

Permalink
Have namedtuple __replace__ return Self (#17475)
Browse files Browse the repository at this point in the history
  • Loading branch information
max-muoto committed Jul 3, 2024
1 parent cb7b96d commit 1882ed7
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
4 changes: 3 additions & 1 deletion mypy/semanal_namedtuple.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
TYPED_NAMEDTUPLE_NAMES,
AnyType,
CallableType,
Instance,
LiteralType,
TupleType,
Type,
Expand Down Expand Up @@ -631,9 +632,10 @@ def add_method(
args=[Argument(var, var.type, EllipsisExpr(), ARG_NAMED_OPT) for var in vars],
)
if self.options.python_version >= (3, 13):
type_vars = [tv for tv in info.defn.type_vars]
add_method(
"__replace__",
ret=None,
ret=Instance(info, type_vars),
args=[Argument(var, var.type, EllipsisExpr(), ARG_NAMED_OPT) for var in vars],
)

Expand Down
16 changes: 15 additions & 1 deletion test-data/unit/check-namedtuple.test
Original file line number Diff line number Diff line change
Expand Up @@ -1407,9 +1407,23 @@ from typing import NamedTuple
class A(NamedTuple):
x: int

A(x=0).__replace__(x=1)
replaced = A(x=0).__replace__(x=1)
reveal_type(replaced) # N: Revealed type is "__main__.A"

A(x=0).__replace__(x="asdf") # E: Argument "x" to "__replace__" of "A" has incompatible type "str"; expected "int"
A(x=0).__replace__(y=1) # E: Unexpected keyword argument "y" for "__replace__" of "A"

from typing import TypeVar, Generic

T = TypeVar("T")

class GenericA(NamedTuple, Generic[T]):
x: T

replaced_2 = GenericA(x=0).__replace__(x=1)
reveal_type(replaced_2) # N: Revealed type is "__main__.GenericA"
GenericA(x=0).__replace__(x="abc") # E: Argument "x" to "__replace__" of "GenericA" has incompatible type "str"; expected "int"

[builtins fixtures/tuple.pyi]
[typing fixtures/typing-namedtuple.pyi]

Expand Down

0 comments on commit 1882ed7

Please sign in to comment.