| [case testNamedTupleUsedAsTuple] | |
| from collections import namedtuple | |
| X = namedtuple('X', 'x y') | |
| x: X | |
| a, b = x | |
| b = x[0] | |
| a = x[1] | |
| a, b, c = x # E: Need more than 2 values to unpack (3 expected) | |
| x[2] # E: Tuple index out of range | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleWithTupleFieldNamesUsedAsTuple] | |
| from collections import namedtuple | |
| X = namedtuple('X', ('x', 'y')) | |
| x: X | |
| a, b = x | |
| b = x[0] | |
| a = x[1] | |
| a, b, c = x # E: Need more than 2 values to unpack (3 expected) | |
| x[2] # E: Tuple index out of range | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleInvalidFields] | |
| from collections import namedtuple | |
| X = namedtuple('X', 'x, _y') # E: "namedtuple()" field name "_y" starts with an underscore | |
| Y = namedtuple('Y', ['x', '1']) # E: "namedtuple()" field name "1" is not a valid identifier | |
| Z = namedtuple('Z', ['x', 'def']) # E: "namedtuple()" field name "def" is a keyword | |
| A = namedtuple('A', ['x', 'x']) # E: "namedtuple()" has duplicate field name "x" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleAccessingAttributes] | |
| from collections import namedtuple | |
| X = namedtuple('X', 'x y') | |
| x: X | |
| x.x | |
| x.y | |
| x.z # E: "X" has no attribute "z" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleClassInStub] | |
| import foo | |
| [file foo.pyi] | |
| from typing import NamedTuple | |
| class A(NamedTuple): | |
| x: int | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleAttributesAreReadOnly] | |
| from collections import namedtuple | |
| X = namedtuple('X', 'x y') | |
| x: X | |
| x.x = 5 # E: Property "x" defined in "X" is read-only | |
| x.y = 5 # E: Property "y" defined in "X" is read-only | |
| x.z = 5 # E: "X" has no attribute "z" | |
| class A(X): pass | |
| a: A | |
| a.x = 5 # E: Property "x" defined in "X" is read-only | |
| a.y = 5 # E: Property "y" defined in "X" is read-only | |
| -- a.z = 5 # not supported yet | |
| [builtins fixtures/tuple.pyi] | |
| [case testTypingNamedTupleAttributesAreReadOnly] | |
| from typing import NamedTuple, Protocol | |
| class HasX(Protocol): | |
| x: str | |
| class A(NamedTuple): | |
| x: str | |
| a: HasX = A("foo") | |
| a.x = "bar" | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| main:9: error: Incompatible types in assignment (expression has type "A", variable has type "HasX") | |
| main:9: note: Protocol member HasX.x expected settable variable, got read-only attribute | |
| [case testNamedTupleCreateWithPositionalArguments] | |
| from collections import namedtuple | |
| X = namedtuple('X', 'x y') | |
| x = X(1, 'x') | |
| x.x | |
| x.z # E: "X" has no attribute "z" | |
| x = X(1) # E: Missing positional argument "y" in call to "X" | |
| x = X(1, 2, 3) # E: Too many arguments for "X" | |
| [builtins fixtures/tuple.pyi] | |
| [case testCreateNamedTupleWithKeywordArguments] | |
| from collections import namedtuple | |
| X = namedtuple('X', 'x y') | |
| x = X(x=1, y='x') | |
| x = X(1, y='x') | |
| x = X(x=1, z=1) # E: Unexpected keyword argument "z" for "X" | |
| x = X(y=1) # E: Missing positional argument "x" in call to "X" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleCreateAndUseAsTuple] | |
| from collections import namedtuple | |
| X = namedtuple('X', 'x y') | |
| x = X(1, 'x') | |
| a, b = x | |
| a, b, c = x # E: Need more than 2 values to unpack (3 expected) | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleAdditionalArgs] | |
| from collections import namedtuple | |
| A = namedtuple('A', 'a b') | |
| B = namedtuple('B', 'a b', rename=1) | |
| C = namedtuple('C', 'a b', rename='not a bool') | |
| D = namedtuple('D', 'a b', unrecognized_arg=False) | |
| E = namedtuple('E', 'a b', 0) | |
| [builtins fixtures/bool.pyi] | |
| [out] | |
| main:4: error: Boolean literal expected as the "rename" argument to namedtuple() | |
| main:5: error: Boolean literal expected as the "rename" argument to namedtuple() | |
| main:5: error: Argument "rename" to "namedtuple" has incompatible type "str"; expected "int" | |
| main:6: error: Unexpected keyword argument "unrecognized_arg" for "namedtuple" | |
| main:6: note: "namedtuple" defined in "collections" | |
| main:7: error: Too many positional arguments for "namedtuple" | |
| main:7: note: "namedtuple" defined in "collections" | |
| [case testNamedTupleDefaults] | |
| from collections import namedtuple | |
| X = namedtuple('X', ['x', 'y'], defaults=(1,)) | |
| X() # E: Missing positional argument "x" in call to "X" | |
| X(0) # ok | |
| X(0, 1) # ok | |
| X(0, 1, 2) # E: Too many arguments for "X" | |
| Y = namedtuple('Y', ['x', 'y'], defaults=(1, 2, 3)) # E: Too many defaults given in call to "namedtuple()" | |
| Z = namedtuple('Z', ['x', 'y'], defaults='not a tuple') # E: List or tuple literal expected as the defaults argument to namedtuple() # E: Argument "defaults" to "namedtuple" has incompatible type "str"; expected "Iterable[Any] | None" | |
| [builtins fixtures/list.pyi] | |
| [case testNamedTupleRename] | |
| from collections import namedtuple | |
| X = namedtuple('X', ['abc', 'def'], rename=False) # E: "namedtuple()" field name "def" is a keyword | |
| Y = namedtuple('Y', ['x', 'x', 'def', '42', '_x'], rename=True) | |
| y = Y(x=0, _1=1, _2=2, _3=3, _4=4) | |
| reveal_type(y.x) # N: Revealed type is "Any" | |
| reveal_type(y._1) # N: Revealed type is "Any" | |
| reveal_type(y._2) # N: Revealed type is "Any" | |
| reveal_type(y._3) # N: Revealed type is "Any" | |
| reveal_type(y._4) # N: Revealed type is "Any" | |
| y._0 # E: "Y" has no attribute "_0" | |
| y._5 # E: "Y" has no attribute "_5" | |
| y._x # E: "Y" has no attribute "_x" | |
| [builtins fixtures/list.pyi] | |
| [case testNamedTupleWithItemTypes] | |
| from typing import NamedTuple | |
| N = NamedTuple('N', [('a', int), | |
| ('b', str)]) | |
| n = N(1, 'x') | |
| s = n.a # type: str # E: Incompatible types in assignment (expression has type "int", \ | |
| variable has type "str") | |
| i = n.b # type: int # E: Incompatible types in assignment (expression has type "str", \ | |
| variable has type "int") | |
| x, y = n | |
| if int(): | |
| x = y # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| [targets __main__, __main__.N.__new__, __main__.N._asdict, __main__.N._make, __main__.N._replace] | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleWithTupleFieldNamesWithItemTypes] | |
| from typing import NamedTuple | |
| N = NamedTuple('N', (('a', int), | |
| ('b', str))) | |
| n = N(1, 'x') | |
| s = n.a # type: str # E: Incompatible types in assignment (expression has type "int", \ | |
| variable has type "str") | |
| i = n.b # type: int # E: Incompatible types in assignment (expression has type "str", \ | |
| variable has type "int") | |
| x, y = n | |
| if int(): | |
| x = y # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleConstructorArgumentTypes] | |
| from typing import NamedTuple | |
| N = NamedTuple('N', [('a', int), | |
| ('b', str)]) | |
| n = N('x', 'x') # E: Argument 1 to "N" has incompatible type "str"; expected "int" | |
| n = N(1, b=2) # E: Argument "b" to "N" has incompatible type "int"; expected "str" | |
| N(1, 'x') | |
| N(b='x', a=1) | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleAsBaseClass] | |
| from typing import NamedTuple | |
| N = NamedTuple('N', [('a', int), | |
| ('b', str)]) | |
| class X(N): | |
| pass | |
| x = X(1, 2) # E: Argument 2 to "X" has incompatible type "int"; expected "str" | |
| s = '' | |
| i = 0 | |
| if int(): | |
| s = x.a # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| if int(): | |
| i, s = x | |
| if int(): | |
| s, s = x # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleAsBaseClass2] | |
| from typing import NamedTuple | |
| class X(NamedTuple('N', [('a', int), | |
| ('b', str)])): | |
| pass | |
| x = X(1, 2) # E: Argument 2 to "X" has incompatible type "int"; expected "str" | |
| s = '' | |
| i = 0 | |
| if int(): | |
| s = x.a # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| if int(): | |
| i, s = x | |
| if int(): | |
| s, s = x # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTuplesTwoAsBaseClasses] | |
| from typing import NamedTuple | |
| A = NamedTuple('A', [('a', int)]) | |
| B = NamedTuple('B', [('a', int)]) | |
| class X(A, B): # E: Class has two incompatible bases derived from tuple | |
| pass | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTuplesTwoAsBaseClasses2] | |
| from typing import NamedTuple | |
| A = NamedTuple('A', [('a', int)]) | |
| class X(A, NamedTuple('B', [('a', int)])): # E: Class has two incompatible bases derived from tuple | |
| pass | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleSelfTypeWithNamedTupleAsBase] | |
| from typing import NamedTuple | |
| A = NamedTuple('A', [('a', int), ('b', str)]) | |
| class B(A): | |
| def f(self, x: int) -> None: | |
| self.f(self.a) | |
| self.f(self.b) # E: Argument 1 to "f" of "B" has incompatible type "str"; expected "int" | |
| i = 0 | |
| s = '' | |
| if int(): | |
| i, s = self | |
| i, i = self # E: Incompatible types in assignment (expression has type "str", \ | |
| variable has type "int") | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testNamedTupleTypeReferenceToClassDerivedFrom] | |
| from typing import NamedTuple | |
| A = NamedTuple('A', [('a', int), ('b', str)]) | |
| class B(A): | |
| def f(self, x: 'B') -> None: | |
| i = 0 | |
| s = '' | |
| if int(): | |
| self = x | |
| i, s = x | |
| i, s = x.a, x.b | |
| i, s = x.a, x.a # E: Incompatible types in assignment (expression has type "int", \ | |
| variable has type "str") | |
| i, i = self # E: Incompatible types in assignment (expression has type "str", \ | |
| variable has type "int") | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testNamedTupleSubtyping] | |
| from typing import NamedTuple, Tuple | |
| A = NamedTuple('A', [('a', int), ('b', str)]) | |
| class B(A): pass | |
| a = A(1, '') | |
| b = B(1, '') | |
| t: Tuple[int, str] | |
| if int(): | |
| b = a # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| if int(): | |
| a = t # E: Incompatible types in assignment (expression has type "tuple[int, str]", variable has type "A") | |
| if int(): | |
| b = t # E: Incompatible types in assignment (expression has type "tuple[int, str]", variable has type "B") | |
| if int(): | |
| t = a | |
| if int(): | |
| t = (1, '') | |
| if int(): | |
| t = b | |
| if int(): | |
| a = b | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleSimpleTypeInference] | |
| from typing import NamedTuple, Tuple | |
| A = NamedTuple('A', [('a', int)]) | |
| l = [A(1), A(2)] | |
| a = A(1) | |
| if int(): | |
| a = l[0] | |
| (i,) = l[0] | |
| if int(): | |
| i, i = l[0] # E: Need more than 1 value to unpack (2 expected) | |
| if int(): | |
| l = [A(1)] | |
| if int(): | |
| a = (1,) # E: Incompatible types in assignment (expression has type "tuple[int]", \ | |
| variable has type "A") | |
| [builtins fixtures/list.pyi] | |
| [case testNamedTupleMissingClassAttribute] | |
| import collections | |
| MyNamedTuple = collections.namedtuple('MyNamedTuple', ['spam', 'eggs']) | |
| MyNamedTuple.x # E: "type[MyNamedTuple]" has no attribute "x" | |
| [builtins fixtures/list.pyi] | |
| [case testNamedTupleEmptyItems] | |
| from typing import NamedTuple | |
| A = NamedTuple('A', []) | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleProperty] | |
| from typing import NamedTuple | |
| A = NamedTuple('A', [('a', int)]) | |
| class B(A): | |
| @property | |
| def b(self) -> int: | |
| return self.a | |
| class C(B): pass | |
| B(1).b | |
| C(2).b | |
| [builtins fixtures/property.pyi] | |
| [case testNamedTupleAsDict] | |
| from collections import namedtuple | |
| X = namedtuple('X', ['x', 'y']) | |
| x: X | |
| reveal_type(x._asdict()) # N: Revealed type is "builtins.dict[builtins.str, Any]" | |
| [builtins fixtures/dict.pyi] | |
| [case testNamedTupleReplace] | |
| from collections import namedtuple | |
| X = namedtuple('X', ['x', 'y']) | |
| x: X | |
| reveal_type(x._replace()) # N: Revealed type is "tuple[Any, Any, fallback=__main__.X]" | |
| x._replace(y=5) | |
| x._replace(x=3) | |
| x._replace(x=3, y=5) | |
| x._replace(z=5) # E: Unexpected keyword argument "z" for "_replace" of "X" | |
| x._replace(5) # E: Too many positional arguments for "_replace" of "X" | |
| [builtins fixtures/list.pyi] | |
| [case testNamedTupleReplaceAsClass] | |
| # flags: --no-strict-optional | |
| from collections import namedtuple | |
| X = namedtuple('X', ['x', 'y']) | |
| x = None # type: X | |
| X._replace(x, x=1, y=2) | |
| X._replace(x=1, y=2) # E: Missing positional argument "_self" in call to "_replace" of "X" | |
| [builtins fixtures/list.pyi] | |
| [case testNamedTupleReplaceTyped] | |
| from typing import NamedTuple | |
| X = NamedTuple('X', [('x', int), ('y', str)]) | |
| x: X | |
| reveal_type(x._replace()) # N: Revealed type is "tuple[builtins.int, builtins.str, fallback=__main__.X]" | |
| x._replace(x=5) | |
| x._replace(y=5) # E: Argument "y" to "_replace" of "X" has incompatible type "int"; expected "str" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleMake] | |
| from typing import NamedTuple | |
| X = NamedTuple('X', [('x', int), ('y', str)]) | |
| reveal_type(X._make([5, 'a'])) # N: Revealed type is "tuple[builtins.int, builtins.str, fallback=__main__.X]" | |
| X._make('a b') # E: Argument 1 to "_make" of "X" has incompatible type "str"; expected "Iterable[Any]" | |
| -- # FIX: not a proper class method | |
| -- x: X | |
| -- reveal_type(x._make([5, 'a'])) # N: Revealed type is "Tuple[builtins.int, builtins.str, fallback=__main__.X]" | |
| -- x._make('a b') # E: Argument 1 to "_make" of "X" has incompatible type "str"; expected Iterable[Any] | |
| [builtins fixtures/list.pyi] | |
| [case testNamedTupleFields] | |
| from typing import NamedTuple | |
| X = NamedTuple('X', [('x', int), ('y', str)]) | |
| reveal_type(X._fields) # N: Revealed type is "tuple[builtins.str, builtins.str]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleSource] | |
| from typing import NamedTuple | |
| X = NamedTuple('X', [('x', int), ('y', str)]) | |
| reveal_type(X._source) # N: Revealed type is "builtins.str" | |
| x: X | |
| reveal_type(x._source) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleUnit] | |
| from typing import NamedTuple | |
| X = NamedTuple('X', []) | |
| x = X() # type: X | |
| x._replace() | |
| x._fields[0] # E: Tuple index out of range | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleJoinNamedTuple] | |
| from typing import NamedTuple | |
| X = NamedTuple('X', [('x', int), ('y', str)]) | |
| Y = NamedTuple('Y', [('x', int), ('y', str)]) | |
| reveal_type([X(3, 'b'), Y(1, 'a')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" | |
| [builtins fixtures/list.pyi] | |
| [case testNamedTupleJoinTuple] | |
| from typing import NamedTuple, Tuple | |
| X = NamedTuple('X', [('x', int), ('y', str)]) | |
| reveal_type([(3, 'b'), X(1, 'a')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" | |
| reveal_type([X(1, 'a'), (3, 'b')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" | |
| [builtins fixtures/list.pyi] | |
| [case testNamedTupleFieldTypes] | |
| from typing import NamedTuple | |
| X = NamedTuple('X', [('x', int), ('y', str)]) | |
| reveal_type(X._field_types) # N: Revealed type is "builtins.dict[builtins.str, Any]" | |
| x: X | |
| reveal_type(x._field_types) # N: Revealed type is "builtins.dict[builtins.str, Any]" | |
| [builtins fixtures/dict.pyi] | |
| [case testNamedTupleAndOtherSuperclass] | |
| from typing import NamedTuple | |
| class A: pass | |
| def f(x: A) -> None: pass | |
| class B(NamedTuple('B', []), A): pass | |
| f(B()) | |
| x: A | |
| if int(): | |
| x = B() | |
| # Sanity check: fail if baseclass does not match | |
| class C: pass | |
| def g(x: C) -> None: pass | |
| class D(NamedTuple('D', []), A): pass | |
| g(D()) # E: Argument 1 to "g" has incompatible type "D"; expected "C" | |
| y: C | |
| if int(): | |
| y = D() # E: Incompatible types in assignment (expression has type "D", variable has type "C") | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleSelfTypeMethod] | |
| from typing import TypeVar, NamedTuple | |
| T = TypeVar('T', bound='A') | |
| class A(NamedTuple('A', [('x', str)])): | |
| def member(self: T) -> T: | |
| return self | |
| class B(A): | |
| pass | |
| a: A | |
| a = A('').member() | |
| b: B | |
| b = B('').member() | |
| a = B('') | |
| a = B('').member() | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleSelfTypeReplace] | |
| from typing import NamedTuple, TypeVar | |
| A = NamedTuple('A', [('x', str)]) | |
| reveal_type(A('hello')._replace(x='')) # N: Revealed type is "tuple[builtins.str, fallback=__main__.A]" | |
| a: A | |
| a = A('hello')._replace(x='') | |
| class B(A): | |
| pass | |
| reveal_type(B('hello')._replace(x='')) # N: Revealed type is "tuple[builtins.str, fallback=__main__.B]" | |
| b: B | |
| b = B('hello')._replace(x='') | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleSelfTypeMake] | |
| from typing import NamedTuple, TypeVar | |
| A = NamedTuple('A', [('x', str)]) | |
| reveal_type(A._make([''])) # N: Revealed type is "tuple[builtins.str, fallback=__main__.A]" | |
| a = A._make(['']) # type: A | |
| class B(A): | |
| pass | |
| reveal_type(B._make([''])) # N: Revealed type is "tuple[builtins.str, fallback=__main__.B]" | |
| b = B._make(['']) # type: B | |
| [builtins fixtures/list.pyi] | |
| [case testNamedTupleIncompatibleRedefinition] | |
| from typing import NamedTuple | |
| class Crash(NamedTuple): | |
| count: int # E: Incompatible types in assignment (expression has type "int", base class "tuple" defined the type as "Callable[[object], int]") | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleInClassNamespace] | |
| # https://github.com/python/mypy/pull/2553#issuecomment-266474341 | |
| from typing import NamedTuple | |
| class C: | |
| def f(self): | |
| A = NamedTuple('A', [('x', int)]) | |
| def g(self): | |
| A = NamedTuple('A', [('y', int)]) | |
| C.A # E: "type[C]" has no attribute "A" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleInFunction] | |
| from typing import NamedTuple | |
| def f() -> None: | |
| A = NamedTuple('A', [('x', int)]) | |
| A # E: Name "A" is not defined | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleForwardAsUpperBound] | |
| # flags: --disable-error-code=used-before-def | |
| from typing import NamedTuple, TypeVar, Generic | |
| T = TypeVar('T', bound='M') | |
| class G(Generic[T]): | |
| x: T | |
| yb: G[int] # E: Type argument "int" of "G" must be a subtype of "M" | |
| yg: G[M] | |
| reveal_type(G[M]().x.x) # N: Revealed type is "builtins.int" | |
| reveal_type(G[M]().x[0]) # N: Revealed type is "builtins.int" | |
| M = NamedTuple('M', [('x', int)]) | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testNamedTupleWithImportCycle] | |
| import a | |
| [file a.py] | |
| from collections import namedtuple | |
| from b import f | |
| N = namedtuple('N', 'a') | |
| class X(N): pass | |
| [file b.py] | |
| import a | |
| def f(x: a.X) -> None: | |
| reveal_type(x) | |
| x = a.X(1) | |
| reveal_type(x) | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| tmp/b.py:4: note: Revealed type is "tuple[Any, fallback=a.X]" | |
| tmp/b.py:6: note: Revealed type is "tuple[Any, fallback=a.X]" | |
| [case testNamedTupleWithImportCycle2] | |
| import a | |
| [file a.py] | |
| from collections import namedtuple | |
| from b import f | |
| N = namedtuple('N', 'a') | |
| [file b.py] | |
| import a | |
| def f(x: a.N) -> None: | |
| reveal_type(x) | |
| if int(): | |
| x = a.N(1) | |
| reveal_type(x) | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| tmp/b.py:4: note: Revealed type is "tuple[Any, fallback=a.N]" | |
| tmp/b.py:7: note: Revealed type is "tuple[Any, fallback=a.N]" | |
| [case testSimpleSelfReferentialNamedTuple] | |
| from typing import NamedTuple | |
| def test() -> None: | |
| class MyNamedTuple(NamedTuple): | |
| parent: 'MyNamedTuple' # E: Cannot resolve name "MyNamedTuple" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope | |
| def bar(nt: MyNamedTuple) -> MyNamedTuple: | |
| return nt | |
| x: MyNamedTuple | |
| reveal_type(x.parent) # N: Revealed type is "Any" | |
| [builtins fixtures/tuple.pyi] | |
| -- Some crazy self-referential named tuples and types dicts | |
| -- to be sure that everything works | |
| [case testCrossFileNamedTupleForwardRefs] | |
| import a | |
| [file a.py] | |
| import b | |
| from typing import Any, NamedTuple | |
| class A: | |
| def a(self, b: 'b.B') -> str: | |
| return 'a' | |
| ATuple = NamedTuple('ATuple', [('a', Any)]) | |
| [file b.py] | |
| import a | |
| class B: | |
| def b(self, a: 'a.A') -> str: | |
| return 'b' | |
| def aWithTuple(self, atuple: 'a.ATuple') -> str: | |
| return 'a' | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testSelfRefNT1] | |
| from typing import Tuple, NamedTuple | |
| def test() -> None: | |
| Node = NamedTuple('Node', [ | |
| ('name', str), | |
| ('children', Tuple['Node', ...]), # E: Cannot resolve name "Node" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope | |
| ]) | |
| n: Node | |
| reveal_type(n) # N: Revealed type is "tuple[builtins.str, builtins.tuple[Any, ...], fallback=__main__.Node@4]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testSelfRefNT2] | |
| from typing import Tuple, NamedTuple | |
| def test() -> None: | |
| A = NamedTuple('A', [ | |
| ('x', str), | |
| ('y', Tuple['B', ...]), # E: Cannot resolve name "B" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope | |
| ]) | |
| class B(NamedTuple): | |
| x: A | |
| y: int | |
| n: A | |
| reveal_type(n) # N: Revealed type is "tuple[builtins.str, builtins.tuple[Any, ...], fallback=__main__.A@4]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testSelfRefNT3] | |
| from typing import NamedTuple, Tuple | |
| def test() -> None: | |
| class B(NamedTuple): | |
| x: Tuple[A, int] # E: Cannot resolve name "A" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope | |
| y: int | |
| A = NamedTuple('A', [ | |
| ('x', str), | |
| ('y', 'B'), | |
| ]) | |
| n: B | |
| m: A | |
| reveal_type(n.x) # N: Revealed type is "tuple[Any, builtins.int]" | |
| reveal_type(m[0]) # N: Revealed type is "builtins.str" | |
| lst = [m, n] | |
| reveal_type(lst[0]) # N: Revealed type is "tuple[builtins.object, builtins.object]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testSelfRefNT4] | |
| from typing import NamedTuple | |
| def test() -> None: | |
| class B(NamedTuple): | |
| x: A # E: Cannot resolve name "A" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope | |
| y: int | |
| class A(NamedTuple): | |
| x: str | |
| y: B | |
| n: A | |
| reveal_type(n.y[0]) # N: Revealed type is "Any" | |
| [builtins fixtures/tuple.pyi] | |
| [case testSelfRefNT5] | |
| from typing import NamedTuple | |
| def test() -> None: | |
| B = NamedTuple('B', [ | |
| ('x', A), # E: Cannot resolve name "A" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope \ | |
| # E: Name "A" is used before definition | |
| ('y', int), | |
| ]) | |
| A = NamedTuple('A', [ | |
| ('x', str), | |
| ('y', 'B'), | |
| ]) | |
| n: A | |
| def f(m: B) -> None: pass | |
| reveal_type(n) # N: Revealed type is "tuple[builtins.str, tuple[Any, builtins.int, fallback=__main__.B@4], fallback=__main__.A@8]" | |
| reveal_type(f) # N: Revealed type is "def (m: tuple[Any, builtins.int, fallback=__main__.B@4])" | |
| [builtins fixtures/tuple.pyi] | |
| [case testRecursiveNamedTupleInBases] | |
| from typing import List, NamedTuple, Union | |
| def test() -> None: | |
| Exp = Union['A', 'B'] # E: Cannot resolve name "Exp" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope \ | |
| # E: Cannot resolve name "A" (possible cyclic definition) | |
| class A(NamedTuple('A', [('attr', List[Exp])])): pass | |
| class B(NamedTuple('B', [('val', object)])): pass | |
| exp: Exp | |
| reveal_type(exp) # N: Revealed type is "Any | tuple[builtins.object, fallback=__main__.B@6]" | |
| if isinstance(exp, A): | |
| reveal_type(exp[0][0]) # N: Revealed type is "Any | tuple[builtins.object, fallback=__main__.B@6]" | |
| reveal_type(exp.attr[0]) # N: Revealed type is "Any | tuple[builtins.object, fallback=__main__.B@6]" | |
| if isinstance(exp, B): | |
| reveal_type(exp.val) # N: Revealed type is "builtins.object" | |
| reveal_type(A([B(1), B(2)])) # N: Revealed type is "tuple[builtins.list[Any | tuple[builtins.object, fallback=__main__.B@6]], fallback=__main__.A@5]" | |
| [builtins fixtures/isinstancelist.pyi] | |
| [out] | |
| [case testNamedTupleImportCycle] | |
| import b | |
| [file a.py] | |
| class C: | |
| pass | |
| from b import tp | |
| x: tp | |
| reveal_type(x.x) # N: Revealed type is "builtins.int" | |
| reveal_type(tp) # N: Revealed type is "def (x: builtins.int) -> tuple[builtins.int, fallback=b.tp]" | |
| tp('x') # E: Argument 1 to "tp" has incompatible type "str"; expected "int" | |
| [file b.py] | |
| from a import C | |
| from typing import NamedTuple | |
| tp = NamedTuple('tp', [('x', int)]) | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testSubclassOfRecursiveNamedTuple] | |
| from typing import List, NamedTuple | |
| def test() -> None: | |
| class Command(NamedTuple): | |
| subcommands: List['Command'] # E: Cannot resolve name "Command" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope | |
| class HelpCommand(Command): | |
| pass | |
| hc = HelpCommand(subcommands=[]) | |
| reveal_type(hc) # N: Revealed type is "tuple[builtins.list[Any], fallback=__main__.HelpCommand@7]" | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| [case testUnsafeOverlappingNamedTuple] | |
| from typing import NamedTuple | |
| class Real(NamedTuple): | |
| def __sub__(self, other: Real) -> str: return "" | |
| class Fraction(Real): | |
| def __rsub__(self, other: Real) -> Real: return other # E: Signatures of "__rsub__" of "Fraction" and "__sub__" of "Real" are unsafely overlapping | |
| [builtins fixtures/tuple.pyi] | |
| [case testForwardReferenceInNamedTuple] | |
| from typing import NamedTuple | |
| class A(NamedTuple): | |
| b: 'B' | |
| x: int | |
| class B: | |
| pass | |
| [builtins fixtures/tuple.pyi] | |
| [case testTypeNamedTupleClassmethod] | |
| from typing import Type, NamedTuple | |
| class D(NamedTuple): | |
| @classmethod | |
| def f(cls) -> None: pass | |
| d: Type[D] | |
| d.g() # E: "type[D]" has no attribute "g" | |
| d.f() | |
| [builtins fixtures/classmethod.pyi] | |
| [case testTypeNamedTupleCall] | |
| from typing import NamedTuple | |
| Thing = NamedTuple('Thing', [('s', str), ('n', int)]) | |
| class CallableTuple(Thing): | |
| def __call__(self) -> None: | |
| pass | |
| o = CallableTuple('hello ', 12) | |
| o() | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleSubclassMulti] | |
| from typing import NamedTuple | |
| class Base: | |
| pass | |
| class BaseTuple(NamedTuple): | |
| value: float | |
| class MyTuple(BaseTuple, Base): | |
| pass | |
| def f(o: Base) -> None: | |
| if isinstance(o, MyTuple): | |
| reveal_type(o.value) # N: Revealed type is "builtins.float" | |
| [builtins fixtures/isinstance.pyi] | |
| [out] | |
| [case testNamedTupleNew] | |
| from typing import NamedTuple | |
| Base = NamedTuple('Base', [('param', int)]) | |
| class Child(Base): | |
| def __new__(cls, param: int = 1) -> 'Child': | |
| return Base.__new__(cls, param) | |
| Base(param=10) | |
| Child(param=10) | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleClassMethodWithGenericReturnValue] | |
| from typing import TypeVar, Type, NamedTuple | |
| T = TypeVar('T', bound='Parent') | |
| class Parent(NamedTuple): | |
| x: str | |
| @classmethod | |
| def class_method(cls: Type[T]) -> T: | |
| return cls(x='text') | |
| class Child(Parent): | |
| pass | |
| reveal_type(Child.class_method()) # N: Revealed type is "tuple[builtins.str, fallback=__main__.Child]" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testNamedTupleAsConditionalStrictOptionalDisabled] | |
| # flags: --no-strict-optional --warn-unreachable | |
| from typing import NamedTuple | |
| class C(NamedTuple): | |
| a: int | |
| b: str | |
| a: C | |
| if not a: | |
| 1() # E: "int" not callable | |
| b = (1, 2) | |
| if not b: | |
| ''() # E: "str" not callable | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleDoubleForward] | |
| # flags: --disable-error-code=used-before-def | |
| from typing import Union, Mapping, NamedTuple | |
| class MyBaseTuple(NamedTuple): | |
| base_field_1: int | |
| base_field_2: int | |
| MyBaseTupleMapping = Mapping[MyBaseTuple, int] | |
| MyTupleUnion = Union[MyTupleA, MyTupleB] | |
| class MyTupleA(NamedTuple): | |
| field_1: MyBaseTupleMapping | |
| field_2: MyBaseTuple | |
| class MyTupleB(NamedTuple): | |
| field_1: MyBaseTupleMapping | |
| field_2: MyBaseTuple | |
| u: MyTupleUnion | |
| reveal_type(u.field_1) # N: Revealed type is "typing.Mapping[tuple[builtins.int, builtins.int, fallback=__main__.MyBaseTuple], builtins.int]" | |
| reveal_type(u.field_2) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.MyBaseTuple]" | |
| reveal_type(u[0]) # N: Revealed type is "typing.Mapping[tuple[builtins.int, builtins.int, fallback=__main__.MyBaseTuple], builtins.int]" | |
| reveal_type(u[1]) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.MyBaseTuple]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testAssignNamedTupleAsAttribute] | |
| from typing import NamedTuple | |
| class A: | |
| def __init__(self) -> None: | |
| self.b = NamedTuple('x', [('s', str), ('n', int)]) # E: NamedTuple type as an attribute is not supported | |
| reveal_type(A().b) # N: Revealed type is "typing.NamedTuple" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testEmptyNamedTupleTypeRepr] | |
| from typing import NamedTuple | |
| N = NamedTuple('N', []) | |
| n: N | |
| reveal_type(N) # N: Revealed type is "def () -> tuple[(), fallback=__main__.N]" | |
| reveal_type(n) # N: Revealed type is "tuple[(), fallback=__main__.N]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleWrongfile] | |
| from typing import NamedTuple | |
| from b import Type1 | |
| Type2 = NamedTuple('Type2', [('x', Type1)]) | |
| [file b.py] | |
| from typing import NamedTuple | |
| def foo(): | |
| pass | |
| Type1 = NamedTuple('Type1', [('foo', foo)]) # E: Function "b.foo" is not valid as a type # N: Perhaps you need "Callable[...]" or a callback protocol? | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleTypeNameMatchesVariableName] | |
| from typing import NamedTuple | |
| from collections import namedtuple | |
| A = NamedTuple('X', [('a', int)]) # E: First argument to namedtuple() should be "A", not "X" | |
| B = namedtuple('X', ['a']) # E: First argument to namedtuple() should be "B", not "X" | |
| C = NamedTuple('X', [('a', 'Y')]) # E: First argument to namedtuple() should be "C", not "X" | |
| class Y: ... | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleTypeIsASuperTypeOfOtherNamedTuples] | |
| from typing import Tuple, NamedTuple | |
| class Bar(NamedTuple): | |
| name: str = "Bar" | |
| class Baz(NamedTuple): | |
| a: str | |
| b: str | |
| class Biz(Baz): ... | |
| class Other: ... | |
| class Both1(Bar, Other): ... | |
| class Both2(Other, Bar): ... | |
| class Both3(Biz, Other): ... | |
| def print_namedtuple(obj: NamedTuple) -> None: | |
| reveal_type(obj._fields) # N: Revealed type is "builtins.tuple[builtins.str, ...]" | |
| b1: Bar | |
| b2: Baz | |
| b3: Biz | |
| b4: Both1 | |
| b5: Both2 | |
| b6: Both3 | |
| print_namedtuple(b1) # ok | |
| print_namedtuple(b2) # ok | |
| print_namedtuple(b3) # ok | |
| print_namedtuple(b4) # ok | |
| print_namedtuple(b5) # ok | |
| print_namedtuple(b6) # ok | |
| print_namedtuple(1) # E: Argument 1 to "print_namedtuple" has incompatible type "int"; expected "NamedTuple" | |
| print_namedtuple(('bar',)) # E: Argument 1 to "print_namedtuple" has incompatible type "tuple[str]"; expected "NamedTuple" | |
| print_namedtuple((1, 2)) # E: Argument 1 to "print_namedtuple" has incompatible type "tuple[int, int]"; expected "NamedTuple" | |
| print_namedtuple((b1,)) # E: Argument 1 to "print_namedtuple" has incompatible type "tuple[Bar]"; expected "NamedTuple" | |
| t: Tuple[str, ...] | |
| print_namedtuple(t) # E: Argument 1 to "print_namedtuple" has incompatible type "tuple[str, ...]"; expected "NamedTuple" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNamedTupleTypeIsASuperTypeOfOtherNamedTuplesReturns] | |
| from typing import Tuple, NamedTuple | |
| class Bar(NamedTuple): | |
| n: int | |
| class Baz(NamedTuple): | |
| a: str | |
| b: str | |
| class Biz(Bar): ... | |
| class Other: ... | |
| class Both1(Bar, Other): ... | |
| class Both2(Other, Bar): ... | |
| class Both3(Biz, Other): ... | |
| def good1() -> NamedTuple: | |
| b: Bar | |
| return b | |
| def good2() -> NamedTuple: | |
| b: Baz | |
| return b | |
| def good3() -> NamedTuple: | |
| b: Biz | |
| return b | |
| def good4() -> NamedTuple: | |
| b: Both1 | |
| return b | |
| def good5() -> NamedTuple: | |
| b: Both2 | |
| return b | |
| def good6() -> NamedTuple: | |
| b: Both3 | |
| return b | |
| def bad1() -> NamedTuple: | |
| return 1 # E: Incompatible return value type (got "int", expected "NamedTuple") | |
| def bad2() -> NamedTuple: | |
| return () # E: Incompatible return value type (got "tuple[()]", expected "NamedTuple") | |
| def bad3() -> NamedTuple: | |
| return (1, 2) # E: Incompatible return value type (got "tuple[int, int]", expected "NamedTuple") | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testBoolInTuplesRegression] | |
| # https://github.com/python/mypy/issues/11701 | |
| from typing import NamedTuple, Literal, List, Tuple | |
| C = NamedTuple("C", [("x", Literal[True, False])]) | |
| T = Tuple[Literal[True, False]] | |
| # Was error here: | |
| # Incompatible types in assignment (expression has type "list[C]", variable has type "list[C]") | |
| x: List[C] = [C(True)] | |
| t: T | |
| # Was error here: | |
| # Incompatible types in assignment (expression has type "list[tuple[bool]]", | |
| # variable has type "list[tuple[Union[Literal[True], Literal[False]]]]") | |
| y: List[T] = [t] | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNamedTupleWithBoolNarrowsToBool] | |
| # flags: --warn-unreachable | |
| from typing import NamedTuple | |
| class C(NamedTuple): | |
| x: int | |
| def __bool__(self) -> bool: | |
| pass | |
| def foo(c: C) -> None: | |
| if c: | |
| reveal_type(c) # N: Revealed type is "tuple[builtins.int, fallback=__main__.C]" | |
| else: | |
| reveal_type(c) # N: Revealed type is "tuple[builtins.int, fallback=__main__.C]" | |
| def bar(c: C) -> None: | |
| if not c: | |
| reveal_type(c) # N: Revealed type is "tuple[builtins.int, fallback=__main__.C]" | |
| else: | |
| reveal_type(c) # N: Revealed type is "tuple[builtins.int, fallback=__main__.C]" | |
| class C1(NamedTuple): | |
| x: int | |
| def foo1(c: C1) -> None: | |
| if c: | |
| reveal_type(c) # N: Revealed type is "tuple[builtins.int, fallback=__main__.C1]" | |
| else: | |
| c # E: Statement is unreachable | |
| def bar1(c: C1) -> None: | |
| if not c: | |
| c # E: Statement is unreachable | |
| else: | |
| reveal_type(c) # N: Revealed type is "tuple[builtins.int, fallback=__main__.C1]" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testInvalidNamedTupleWithinFunction] | |
| from collections import namedtuple | |
| def f(fields) -> None: | |
| TupleType = namedtuple("TupleType", fields) \ | |
| # E: List or tuple literal expected as the second argument to "namedtuple()" | |
| class InheritFromTuple(TupleType): | |
| pass | |
| t: TupleType | |
| it: InheritFromTuple | |
| NT2 = namedtuple("bad", "x") # E: First argument to namedtuple() should be "NT2", not "bad" | |
| nt2: NT2 = NT2(x=1) | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleHasMatchArgs] | |
| from typing import NamedTuple | |
| class One(NamedTuple): | |
| bar: int | |
| baz: str | |
| o: One | |
| reveal_type(o.__match_args__) # N: Revealed type is "tuple[Literal['bar'], Literal['baz']]" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNamedTupleNoBytes] | |
| from collections import namedtuple | |
| from typing import NamedTuple | |
| NT1 = namedtuple('NT1', b'x y z') # E: List or tuple literal expected as the second argument to "namedtuple()" | |
| NT2 = namedtuple(b'NT2', 'x y z') # E: "namedtuple()" expects a string literal as the first argument \ | |
| # E: Argument 1 to "namedtuple" has incompatible type "bytes"; expected "str" | |
| NT3 = namedtuple('NT3', [b'x', 'y']) # E: String literal expected as "namedtuple()" item | |
| NT4 = NamedTuple('NT4', [('x', int), (b'y', int)]) # E: Invalid "NamedTuple()" field name | |
| NT5 = NamedTuple(b'NT5', [('x', int), ('y', int)]) # E: "NamedTuple()" expects a string literal as the first argument | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testGenericNamedTupleCreation] | |
| from typing import Generic, NamedTuple, TypeVar | |
| T = TypeVar("T") | |
| class NT(NamedTuple, Generic[T]): | |
| key: int | |
| value: T | |
| nts: NT[str] | |
| reveal_type(nts) # N: Revealed type is "tuple[builtins.int, builtins.str, fallback=__main__.NT[builtins.str]]" | |
| reveal_type(nts.value) # N: Revealed type is "builtins.str" | |
| nti = NT(key=0, value=0) | |
| reveal_type(nti) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.NT[builtins.int]]" | |
| reveal_type(nti.value) # N: Revealed type is "builtins.int" | |
| NT[str](key=0, value=0) # E: Argument "value" to "NT" has incompatible type "int"; expected "str" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testGenericNamedTupleAlias] | |
| from typing import NamedTuple, Generic, TypeVar, List | |
| T = TypeVar("T") | |
| class NT(NamedTuple, Generic[T]): | |
| key: int | |
| value: T | |
| Alias = NT[List[T]] | |
| an: Alias[str] | |
| reveal_type(an) # N: Revealed type is "tuple[builtins.int, builtins.list[builtins.str], fallback=__main__.NT[builtins.list[builtins.str]]]" | |
| Alias[str](key=0, value=0) # E: Argument "value" to "NT" has incompatible type "int"; expected "list[str]" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testGenericNamedTupleMethods] | |
| from typing import Generic, NamedTuple, TypeVar | |
| T = TypeVar("T") | |
| class NT(NamedTuple, Generic[T]): | |
| key: int | |
| value: T | |
| x: int | |
| nti: NT[int] | |
| reveal_type(nti * x) # N: Revealed type is "builtins.tuple[builtins.int, ...]" | |
| nts: NT[str] | |
| reveal_type(nts * x) # N: Revealed type is "builtins.tuple[builtins.int | builtins.str, ...]" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testGenericNamedTupleCustomMethods] | |
| from typing import Generic, NamedTuple, TypeVar | |
| T = TypeVar("T") | |
| class NT(NamedTuple, Generic[T]): | |
| key: int | |
| value: T | |
| def foo(self) -> T: ... | |
| @classmethod | |
| def from_value(cls, value: T) -> NT[T]: ... | |
| nts: NT[str] | |
| reveal_type(nts.foo()) # N: Revealed type is "builtins.str" | |
| nti = NT.from_value(1) | |
| reveal_type(nti) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.NT[builtins.int]]" | |
| NT[str].from_value(1) # E: Argument 1 to "from_value" of "NT" has incompatible type "int"; expected "str" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testGenericNamedTupleSubtyping] | |
| from typing import Generic, NamedTuple, TypeVar, Tuple | |
| T = TypeVar("T") | |
| class NT(NamedTuple, Generic[T]): | |
| key: int | |
| value: T | |
| nts: NT[str] | |
| nti: NT[int] | |
| def foo(x: Tuple[int, ...]) -> None: ... | |
| foo(nti) | |
| foo(nts) # E: Argument 1 to "foo" has incompatible type "NT[str]"; expected "tuple[int, ...]" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testGenericNamedTupleJoin] | |
| from typing import Generic, NamedTuple, TypeVar, Tuple | |
| T = TypeVar("T", covariant=True) | |
| class NT(NamedTuple, Generic[T]): | |
| key: int | |
| value: T | |
| nts: NT[str] | |
| nti: NT[int] | |
| x: Tuple[int, ...] | |
| S = TypeVar("S") | |
| def foo(x: S, y: S) -> S: ... | |
| reveal_type(foo(nti, nti)) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.NT[builtins.int]]" | |
| reveal_type(foo(nti, nts)) # N: Revealed type is "tuple[builtins.int, builtins.object, fallback=__main__.NT[builtins.object]]" | |
| reveal_type(foo(nts, nti)) # N: Revealed type is "tuple[builtins.int, builtins.object, fallback=__main__.NT[builtins.object]]" | |
| reveal_type(foo(nti, x)) # N: Revealed type is "builtins.tuple[builtins.int, ...]" | |
| reveal_type(foo(nts, x)) # N: Revealed type is "builtins.tuple[builtins.int | builtins.str, ...]" | |
| reveal_type(foo(x, nti)) # N: Revealed type is "builtins.tuple[builtins.int, ...]" | |
| reveal_type(foo(x, nts)) # N: Revealed type is "builtins.tuple[builtins.int | builtins.str, ...]" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testGenericNamedTupleCallSyntax] | |
| from typing import NamedTuple, TypeVar | |
| T = TypeVar("T") | |
| NT = NamedTuple("NT", [("key", int), ("value", T)]) | |
| reveal_type(NT) # N: Revealed type is "def [T] (key: builtins.int, value: T`1) -> tuple[builtins.int, T`1, fallback=__main__.NT[T`1]]" | |
| nts: NT[str] | |
| reveal_type(nts) # N: Revealed type is "tuple[builtins.int, builtins.str, fallback=__main__.NT[builtins.str]]" | |
| nti = NT(key=0, value=0) | |
| reveal_type(nti) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.NT[builtins.int]]" | |
| NT[str](key=0, value=0) # E: Argument "value" to "NT" has incompatible type "int"; expected "str" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testGenericNamedTupleNoLegacySyntax] | |
| from typing import TypeVar, NamedTuple | |
| T = TypeVar("T") | |
| class C( | |
| NamedTuple("_C", [("x", int), ("y", T)]) # E: Generic named tuples are not supported for legacy class syntax \ | |
| # N: Use either Python 3 class syntax, or the assignment syntax | |
| ): ... | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNamedTupleSelfItemNotAllowed] | |
| from typing import Self, NamedTuple, Optional | |
| class NT(NamedTuple): | |
| val: int | |
| next: Optional[Self] # E: Self type cannot be used in NamedTuple item type | |
| NTC = NamedTuple("NTC", [("val", int), ("next", Optional[Self])]) # E: Self type cannot be used in NamedTuple item type | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNamedTupleTypingSelfMethod] | |
| from typing import Self, NamedTuple, TypeVar, Generic | |
| T = TypeVar("T") | |
| class NT(NamedTuple, Generic[T]): | |
| key: str | |
| val: T | |
| def meth(self) -> Self: | |
| nt: NT[int] | |
| if bool(): | |
| return nt._replace() # E: Incompatible return value type (got "NT[int]", expected "Self") | |
| else: | |
| return self._replace() | |
| class SNT(NT[int]): ... | |
| reveal_type(SNT("test", 42).meth()) # N: Revealed type is "tuple[builtins.str, builtins.int, fallback=__main__.SNT]" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNoCrashUnsupportedNamedTuple] | |
| from typing import NamedTuple | |
| class Test: | |
| def __init__(self, field) -> None: | |
| self.Item = NamedTuple("x", [(field, str)]) # E: NamedTuple type as an attribute is not supported | |
| self.item: self.Item # E: Name "self.Item" is not defined | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNoClassKeywordsForNamedTuple] | |
| from typing import NamedTuple | |
| class Test1(NamedTuple, x=1, y=2): # E: Unexpected keyword argument "x" for "__init_subclass__" of "NamedTuple" \ | |
| # E: Unexpected keyword argument "y" for "__init_subclass__" of "NamedTuple" | |
| ... | |
| class Meta(type): ... | |
| class Test2(NamedTuple, metaclass=Meta): # E: Unexpected keyword argument "metaclass" for "__init_subclass__" of "NamedTuple" | |
| ... | |
| # Technically this would work, but it is just easier for the implementation: | |
| class Test3(NamedTuple, metaclass=type): # E: Unexpected keyword argument "metaclass" for "__init_subclass__" of "NamedTuple" | |
| ... | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNamedTupleDunderReplace] | |
| # flags: --python-version 3.13 | |
| from typing import NamedTuple | |
| class A(NamedTuple): | |
| x: int | |
| A(x=0).__replace__(x=1) | |
| 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" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testUnpackSelfNamedTuple] | |
| import typing | |
| class Foo(typing.NamedTuple): | |
| bar: int | |
| def baz(self: typing.Self) -> None: | |
| x, = self | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNameErrorInNamedTupleNestedInFunction1] | |
| from typing import NamedTuple | |
| def bar() -> None: | |
| class MyNamedTuple(NamedTuple): | |
| a: int | |
| def foo(self) -> None: | |
| ... | |
| int_set: Set[int] # E: Name "Set" is not defined \ | |
| # N: Did you forget to import it from "typing"? (Suggestion: "from typing import Set") | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNameErrorInNamedTupleNestedInFunction2] | |
| from typing import NamedTuple | |
| def bar() -> None: | |
| class MyNamedTuple(NamedTuple): | |
| a: int | |
| def foo(self) -> None: | |
| misspelled_var_name # E: Name "misspelled_var_name" is not defined | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNamedTupleFinalAndClassVar] | |
| from typing import NamedTuple, Final, ClassVar | |
| class My(NamedTuple): | |
| a: Final # E: Final[...] can't be used inside a NamedTuple | |
| b: Final[int] # E: Final[...] can't be used inside a NamedTuple | |
| c: ClassVar # E: ClassVar[...] can't be used inside a NamedTuple | |
| d: ClassVar[int] # E: ClassVar[...] can't be used inside a NamedTuple | |
| Func = NamedTuple('Func', [ | |
| ('a', Final), # E: Final[...] can't be used inside a NamedTuple | |
| ('b', Final[int]), # E: Final[...] can't be used inside a NamedTuple | |
| ('c', ClassVar), # E: ClassVar[...] can't be used inside a NamedTuple | |
| ('d', ClassVar[int]), # E: ClassVar[...] can't be used inside a NamedTuple | |
| ]) | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testGenericNamedTupleRecursiveBound] | |
| from typing import Generic, NamedTuple, TypeVar | |
| T = TypeVar("T", bound="NT") | |
| class NT(NamedTuple, Generic[T]): | |
| parent: T | |
| item: int | |
| def main(n: NT[T]) -> None: | |
| reveal_type(n.parent) # N: Revealed type is "T`-1" | |
| reveal_type(n.item) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-namedtuple.pyi] | |
| [case testNamedTupleOverlappingCheck] | |
| from typing import overload, NamedTuple, Union | |
| class AKey(NamedTuple): | |
| k: str | |
| class A(NamedTuple): | |
| key: AKey | |
| class BKey(NamedTuple): | |
| k: str | |
| class B(NamedTuple): | |
| key: BKey | |
| @overload | |
| def f(arg: A) -> A: ... | |
| @overload | |
| def f(arg: B) -> B: ... | |
| def f(arg: Union[A, B]) -> Union[A, B]: ... | |
| def g(x: Union[A, B, str]) -> Union[A, B, str]: | |
| if isinstance(x, str): | |
| return x | |
| else: | |
| reveal_type(x) # N: Revealed type is "tuple[tuple[builtins.str, fallback=__main__.AKey], fallback=__main__.A] | tuple[tuple[builtins.str, fallback=__main__.BKey], fallback=__main__.B]" | |
| return x._replace() | |
| # no errors should be raised above. | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleUnionAnyMethodCall] | |
| from collections import namedtuple | |
| from typing import Any, Union | |
| T = namedtuple("T", ["x"]) | |
| class C(T): | |
| def f(self) -> bool: | |
| return True | |
| c: Union[C, Any] | |
| reveal_type(c.f()) # N: Revealed type is "builtins.bool | Any" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleAsClassMemberNoCrash] | |
| # https://github.com/python/mypy/issues/18736 | |
| from collections import namedtuple | |
| class Base: | |
| def __init__(self, namespace: tuple[str, ...]) -> None: | |
| # Not a bug: trigger defer | |
| names = [name for name in namespace if fail] # E: Name "fail" is not defined | |
| self.n = namedtuple("n", names) # E: NamedTuple type as an attribute is not supported | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleDefaultValueDefer] | |
| # flags: --debug-serialize | |
| from typing import NamedTuple | |
| class NT(NamedTuple): | |
| foo: int = UNDEFINED # E: Name "UNDEFINED" is not defined | |
| [builtins fixtures/tuple.pyi] | |
| [case testNamedTupleDefaultValueDefer2] | |
| # flags: --debug-serialize | |
| from typing import NamedTuple | |
| class NT(NamedTuple): | |
| foo: int = DEFERRED_INT | |
| class NT2(NamedTuple): | |
| foo: int = DEFERRED_STR # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| from foo import DEFERRED_INT, DEFERRED_STR | |
| [file foo.py] | |
| DEFERRED_INT = 1 | |
| DEFERRED_STR = "a" | |
| [builtins fixtures/tuple.pyi] |