8000 Fix attrs.evolve on bound TypeVar · python/mypy@3a8b535 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3a8b535

Browse files
committed
Fix attrs.evolve on bound TypeVar
1 parent e9f876e commit 3a8b535

File tree

2 files changed

+14
-62
lines changed

2 files changed

+14
-62
lines changed

mypy/plugins/attrs.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from mypy.applytype import apply_generic_arguments
1010
from mypy.checker import TypeChecker
1111
from mypy.errorcodes import LITERAL_REQ
12-
from mypy.expandtype import expand_type, expand_type_by_instance
12+
from mypy.expandtype import expand_type
1313
from mypy.exprtotype import TypeTranslationError, expr_to_unanalyzed_type
1414
from mypy.messages import format_type_bare
1515
from mypy.nodes import (
@@ -982,8 +982,6 @@ def evolve_function_sig_callback(ctx: mypy.plugin.FunctionSigContext) -> Callabl
982982
return ctx.default_signature
983983
assert isinstance(attrs_type, Instance)
984984

985-
attrs_init_type = expand_type_by_instance(attrs_init_type, attrs_type)
986-
987985
# AttrClass.__init__ has the following signature (or similar, if having kw-only & defaults):
988986
# def __init__(self, attr1: Type1, attr2: Type2) -> None:
989987
# We want to generate a signature for evolve that looks like this:

test-data/unit/check-attr.test

Lines changed: 13 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,47 +1970,19 @@ reveal_type(ret) # N: Revealed type is "Any"
19701970

19711971
[typing fixtures/typing-medium.pyi]
19721972

1973-
[case testEvolveGeneric]
1974-
import attrs
1975-
from typing import Generic, TypeVar
1976-
1977-
T = TypeVar('T')
1978-
1979-
@attrs.define
1980-
class A(Generic[T]):
1981-
x: T
1982-
1983-
1984-
a = A(x=42)
1985-
reveal_type(a) # N: Revealed type is "__main__.A[builtins.int]"
1986-
a2 = attrs.evolve(a, x=42)
1987-
reveal_type(a2) # N: Revealed type is "__main__.A[builtins.int]"
1988-
a2 = attrs.evolve(a, x='42') # E: Argument "x" to "evolve" of "A[int]" has incompatible type "str"; expected "int"
1989-
reveal_type(a2) # N: Revealed type is "__main__.A[builtins.int]"
1990-
1991-
[builtins fixtures/attr.pyi]
1992-
[typing fixtures/typing-medium.pyi]
1993-
1994-
[case testEvolveTypeVarWithAttrsUpperBound]
1973+
[case testEvolveTypeVarBound]
19951974
import attrs
19961975
from typing import TypeVar
19971976

1998-
19991977
@attrs.define
20001978
class A:
20011979
x: int
20021980

2003-
20041981
@attrs.define
20051982
class B(A):
20061983
pass
20071984

2008-
20091985
TA = TypeVar('TA', bound=A)
2010-
TInt = TypeVar('TInt', bound=int)
2011-
TAny = TypeVar('TAny')
2012-
TNone = TypeVar('TNone', bound=None)
2013-
20141986

20151987
def f(t: TA) -> TA:
20161988
t2 = attrs 10000 .evolve(t, x=42)
@@ -2021,58 +1993,41 @@ def f(t: TA) -> TA:
20211993
f(A(x=42))
20221994
f(B(x=42))
20231995

2024-
def g(t: TInt) -> None:
2025-
_ = attrs.evolve(t, x=42) # E: Argument 1 to "evolve" has a variable type "TInt" not bound to an attrs class
2026-
2027-
def h(t: TAny) -> None:
2028-
_ = attrs.evolve(t, x=42) # E: Argument 1 to "evolve" has a variable type "TAny" not bound to an attrs class
2029-
2030-
def q(t: TNone) -> None:
2031-
_ = attrs.evolve(t, x=42) # E: Argument 1 to "evolve" has a variable type "TNone" not bound to an attrs class
2032-
20331996
[builtins fixtures/attr.pyi]
2034-
[typing fixtures/typing-medium.pyi]
20351997

2036-
[case testEvolveTypeVarWithAttrsGenericUpperBound]
1998+
[case testEvolveTypeVarBoundNonAttrs]
20371999
import attrs
2038-
from typing import Generic, TypeVar
2039-
2040-
Q = TypeVar('Q', bound=str)
2041-
2042-
@attrs.define
2043-
class A(Generic[Q]):
2044-
x: Q
2045-
2000+
from typing import TypeVar
20462001

2047-
T = TypeVar('T', bound=A[str])
2002+
TInt = TypeVar('TInt', bound=int)
2003+
TAny = TypeVar('TAny')
2004+
TNone = TypeVar('TNone', bound=None)
20482005

2006+
def f(t: TInt) -> None:
2007+
_ = attrs.evolve(t, x=42) # E: Argument 1 to "evolve" has a variable type "TInt" not bound to an attrs class
20492008

2050-
def f(t: T) -> T:
2051-
t = attrs.evolve(t, x=42) # E: Argument "x" to "evolve" of "T" has incompatible type "int"; expected "str"
2052-
return t
2009+
def g(t: TAny) -> None:
2010+
_ = attrs.evolve(t, x=42) # E: Argument 1 to "evolve" has a variable type "TAny" not bound to an attrs class
20532011

2054-
f(A(x='42'))
2012+
def h(t: TNone) -> None:
2013+
_ = attrs.evolve(t, x=42) # E: Argument 1 to "evolve" has a variable type "TNone" not bound to an attrs class
20552014

20562015
[builtins fixtures/attr.pyi]
2057-
[typing fixtures/typing-medium.pyi]
20582016

2059-
[case testEvolveTypeVarWithAttrsValueRestrictions]
2017+
[case testEvolveTypeVarConstrained]
20602018
import attrs
20612019
from typing import TypeVar
20622020

20632021
@attrs.define
20642022
class A:
20652023
x: int
20662024

2067-
20682025
@attrs.define
20692026
class B:
20702027
x: str # conflicting with A.x
20712028

2072-
20732029
T = TypeVar('T', A, B)
20742030

2075-
20762031
def f(t: T) -> T:
20772032
t2 = attrs.evolve(t, x=42) # E: Argument "x" to "evolve" of "B" has incompatible type "int"; expected "str"
20782033
reveal_type(t2) # N: Revealed type is "__main__.A" # N: Revealed type is "__main__.B"
@@ -2083,7 +2038,6 @@ f(A(x=42))
20832038
f(B(x='42'))
20842039

20852040
[builtins fixtures/attr.pyi]
2086-
[typing fixtures/typing-medium.pyi]
20872041

20882042
[case testEvolveVariants]
20892043
from typing import Any

0 commit comments

Comments
 (0)
0