| [case testNamedTupleUsedAsTuple] |
| from collections import namedtuple |
| |
| X = namedtuple('X', 'x y') |
| x = None # type: 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 = None # type: 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 testNamedTupleUnicode_python2] |
| from __future__ import unicode_literals |
| from collections import namedtuple |
| |
| # This test is a regression test for a bug where mypyc-compiled mypy |
| # would crash on namedtuple's with unicode arguments. Our test stubs |
| # don't actually allow that, though, so we ignore the error and just |
| # care we don't crash. |
| X = namedtuple('X', ('x', 'y')) # type: ignore |
| |
| [case testNamedTupleNoUnderscoreFields] |
| from collections import namedtuple |
| |
| X = namedtuple('X', 'x, _y, _z') # E: "namedtuple()" field names cannot start with an underscore: _y, _z |
| [builtins fixtures/tuple.pyi] |
| |
| [case testNamedTupleAccessingAttributes] |
| from collections import namedtuple |
| |
| X = namedtuple('X', 'x y') |
| x = None # type: X |
| x.x |
| x.y |
| x.z # E: "X" has no attribute "z" |
| [builtins fixtures/tuple.pyi] |
| |
| [case testNamedTupleClassPython35] |
| # flags: --python-version 3.5 |
| from typing import NamedTuple |
| |
| class A(NamedTuple): |
| x = 3 # type: int |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:4: error: NamedTuple class syntax is only supported in Python 3.6 |
| |
| [case testNamedTupleClassInStubPython35] |
| # flags: --python-version 3.5 |
| 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 = None # type: 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 = None # type: 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 |
| from typing_extensions import Protocol |
| |
| class HasX(Protocol): |
| x: str |
| |
| class A(NamedTuple): |
| x: str |
| |
| a: HasX = A("foo") |
| a.x = "bar" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:10: error: Incompatible types in assignment (expression has type "A", variable has type "HasX") |
| main:10: 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:5: error: Argument "rename" to "namedtuple" has incompatible type "str"; expected "int" |
| main:6: error: Unexpected keyword argument "unrecognized_arg" for "namedtuple" |
| <ROOT>/test-data/unit/lib-stub/collections.pyi:3: note: "namedtuple" defined here |
| main:7: error: Too many positional arguments for "namedtuple" |
| |
| [case testNamedTupleDefaults] |
| # flags: --python-version 3.7 |
| 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 "Optional[Iterable[Any]]" |
| |
| [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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: 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 = None # type: A |
| a = A('').member() |
| b = None # type: 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 = None # type: 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 = None # type: 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[[Tuple[int, ...], 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] |
| 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 |
| class MyNamedTuple(NamedTuple): |
| parent: 'MyNamedTuple' # E: Cannot resolve name "MyNamedTuple" (possible cyclic definition) |
| |
| 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 |
| |
| Node = NamedTuple('Node', [ |
| ('name', str), |
| ('children', Tuple['Node', ...]), # E: Cannot resolve name "Node" (possible cyclic definition) |
| ]) |
| n: Node |
| reveal_type(n) # N: Revealed type is "Tuple[builtins.str, builtins.tuple[Any, ...], fallback=__main__.Node]" |
| [builtins fixtures/tuple.pyi] |
| |
| [case testSelfRefNT2] |
| |
| from typing import Tuple, NamedTuple |
| |
| A = NamedTuple('A', [ |
| ('x', str), |
| ('y', Tuple['B', ...]), # E: Cannot resolve name "B" (possible cyclic definition) |
| ]) |
| 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]" |
| [builtins fixtures/tuple.pyi] |
| |
| [case testSelfRefNT3] |
| |
| from typing import NamedTuple, Tuple |
| |
| class B(NamedTuple): |
| x: Tuple[A, int] # E: Cannot resolve name "A" (possible cyclic definition) |
| 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 |
| |
| class B(NamedTuple): |
| x: A # E: Cannot resolve name "A" (possible cyclic definition) |
| 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 |
| |
| B = NamedTuple('B', [ |
| ('x', A), # E: Cannot resolve name "A" (possible cyclic 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], fallback=__main__.A]" |
| reveal_type(f) # N: Revealed type is "def (m: Tuple[Any, builtins.int, fallback=__main__.B])" |
| [builtins fixtures/tuple.pyi] |
| |
| [case testRecursiveNamedTupleInBases] |
| |
| from typing import List, NamedTuple, Union |
| |
| Exp = Union['A', 'B'] # E: Cannot resolve name "Exp" (possible cyclic definition) \ |
| # E: Cannot resolve name "A" (possible cyclic definition) |
| class A(NamedTuple('A', [('attr', List[Exp])])): pass |
| class B(NamedTuple('B', [('val', object)])): pass |
| |
| def my_eval(exp: Exp) -> int: |
| reveal_type(exp) # N: Revealed type is "Union[Any, Tuple[builtins.object, fallback=__main__.B]]" |
| if isinstance(exp, A): |
| my_eval(exp[0][0]) |
| return my_eval(exp.attr[0]) |
| if isinstance(exp, B): |
| return exp.val # E: Incompatible return value type (got "object", expected "int") |
| return 0 |
| |
| my_eval(A([B(1), B(2)])) # OK |
| [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 |
| |
| class Command(NamedTuple): |
| subcommands: List['Command'] # E: Cannot resolve name "Command" (possible cyclic definition) |
| |
| class HelpCommand(Command): |
| pass |
| |
| hc = HelpCommand(subcommands=[]) |
| reveal_type(hc) # N: Revealed type is "Tuple[builtins.list[Any], fallback=__main__.HelpCommand]" |
| [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 |
| 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] |
| 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 "Any" |
| [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.name) # N: Revealed type is "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] |