| -- Test cases for fine-grained incremental checking |
| -- |
| -- Test cases may define multiple versions of a file |
| -- (e.g. m.py, m.py.2). There is always an initial batch |
| -- pass that processes all files present initially, followed |
| -- by one or more fine-grained incremental passes that use |
| -- alternative versions of files, if available. If a file |
| -- just has a single .py version, it is used for all passes. |
| |
| -- TODO: what if version for some passes but not all |
| |
| -- Output is laid out like this: |
| -- |
| -- [out] |
| -- <optional output from batch pass> |
| -- == |
| -- <optional output from first incremental pass> |
| -- |
| -- |
| -- Modules that are expected to be detected as changed by dmypy_server |
| -- can be checked with [stale ...] |
| -- Generally this should mean added, deleted, or changed files, though there |
| -- are important edge cases related to the cache: deleted files won't be detected |
| -- as changed in the initial run with the cache while modules that depended on them |
| -- should be. |
| -- |
| -- Modules that are require a full-module reprocessing by update can be checked with |
| -- [rechecked ...]. This should include any files detected as having changed as well |
| -- as any files that contain targets that need to be reprocessed but which haven't |
| -- been loaded yet. If there is no [rechecked...] directive, it inherits the value of |
| -- [stale ...]. |
| -- |
| -- Specifications for later runs can be given with [stale2 ...], [stale3 ...], etc. |
| -- |
| -- Test runner can parse options from mypy.ini file. Updating this file in between |
| -- incremental runs is not yet supported. |
| -- |
| -- Each test case run without caching and with caching (if the initial run passes), |
| -- unless it has one a -only_when_cache or -only_when_nocache arguments. We sometimes |
| -- skip caching test cases to speed up tests, if the caching variant is not useful. |
| -- The caching test case variants get an implicit _cached suffix. |
| |
| [case testReprocessFunction] |
| import m |
| def g() -> int: |
| return m.f() |
| [file m.py] |
| def f() -> int: |
| pass |
| [file m.py.2] |
| def f() -> str: |
| pass |
| [out] |
| == |
| main:3: error: Incompatible return value type (got "str", expected "int") |
| |
| [case testReprocessTopLevel] |
| import m |
| m.f(1) |
| def g() -> None: pass |
| [file m.py] |
| def f(x: int) -> None: pass |
| [file m.py.2] |
| def f(x: str) -> None: pass |
| [out] |
| == |
| main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str" |
| |
| [case testReprocessMethod] |
| import m |
| class B: |
| def f(self, a: m.A) -> None: |
| a.g() # E |
| [file m.py] |
| class A: |
| def g(self) -> None: pass |
| [file m.py.2] |
| class A: |
| def g(self, a: A) -> None: pass |
| [out] |
| == |
| main:4: error: Missing positional argument "a" in call to "g" of "A" |
| |
| [case testReprocessMethodShowSource] |
| # flags: --pretty --show-error-codes |
| import m |
| class B: |
| def f(self, a: m.A) -> None: |
| a.g() # E |
| [file m.py] |
| class A: |
| def g(self) -> None: pass |
| [file m.py.2] |
| class A: |
| def g(self, a: A) -> None: pass |
| [out] |
| == |
| main:5: error: Missing positional argument "a" in call to "g" of "A" [call-arg] |
| a.g() # E |
| ^ |
| |
| [case testFunctionMissingModuleAttribute] |
| import m |
| def h() -> None: |
| m.f(1) |
| [file m.py] |
| def f(x: int) -> None: pass |
| [file m.py.2] |
| def g(x: str) -> None: pass |
| [builtins fixtures/fine_grained.pyi] |
| [out] |
| == |
| main:3: error: Module has no attribute "f" |
| |
| [case testTopLevelMissingModuleAttribute] |
| import m |
| m.f(1) |
| def g() -> None: pass |
| [file m.py] |
| def f(x: int) -> None: pass |
| [file m.py.2] |
| def g(x: int) -> None: pass |
| [builtins fixtures/fine_grained.pyi] |
| [out] |
| == |
| main:2: error: Module has no attribute "f" |
| |
| [case testClassChangedIntoFunction] |
| |
| import m |
| def f(a: m.A) -> None: |
| pass |
| [file m.py] |
| class A: pass |
| [file m.py.2] |
| def A() -> None: pass |
| [out] |
| == |
| main:3: error: Function "m.A" is not valid as a type |
| main:3: note: Perhaps you need "Callable[...]" or a callback protocol? |
| |
| [case testClassChangedIntoFunction2] |
| |
| import m |
| class B: |
| def f(self, a: m.A) -> None: pass |
| [file m.py] |
| class A: pass |
| [file m.py.2] |
| def A() -> None: pass |
| [file n.py.3] |
| [out] |
| == |
| main:4: error: Function "m.A" is not valid as a type |
| main:4: note: Perhaps you need "Callable[...]" or a callback protocol? |
| == |
| main:4: error: Function "m.A" is not valid as a type |
| main:4: note: Perhaps you need "Callable[...]" or a callback protocol? |
| |
| [case testAttributeTypeChanged] |
| import m |
| def f(a: m.A) -> int: |
| return a.x |
| [file m.py] |
| class A: |
| def f(self) -> None: |
| self.x = 1 |
| [file m.py.2] |
| class A: |
| def f(self) -> None: |
| self.x = 'x' |
| [out] |
| == |
| main:3: error: Incompatible return value type (got "str", expected "int") |
| |
| [case testAttributeRemoved] |
| import m |
| def f(a: m.A) -> int: |
| return a.x |
| [file m.py] |
| class A: |
| def f(self) -> None: |
| self.x = 1 |
| [file m.py.2] |
| class A: |
| def f(self) -> None: pass |
| [out] |
| == |
| main:3: error: "A" has no attribute "x" |
| |
| [case testVariableTypeBecomesInvalid] |
| import m |
| def f() -> None: |
| a = None # type: m.A |
| [file m.py] |
| class A: pass |
| [file m.py.2] |
| [out] |
| == |
| main:3: error: Name 'm.A' is not defined |
| |
| [case testTwoIncrementalSteps] |
| import m |
| import n |
| [file m.py] |
| def f() -> None: pass |
| [file n.py] |
| import m |
| def g() -> None: |
| m.f() # E |
| [file m.py.2] |
| import n |
| def f(x: int) -> None: |
| n.g() # E |
| [file n.py.3] |
| import m |
| def g(a: str) -> None: |
| m.f('') # E |
| [out] |
| == |
| n.py:3: error: Missing positional argument "x" in call to "f" |
| == |
| n.py:3: error: Argument 1 to "f" has incompatible type "str"; expected "int" |
| m.py:3: error: Missing positional argument "a" in call to "g" |
| |
| [case testTwoRounds] |
| import m |
| def h(a: m.A) -> int: |
| return a.x |
| [file m.py] |
| import n |
| class A: |
| def g(self, b: n.B) -> None: |
| self.x = b.f() |
| [file n.py] |
| class B: |
| def f(self) -> int: pass |
| [file n.py.2] |
| class B: |
| def f(self) -> str: pass |
| [out] |
| == |
| main:3: error: Incompatible return value type (got "str", expected "int") |
| |
| [case testFixTypeError] |
| import m |
| def f(a: m.A) -> None: |
| a.f(a) |
| [file m.py] |
| class A: |
| def f(self, a: 'A') -> None: pass |
| [file m.py.2] |
| class A: |
| def f(self) -> None: pass |
| [file m.py.3] |
| class A: |
| def f(self, a: 'A') -> None: pass |
| [out] |
| == |
| main:3: error: Too many arguments for "f" of "A" |
| == |
| |
| [case testFixTypeError2] |
| import m |
| def f(a: m.A) -> None: |
| a.f() |
| [file m.py] |
| class A: |
| def f(self) -> None: pass |
| [file m.py.2] |
| class A: |
| def g(self) -> None: pass |
| [file m.py.3] |
| class A: |
| def f(self) -> None: pass |
| [out] |
| == |
| main:3: error: "A" has no attribute "f" |
| == |
| |
| [case testFixSemanticAnalysisError] |
| import m |
| def f() -> None: |
| m.A() |
| [file m.py] |
| class A: pass |
| [file m.py.2] |
| class B: pass |
| [file m.py.3] |
| class A: pass |
| [builtins fixtures/fine_grained.pyi] |
| [out] |
| == |
| main:3: error: Module has no attribute "A" |
| == |
| |
| [case testContinueToReportTypeCheckError] |
| import m |
| def f(a: m.A) -> None: |
| a.f() |
| def g(a: m.A) -> None: |
| a.g() |
| [file m.py] |
| class A: |
| def f(self) -> None: pass |
| def g(self) -> None: pass |
| [file m.py.2] |
| class A: pass |
| [file m.py.3] |
| class A: |
| def f(self) -> None: pass |
| [out] |
| == |
| main:3: error: "A" has no attribute "f" |
| main:5: error: "A" has no attribute "g" |
| == |
| main:5: error: "A" has no attribute "g" |
| |
| [case testContinueToReportSemanticAnalysisError] |
| import m |
| def f() -> None: |
| m.A() |
| def g() -> None: |
| m.B() |
| [file m.py] |
| class A: pass |
| class B: pass |
| [file m.py.2] |
| [file m.py.3] |
| class A: pass |
| [builtins fixtures/fine_grained.pyi] |
| [out] |
| == |
| main:3: error: Module has no attribute "A" |
| main:5: error: Module has no attribute "B" |
| == |
| main:5: error: Module has no attribute "B" |
| |
| [case testContinueToReportErrorAtTopLevel-only_when_nocache] |
| -- Different cache/no-cache tests because: |
| -- Error message ordering differs |
| import n |
| import m |
| m.A().f() |
| [file n.py] |
| import m |
| m.A().g() |
| [file m.py] |
| class A: |
| def f(self) -> None: pass |
| def g(self) -> None: pass |
| [file m.py.2] |
| class A: pass |
| [file m.py.3] |
| class A: |
| def f(self) -> None: pass |
| [out] |
| == |
| main:3: error: "A" has no attribute "f" |
| n.py:2: error: "A" has no attribute "g" |
| == |
| n.py:2: error: "A" has no attribute "g" |
| |
| [case testContinueToReportErrorAtTopLevel-only_when_cache] |
| -- Different cache/no-cache tests because: |
| -- Error message ordering differs |
| import n |
| import m |
| m.A().f() |
| [file n.py] |
| import m |
| m.A().g() |
| [file m.py] |
| class A: |
| def f(self) -> None: pass |
| def g(self) -> None: pass |
| [file m.py.2] |
| class A: pass |
| [file m.py.3] |
| class A: |
| def f(self) -> None: pass |
| [out] |
| == |
| n.py:2: error: "A" has no attribute "g" |
| main:3: error: "A" has no attribute "f" |
| == |
| n.py:2: error: "A" has no attribute "g" |
| |
| [case testContinueToReportErrorInMethod] |
| import m |
| class C: |
| def f(self, a: m.A) -> None: |
| a.f() |
| def g(self, a: m.A) -> None: |
| a.g() |
| [file m.py] |
| class A: |
| def f(self) -> None: pass |
| def g(self) -> None: pass |
| [file m.py.2] |
| class A: pass |
| [file m.py.3] |
| class A: |
| def f(self) -> None: pass |
| [out] |
| == |
| main:4: error: "A" has no attribute "f" |
| main:6: error: "A" has no attribute "g" |
| == |
| main:6: error: "A" has no attribute "g" |
| |
| [case testInitialBatchGeneratedError] |
| import m |
| def g() -> None: |
| m.f() |
| def h() -> None: |
| m.g() |
| [file m.py] |
| def f(x: object) -> None: pass |
| [file m.py.2] |
| def f() -> None: pass |
| [file m.py.3] |
| def f() -> None: pass |
| def g() -> None: pass |
| [builtins fixtures/fine_grained.pyi] |
| [out] |
| main:3: error: Missing positional argument "x" in call to "f" |
| main:5: error: Module has no attribute "g" |
| == |
| main:5: error: Module has no attribute "g" |
| == |
| |
| [case testKeepReportingErrorIfNoChanges] |
| import m |
| def h() -> None: |
| m.g() |
| [file m.py] |
| [file m.py.2] |
| [builtins fixtures/fine_grained.pyi] |
| [out] |
| main:3: error: Module has no attribute "g" |
| == |
| main:3: error: Module has no attribute "g" |
| |
| [case testFixErrorAndReintroduce] |
| import m |
| def h() -> None: |
| m.g() |
| [file m.py] |
| [file m.py.2] |
| def g() -> None: pass |
| [file m.py.3] |
| [builtins fixtures/fine_grained.pyi] |
| [out] |
| main:3: error: Module has no attribute "g" |
| == |
| == |
| main:3: error: Module has no attribute "g" |
| |
| [case testIgnoreWorksAfterUpdate] |
| import a |
| [file a.py] |
| import b |
| int() + str() # type: ignore |
| [file b.py] |
| x = 1 |
| [file b.py.2] |
| x = 2 |
| [file b.py.3] |
| x = 3 |
| [delete b.py.4] |
| [out] |
| == |
| == |
| == |
| a.py:1: error: Cannot find implementation or library stub for module named "b" |
| a.py:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports |
| |
| [case testIgnoreWorksWithMissingImports] |
| import a |
| [file a.py] |
| import b |
| import xyz # type: ignore |
| xyz.whatever |
| [file b.py] |
| x = 1 |
| [file b.py.2] |
| x = 2 |
| [file b.py.3] |
| x = 3 |
| [file xyz.py.4] |
| [out] |
| == |
| == |
| == |
| a.py:3: error: "object" has no attribute "whatever" |
| |
| [case testAddedIgnoreWithMissingImports] |
| import a |
| [file a.py] |
| from b import x |
| y: int = x |
| [file b.py] |
| from xyz import x |
| [file b.py.2] |
| from xyz import x # type: ignore |
| [file xyz.py.3] |
| x = str() |
| [out] |
| b.py:1: error: Cannot find implementation or library stub for module named "xyz" |
| b.py:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports |
| == |
| == |
| a.py:2: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testRemovedIgnoreWithMissingImport] |
| import a |
| [file a.py] |
| from b import x |
| y: int = x |
| [file b.py] |
| from xyz import x # type: ignore |
| [file b.py.2] |
| from xyz import x |
| [file xyz.py.3] |
| x = str() |
| [out] |
| == |
| b.py:1: error: Cannot find implementation or library stub for module named "xyz" |
| b.py:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports |
| == |
| a.py:2: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testRemovedModuleUnderIgnore] |
| import a |
| [file a.py] |
| import c |
| from b import x # type: ignore |
| y: int = x |
| [file b.py] |
| x = str() |
| [file c.py] |
| x = 1 |
| [delete b.py.2] |
| [file c.py.3] |
| x = 3 |
| [out] |
| a.py:3: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| == |
| == |
| |
| [case AddedModuleUnderIgnore] |
| import a |
| [file a.py] |
| import c |
| from b import x # type: ignore |
| y: int = x |
| [file c.py] |
| x = 1 |
| [file c.py.2] |
| x = 2 |
| [file b.py.3] |
| # empty |
| [out] |
| == |
| == |
| |
| [case testIgnoreInBetween] |
| import a |
| [file a.py] |
| import b |
| x: int = b.x |
| [file b.py] |
| import c |
| x = c.C.x # type: ignore |
| [file c.py] |
| class C: |
| pass |
| [file c.py.2] |
| class C: |
| x: int |
| [file c.py.3] |
| # empty |
| [file c.py.4] |
| class C: |
| x: str |
| [out] |
| == |
| == |
| == |
| a.py:2: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testIgnoredAttrReprocessedModule] |
| import a |
| [file a.py] |
| import b |
| x = b.x # type: ignore |
| y: int = x |
| [file b.py] |
| import c |
| [file b.py.2] |
| import c |
| x = c.x |
| [file c.py] |
| x: str |
| [out] |
| == |
| a.py:3: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testIgnoredAttrReprocessedBase] |
| import a |
| [file a.py] |
| import b |
| def fun() -> None: |
| x = b.C.x # type: ignore |
| y: int = x |
| [file b.py] |
| import c |
| class C: |
| pass |
| [file b.py.2] |
| import c |
| class C(c.B): |
| pass |
| [file c.py] |
| class B: |
| x: str |
| [out] |
| == |
| a.py:4: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testIgnoredAttrReprocessedMeta] |
| import a |
| [file a.py] |
| import b |
| def fun() -> None: |
| x = b.C.x # type: ignore |
| y: int = x |
| [file b.py] |
| import c |
| class C: |
| pass |
| [file b.py.2] |
| import c |
| class C(metaclass=c.M): |
| pass |
| [file c.py] |
| class M(type): |
| x: str |
| [out] |
| == |
| a.py:4: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testDataclassUpdate1] |
| # flags: --python-version 3.7 |
| [file a.py] |
| from dataclasses import dataclass |
| |
| @dataclass |
| class A: |
| x: int |
| |
| [file b.py] |
| from dataclasses import dataclass |
| |
| from a import A |
| @dataclass |
| class B(A): |
| y: int |
| |
| B(1, 2) |
| |
| [file a.py.2] |
| from dataclasses import dataclass |
| |
| @dataclass |
| class A: |
| x: str |
| |
| [file a.py.3] |
| from dataclasses import dataclass |
| |
| @dataclass |
| class A: |
| x: int |
| |
| [out] |
| == |
| b.py:8: error: Argument 1 to "B" has incompatible type "int"; expected "str" |
| == |
| [builtins fixtures/list.pyi] |
| |
| [case testDataclassUpdate2] |
| # flags: --python-version 3.7 |
| [file c.py] |
| Foo = int |
| |
| [file c.py.2] |
| Foo = str |
| |
| [file a.py] |
| from dataclasses import dataclass |
| from c import Foo |
| |
| @dataclass |
| class A: |
| x: Foo |
| |
| [file b.py] |
| from dataclasses import dataclass |
| |
| from a import A |
| @dataclass |
| class B(A): |
| y: int |
| |
| B(1, 2) |
| |
| [out] |
| == |
| b.py:8: error: Argument 1 to "B" has incompatible type "int"; expected "str" |
| [builtins fixtures/list.pyi] |
| |
| [case testDataclassUpdate3] |
| # flags: --python-version 3.7 |
| from b import B |
| B(1, 2) |
| [file b.py] |
| from a import A |
| from dataclasses import dataclass |
| @dataclass |
| class B(A): |
| b: int |
| [file a.py] |
| from dataclasses import dataclass |
| @dataclass |
| class A: |
| a: int |
| |
| [file a.py.2] |
| from dataclasses import dataclass |
| @dataclass |
| class A: |
| a: int |
| other: int |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:3: error: Missing positional argument "b" in call to "B" |
| |
| [case testDataclassUpdate4] |
| # flags: --python-version 3.7 |
| from b import B |
| B(1, 2) |
| [file b.py] |
| from a import A |
| from dataclasses import dataclass |
| @dataclass(frozen=True) |
| class B(A): |
| b: int |
| [file a.py] |
| from dataclasses import dataclass |
| @dataclass(frozen=True) |
| class A: |
| a: int |
| |
| [file a.py.2] |
| from dataclasses import dataclass |
| @dataclass(frozen=True) |
| class A: |
| a: int |
| other: int |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:3: error: Missing positional argument "b" in call to "B" |
| |
| [case testDataclassUpdate5] |
| # flags: --python-version 3.7 |
| from b import B |
| B(1, 2) |
| [file b.py] |
| from a import A |
| from dataclasses import dataclass |
| @dataclass |
| class B(A): |
| b: int |
| [file a.py] |
| from dataclasses import dataclass |
| @dataclass(init=False) |
| class A: |
| a: int |
| |
| [file a.py.2] |
| from dataclasses import dataclass |
| @dataclass(init=False) |
| class A: |
| a: int |
| other: int |
| |
| [file a.py.3] |
| from dataclasses import dataclass |
| @dataclass(init=False) |
| class A: |
| a: int |
| |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:3: error: Missing positional argument "b" in call to "B" |
| == |
| |
| [case testDataclassUpdate6] |
| # flags: --python-version 3.7 |
| from b import B |
| B(1, 2) < B(1, 2) |
| [file b.py] |
| from a import A |
| from dataclasses import dataclass |
| @dataclass |
| class B(A): |
| b: int |
| [file a.py] |
| from dataclasses import dataclass |
| @dataclass(order=True) |
| class A: |
| a: int |
| |
| [file a.py.2] |
| from dataclasses import dataclass |
| @dataclass |
| class A: |
| a: int |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:3: error: Unsupported left operand type for < ("B") |
| |
| [case testDataclassUpdate8] |
| # flags: --python-version 3.7 |
| from c import C |
| C(1, 2, 3) |
| [file c.py] |
| from b import B |
| from dataclasses import dataclass |
| @dataclass |
| class C(B): |
| c: int |
| [file b.py] |
| from a import A |
| from dataclasses import dataclass |
| @dataclass |
| class B(A): |
| b: int |
| [file a.py] |
| from dataclasses import dataclass |
| @dataclass |
| class A: |
| a: int |
| |
| [file a.py.2] |
| from dataclasses import dataclass |
| @dataclass |
| class A: |
| a: int |
| other: int |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:3: error: Missing positional argument "c" in call to "C" |
| |
| [case testDataclassUpdate9] |
| # flags: --python-version 3.7 |
| from c import C |
| C(1, 2, 3) |
| [file c.py] |
| from b import B |
| from dataclasses import dataclass |
| @dataclass |
| class C(B): |
| c: int |
| [file b.py] |
| from a import A |
| from dataclasses import dataclass |
| @dataclass |
| class B(A): |
| b: int |
| [file a.py] |
| from dataclasses import dataclass |
| @dataclass(init=False) |
| class A: |
| a: int |
| |
| [file a.py.2] |
| from dataclasses import dataclass |
| @dataclass(init=False) |
| class A: |
| a: int |
| other: int |
| |
| [file a.py.3] |
| from dataclasses import dataclass |
| @dataclass(init=False) |
| class A: |
| a: int |
| |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:3: error: Missing positional argument "c" in call to "C" |
| == |
| |
| [case testAttrsUpdate1] |
| [file a.py] |
| import attr |
| @attr.s |
| class A: |
| a = attr.ib() # type: int |
| |
| [file b.py] |
| from a import A |
| import attr |
| @attr.s |
| class B(A): |
| b = attr.ib() # type: int |
| |
| B(1, 2) |
| |
| [file a.py.2] |
| import attr |
| @attr.s |
| class A: |
| a = attr.ib() # type: int |
| other = attr.ib() # type: int |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| b.py:7: error: Missing positional argument "b" in call to "B" |
| |
| [case testAttrsUpdate2] |
| from b import B |
| B(1, 2) |
| [file b.py] |
| from a import A |
| import attr |
| @attr.s |
| class B(A): |
| b = attr.ib() # type: int |
| [file a.py] |
| import attr |
| @attr.s(init=False) |
| class A: |
| a = attr.ib() # type: int |
| |
| [file a.py.2] |
| import attr |
| @attr.s(init=False) |
| class A: |
| a = attr.ib() # type: int |
| other = attr.ib() # type: int |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:2: error: Missing positional argument "b" in call to "B" |
| |
| [case testAttrsUpdate3] |
| from b import B |
| B(1, 2) |
| [file b.py] |
| from a import A |
| import attr |
| @attr.s(auto_attribs=True) |
| class B(A): |
| x: int |
| [file a.py] |
| import attr |
| @attr.s(auto_attribs=True, init=False) |
| class A: |
| a: int |
| |
| [file a.py.2] |
| import attr |
| @attr.s(auto_attribs=True, init=False) |
| class A: |
| a: int |
| other: int |
| [builtins fixtures/list.pyi] |
| |
| [file a.py.3] |
| import attr |
| @attr.s(auto_attribs=True, init=False) |
| class A: |
| a: int |
| [builtins fixtures/list.pyi] |
| |
| [out] |
| == |
| main:2: error: Missing positional argument "x" in call to "B" |
| == |
| |
| [case testAttrsUpdate4] |
| from b import B |
| B(1, 2) < B(1, 2) |
| [file b.py] |
| from a import A |
| import attr |
| @attr.s(eq=False) |
| class B(A): |
| b = attr.ib() # type: int |
| [file a.py] |
| import attr |
| @attr.s(init=False) |
| class A: |
| a = attr.ib() # type: int |
| |
| [file a.py.2] |
| import attr |
| @attr.s(eq=False, init=False) |
| class A: |
| a = attr.ib() # type: int |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:2: error: Unsupported left operand type for < ("B") |
| |
| [case testAttrsUpdateBaseKwOnly] |
| from b import B |
| B(5) |
| [file a.py] |
| import attr |
| @attr.s() |
| class A: |
| a = attr.ib(15) # type: int |
| [file b.py] |
| from a import A |
| import attr |
| @attr.s(kw_only=True) |
| class B(A): |
| b = attr.ib("16") # type: str |
| |
| [file a.py.2] |
| import attr |
| @attr.s(kw_only=True) |
| class A: |
| a = attr.ib(15) # type: int |
| [builtins fixtures/attr.pyi] |
| [out] |
| == |
| main:2: error: Too many positional arguments for "B" |
| |
| [case testAddBaseClassMethodCausingInvalidOverride] |
| import m |
| class B(m.A): |
| def f(self) -> str: pass |
| [file m.py] |
| class A: pass |
| [file m.py.2] |
| class A: |
| def f(self) -> int: pass |
| [file n.py.3] |
| [out] |
| == |
| main:3: error: Return type "str" of "f" incompatible with return type "int" in supertype "A" |
| == |
| main:3: error: Return type "str" of "f" incompatible with return type "int" in supertype "A" |
| |
| [case testModifyBaseClassMethodCausingInvalidOverride] |
| import m |
| class B(m.A): |
| def f(self) -> str: pass |
| [file m.py] |
| class A: |
| def f(self) -> str: pass |
| [file m.py.2] |
| class A: |
| def f(self) -> int: pass |
| [out] |
| == |
| main:3: error: Return type "str" of "f" incompatible with return type "int" in supertype "A" |
| |
| [case testAddBaseClassAttributeCausingErrorInSubclass] |
| import m |
| class B(m.A): |
| def a(self) -> None: |
| x = 1 |
| if int(): |
| x = self.x |
| |
| def f(self) -> None: |
| self.x = 1 |
| |
| def z(self) -> None: |
| x = 1 |
| if int(): |
| x = self.x |
| [file m.py] |
| class A: pass |
| [file m.py.2] |
| class A: |
| def g(self) -> None: |
| self.x = 'a' |
| [out] |
| == |
| main:6: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| main:9: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| main:14: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testChangeBaseClassAttributeType] |
| import m |
| class B(m.A): |
| def f(sel) -> None: |
| sel.x = 1 |
| [file m.py] |
| class A: |
| def g(self) -> None: |
| self.x = 1 |
| [file m.py.2] |
| class A: |
| def g(self) -> None: |
| self.x = 'a' |
| [out] |
| == |
| main:4: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testRemoveAttributeInBaseClass] |
| import m |
| class B(m.A): |
| def f(self) -> None: |
| a = 1 |
| a = self.x |
| [file m.py] |
| class A: |
| def g(self) -> None: |
| self.x = 1 |
| [file m.py.2] |
| class A: pass |
| [out] |
| == |
| main:5: error: "B" has no attribute "x" |
| |
| [case testTestSignatureOfInheritedMethod] |
| import m |
| class B(m.A): |
| def f(self) -> None: |
| self.g() |
| [file m.py] |
| class A: |
| def g(self) -> None: pass |
| [file m.py.2] |
| class A: |
| def g(self, a: 'A') -> None: pass |
| [out] |
| == |
| main:4: error: Missing positional argument "a" in call to "g" of "A" |
| |
| [case testRemoveBaseClass] |
| import m |
| class A(m.B): |
| def f(self) -> None: |
| self.g() |
| self.x |
| self.y = 1 |
| [file m.py] |
| class C: |
| def g(self) -> None: |
| self.x = 1 |
| class B(C): pass |
| [file m.py.2] |
| class C: pass |
| class B: pass |
| [out] |
| == |
| main:4: error: "A" has no attribute "g" |
| main:5: error: "A" has no attribute "x" |
| |
| [case testRemoveBaseClass2] |
| import m |
| class A(m.B): |
| def f(self) -> None: |
| self.g() |
| self.x |
| self.y = 1 |
| [file m.py] |
| class C: |
| def g(self) -> None: |
| self.x = 1 |
| class B(C): pass |
| [file m.py.2] |
| class C: |
| def g(self) -> None: |
| self.x = 1 |
| class B: pass |
| [out] |
| == |
| main:4: error: "A" has no attribute "g" |
| main:5: error: "A" has no attribute "x" |
| |
| [case testChangeInPackage] |
| import m.n |
| def f() -> None: |
| m.n.g() |
| [file m/__init__.py] |
| [file m/n.py] |
| def g() -> None: pass |
| [file m/n.py.2] |
| def g(x: int) -> None: pass |
| [out] |
| == |
| main:3: error: Missing positional argument "x" in call to "g" |
| |
| [case testTriggerTargetInPackage] |
| import m.n |
| [file m/__init__.py] |
| [file m/n.py] |
| import a |
| def f() -> None: |
| a.g() |
| [file a.py] |
| def g() -> None: pass |
| [file a.py.2] |
| def g(x: int) -> None: pass |
| [out] |
| == |
| m/n.py:3: error: Missing positional argument "x" in call to "g" |
| |
| [case testChangeInPackage__init__] |
| import m |
| import m.n |
| def f() -> None: |
| m.g() |
| [file m/__init__.py] |
| def g() -> None: pass |
| [file m/__init__.py.2] |
| def g(x: int) -> None: pass |
| [file m/n.py] |
| [out] |
| == |
| main:4: error: Missing positional argument "x" in call to "g" |
| |
| [case testTriggerTargetInPackage__init__] |
| import m |
| import m.n |
| [file m/__init__.py] |
| import a |
| def f() -> None: |
| a.g() |
| [file a.py] |
| def g() -> None: pass |
| [file a.py.2] |
| def g(x: int) -> None: pass |
| [file m/n.py] |
| [out] |
| == |
| m/__init__.py:3: error: Missing positional argument "x" in call to "g" |
| |
| [case testModuleAttributeTypeChanges] |
| import m |
| def f() -> None: |
| x = 1 |
| if int(): |
| x = m.x |
| [file m.py] |
| x = 1 |
| [file m.py.2] |
| x = '' |
| [out] |
| == |
| main:5: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testTwoStepsDueToModuleAttribute] |
| import m |
| x = m.f() |
| |
| def g() -> None: |
| y = 1 |
| if int(): |
| y = x # E |
| [file m.py] |
| def f() -> int: pass |
| [file m.py.2] |
| def f() -> str: pass |
| [out] |
| == |
| main:7: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testTwoStepsDueToMultipleNamespaces] |
| import m |
| x = m.f() |
| |
| def g() -> None: |
| xx = 1 |
| if int(): |
| xx = x # E |
| |
| class A: |
| def a(self) -> None: |
| self.y = m.f() |
| def b(self) -> None: |
| yy = 1 |
| if int(): |
| yy = self.y |
| |
| class B: |
| def c(self) -> None: |
| self.z = m.f() |
| def b(self) -> None: |
| zz = 1 |
| if int(): |
| zz = self.z |
| [file m.py] |
| def f() -> int: pass |
| [file m.py.2] |
| def f() -> str: pass |
| [out] |
| == |
| main:7: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| main:15: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| main:23: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testConstructorSignatureChanged] |
| import m |
| |
| def f() -> None: |
| m.A() |
| [file m.py] |
| class A: |
| def __init__(self) -> None: pass |
| [file m.py.2] |
| class A: |
| def __init__(self, x: int) -> None: pass |
| [out] |
| == |
| main:4: error: Missing positional argument "x" in call to "A" |
| |
| [case testConstructorSignatureChanged2] |
| from typing import Callable |
| import m |
| |
| def use(x: Callable[[], m.A]) -> None: |
| x() |
| def f() -> None: |
| use(m.A) |
| [file m.py] |
| class A: |
| def __init__(self) -> None: pass |
| [file m.py.2] |
| class A: |
| def __init__(self, x: int) -> None: pass |
| [out] |
| == |
| -- This is a bad error message |
| main:7: error: Argument 1 to "use" has incompatible type "Type[A]"; expected "Callable[[], A]" |
| |
| [case testConstructorSignatureChanged3] |
| from a import C |
| class D(C): |
| def g(self) -> None: |
| super().__init__() |
| D() |
| [file a.py] |
| class C: |
| def __init__(self) -> None: pass |
| [file a.py.2] |
| class C: |
| def __init__(self, x: int) -> None: pass |
| [out] |
| == |
| main:4: error: Missing positional argument "x" in call to "__init__" of "C" |
| main:5: error: Missing positional argument "x" in call to "D" |
| |
| [case testConstructorAdded] |
| import m |
| |
| def f() -> None: |
| m.A() |
| [file m.py] |
| class A: pass |
| [file m.py.2] |
| class A: |
| def __init__(self, x: int) -> None: pass |
| [out] |
| == |
| main:4: error: Missing positional argument "x" in call to "A" |
| |
| [case testConstructorDeleted] |
| import m |
| |
| def f() -> None: |
| m.A(1) |
| [file m.py] |
| class A: |
| def __init__(self, x: int) -> None: pass |
| [file m.py.2] |
| class A: pass |
| [out] |
| == |
| main:4: error: Too many arguments for "A" |
| |
| [case testBaseClassConstructorChanged] |
| import m |
| |
| def f() -> None: |
| m.B() |
| [file m.py] |
| class A: |
| def __init__(self) -> None: pass |
| class B(A): pass |
| [file m.py.2] |
| class A: |
| def __init__(self, x: int) -> None: pass |
| class B(A): pass |
| [out] |
| == |
| main:4: error: Missing positional argument "x" in call to "B" |
| |
| [case testSuperField] |
| from a import C |
| class D(C): |
| def g(self) -> int: |
| return super().x |
| [file a.py] |
| class C: |
| def __init__(self) -> None: self.x = 12 |
| [file a.py.2] |
| class C: |
| def __init__(self) -> None: self.x = 'ar' |
| [out] |
| == |
| main:4: error: Incompatible return value type (got "str", expected "int") |
| |
| [case testImportFrom] |
| from m import f |
| |
| def g() -> None: |
| f() |
| [file m.py] |
| def f() -> None: pass |
| [file m.py.2] |
| def f(x: int) -> None: pass |
| [builtins fixtures/fine_grained.pyi] |
| [out] |
| == |
| main:4: error: Missing positional argument "x" in call to "f" |
| |
| [case testImportFrom2] |
| from m import f |
| f() |
| [file m.py] |
| def f() -> None: pass |
| [file m.py.2] |
| def f(x: int) -> None: pass |
| [out] |
| == |
| main:2: error: Missing positional argument "x" in call to "f" |
| |
| [case testImportFromTargetsClass] |
| from m import C |
| |
| def f(c: C) -> None: |
| c.g() |
| [file m.py] |
| class C: |
| def g(self) -> None: pass |
| [file m.py.2] |
| class C: |
| def g(self, x: int) -> None: pass |
| [out] |
| == |
| main:4: error: Missing positional argument "x" in call to "g" of "C" |
| |
| [case testImportFromTargetsVariable] |
| from m import x |
| |
| def f() -> None: |
| y = 1 |
| if int(): |
| y = x |
| [file m.py] |
| x = 1 |
| [file m.py.2] |
| x = '' |
| [out] |
| == |
| main:6: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testImportFromSubmoduleOfPackage] |
| from m import n |
| |
| def f() -> None: |
| n.g() |
| [file m/__init__.py] |
| [file m/n.py] |
| def g() -> None: pass |
| [file m/n.py.2] |
| def g(x: int) -> None: pass |
| [out] |
| == |
| main:4: error: Missing positional argument "x" in call to "g" |
| |
| [case testImportedFunctionGetsImported] |
| from m import f |
| |
| def g() -> None: |
| f() |
| [file m.py] |
| from n import f |
| [file n.py] |
| def f() -> None: pass |
| [file n.py.2] |
| def f(x: int) -> None: pass |
| [out] |
| == |
| main:4: error: Missing positional argument "x" in call to "f" |
| |
| [case testNestedClassMethodSignatureChanges] |
| from m import A |
| |
| def f(x: A.B) -> None: |
| x.g() |
| [file m.py] |
| class A: |
| class B: |
| def g(self) -> None: pass |
| [file m.py.2] |
| class A: |
| class B: |
| def g(self, x: int) -> None: pass |
| [out] |
| == |
| main:4: error: Missing positional argument "x" in call to "g" of "B" |
| |
| [case testNestedClassAttributeTypeChanges] |
| from m import A |
| |
| def f(x: A.B) -> None: |
| z = 1 |
| if int(): |
| z = x.y |
| [file m.py] |
| class A: |
| class B: |
| def g(self) -> None: |
| self.y = 1 |
| [file m.py.2] |
| class A: |
| class B: |
| def g(self) -> None: |
| self.y = '' |
| [out] |
| == |
| main:6: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testReprocessMethodInNestedClass] |
| from m import f |
| |
| class A: |
| class B: |
| def g(self) -> None: |
| x = 1 |
| if int(): |
| x = f() |
| [file m.py] |
| def f() -> int: pass |
| [file m.py.2] |
| def f() -> str: pass |
| [file n.py.3] |
| [out] |
| == |
| main:8: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| == |
| main:8: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testReprocessMethodInNestedClassSemanal] |
| import a |
| [file a.py] |
| class A: |
| class B: |
| def g() -> None: pass |
| def foo(self) -> int: return 12 |
| [file b.py.2] |
| [file b.py.3] |
| 2 |
| [out] |
| a.py:3: error: Method must have at least one argument |
| == |
| a.py:3: error: Method must have at least one argument |
| == |
| a.py:3: error: Method must have at least one argument |
| |
| [case testBaseClassDeleted] |
| import m |
| |
| class A(m.C): |
| def f(self) -> None: |
| self.g() # No error here because m.C becomes an Any base class |
| def g(self) -> None: |
| self.x |
| [file m.py] |
| class C: |
| def g(self) -> None: pass |
| [file m.py.2] |
| [out] |
| main:7: error: "A" has no attribute "x" |
| == |
| main:3: error: Name 'm.C' is not defined |
| |
| [case testBaseClassOfNestedClassDeleted] |
| import m |
| |
| class A: |
| class B(m.C): |
| def f(self) -> None: |
| self.g() # No error here because m.C becomes an Any base class |
| def g(self) -> None: |
| self.x |
| [file m.py] |
| class C: |
| def g(self) -> None: pass |
| [file m.py.2] |
| [out] |
| main:8: error: "B" has no attribute "x" |
| == |
| main:4: error: Name 'm.C' is not defined |
| |
| [case testImportQualifiedModuleName] |
| import a |
| [file a.py] |
| import b.c |
| b.c.f() |
| [file a.py.2] |
| import b.c |
| b.c.f() # dummy change |
| [file b/__init__.py] |
| [file b/c.py] |
| def f() -> None: pass |
| [out] |
| == |
| |
| [case testTypeAliasRefresh] |
| from typing import Callable |
| from a import f |
| C = Callable[[int], str] |
| [file a.py] |
| def f() -> None: pass |
| [file a.py.2] |
| [out] |
| == |
| main:2: error: Module 'a' has no attribute 'f' |
| |
| [case testTypeVarRefresh] |
| from typing import TypeVar |
| from a import f |
| T = TypeVar('T') |
| [file a.py] |
| def f() -> None: pass |
| [file a.py.2] |
| [out] |
| == |
| main:2: error: Module 'a' has no attribute 'f' |
| |
| [case testRefreshTyping] |
| from typing import Sized |
| from c import A |
| import z |
| |
| # Force typing to get refreshed by using a protocol from it |
| x: Sized = A() |
| |
| [file c.py] |
| class D: |
| def __len__(self) -> int: return 0 |
| A = D |
| [file c.py.2] |
| class C: |
| def __len__(self) -> int: return 0 |
| A = C |
| [file z.py] |
| from typing import List |
| T = List[int] |
| [file z.py.2] |
| from typing import List |
| T = List[int] # yo |
| [builtins fixtures/list.pyi] |
| [typing fixtures/typing-medium.pyi] |
| [out] |
| == |
| |
| [case testNamedTupleRefresh] |
| from typing import NamedTuple |
| from a import f |
| N = NamedTuple('N', [('x', int)]) |
| [file a.py] |
| def f() -> None: pass |
| [file a.py.2] |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| main:2: error: Module 'a' has no attribute 'f' |
| |
| [case testModuleLevelAttributeRefresh] |
| from typing import Callable |
| from a import f |
| x = 1 |
| y = '' # type: str |
| [file a.py] |
| def f() -> None: pass |
| [file a.py.2] |
| [out] |
| == |
| main:2: error: Module 'a' has no attribute 'f' |
| |
| [case testClassBodyRefresh] |
| from a import f |
| class A: |
| x = 1 |
| y = '' # type: str |
| |
| def f(self) -> None: |
| self.x = 1 |
| [file a.py] |
| f = 1 |
| [file a.py.2] |
| [out] |
| == |
| main:1: error: Module 'a' has no attribute 'f' |
| |
| [case testDecoratedMethodRefresh] |
| from typing import Iterator, Callable, List |
| from a import f |
| import a |
| |
| def dec(f: Callable[['A'], Iterator[int]]) -> Callable[[int], int]: pass |
| |
| class A: |
| @dec |
| def f(self) -> Iterator[int]: |
| self.x = a.g() # type: int |
| return None |
| [builtins fixtures/list.pyi] |
| [file a.py] |
| f = 1 |
| def g() -> int: pass |
| [file a.py.2] |
| def f() -> None: pass |
| def g() -> int: pass |
| [file a.py.3] |
| def f() -> None: pass |
| def g() -> str: pass |
| [out] |
| == |
| == |
| main:10: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testTwoPassTypeChecking] |
| import a |
| [file a.py] |
| [file a.py.2] |
| class A: |
| def __init__(self, b: B) -> None: |
| self.a = b.a |
| |
| class B: |
| def __init__(self) -> None: |
| self.a = int() |
| [file a.py.3] |
| class A: |
| def __init__(self, b: B) -> None: |
| self.a = b.a |
| reveal_type(self.a) # E |
| |
| class B: |
| def __init__(self) -> None: |
| self.a = int() |
| [out] |
| == |
| == |
| a.py:4: note: Revealed type is 'builtins.int' |
| |
| [case testStripRevealType] |
| import a |
| reveal_type(a.f()) |
| [file a.py] |
| def f() -> int: pass |
| [file a.py.2] |
| def f() -> str: pass |
| [out] |
| main:2: note: Revealed type is 'builtins.int' |
| == |
| main:2: note: Revealed type is 'builtins.str' |
| |
| [case testDecoratorTypeAfterReprocessing] |
| import a |
| reveal_type(a.f()) |
| [file a.py] |
| from contextlib import contextmanager |
| from typing import Iterator |
| import b |
| @contextmanager |
| def f() -> Iterator[None]: |
| yield |
| [file b.py] |
| [delete b.py.2] |
| [file b.py.3] |
| [typing fixtures/typing-medium.pyi] |
| [builtins fixtures/list.pyi] |
| [triggered] |
| 2: <b>, __main__ |
| 3: <b>, __main__, a |
| [out] |
| main:2: note: Revealed type is 'contextlib.GeneratorContextManager[None]' |
| == |
| a.py:3: error: Cannot find implementation or library stub for module named "b" |
| a.py:3: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports |
| main:2: note: Revealed type is 'contextlib.GeneratorContextManager[None]' |
| == |
| main:2: note: Revealed type is 'contextlib.GeneratorContextManager[None]' |
| |
| [case testDecoratorSpecialCase1] |
| import a |
| [file a.py] |
| import contextlib |
| from typing import List, Iterator |
| |
| @contextlib.contextmanager |
| def f(x: List[int]) -> Iterator[None]: |
| x.append(1) |
| yield |
| |
| def g() -> None: |
| import b |
| b.h(1) |
| [file b.py] |
| def h() -> None: pass |
| [delete b.py.2] |
| [file b.py.3] |
| def h() -> None: pass |
| [file a.py.4] |
| import contextlib |
| from typing import List, Iterator |
| |
| @contextlib.contextmanager |
| def f(x: List[int]) -> Iterator[None]: |
| x.append(1) |
| yield |
| |
| def g() -> None: |
| import b |
| b.h(1) |
| pass |
| [typing fixtures/typing-medium.pyi] |
| [builtins fixtures/list.pyi] |
| [triggered] |
| 2: <b.h>, <b>, <b[wildcard]>, a.g |
| 3: <b.h>, <b>, <b[wildcard]>, a |
| 4: a.g |
| [out] |
| a.py:11: error: Too many arguments for "h" |
| == |
| a.py:10: error: Cannot find implementation or library stub for module named "b" |
| a.py:10: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports |
| == |
| a.py:11: error: Too many arguments for "h" |
| == |
| a.py:11: error: Too many arguments for "h" |
| |
| [case testDecoratorSpecialCase2] |
| import a |
| [file a.py] |
| from contextlib import contextmanager |
| from typing import Iterator, List |
| import b |
| |
| @contextmanager |
| def f(x: List[int]) -> Iterator[None]: |
| x.append(1) |
| yield |
| [file b.py] |
| [delete b.py.2] |
| [file b.py.3] |
| [file a.py.4] |
| from contextlib import contextmanager |
| from typing import Iterator, List |
| import b |
| |
| @contextmanager |
| def f(x: List[int]) -> Iterator[None]: |
| x.append(1) |
| yield |
| [typing fixtures/typing-medium.pyi] |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| a.py:3: error: Cannot find implementation or library stub for module named "b" |
| a.py:3: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports |
| == |
| == |
| |
| [case testDecoratorMethodCompat] |
| from typing import Callable, List, TypeVar |
| import x |
| |
| class Base: pass |
| _Base = TypeVar('_Base', bound=Base) |
| |
| def dec(f: Callable[[_Base], int]) -> Callable[[_Base], List[int]]: pass |
| |
| class B(Base): |
| def foo(self) -> List[int]: pass |
| |
| class A(B): |
| @dec |
| def foo(self) -> int: |
| x.lol() |
| return 12 |
| |
| [file x.py] |
| def lol() -> str: pass |
| [file x.py.2] |
| def lol() -> int: pass |
| [file x.py.3] |
| def lol() -> str: pass |
| |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| == |
| |
| [case testPreviousErrorInDecoratedFunction] |
| import a |
| [file a.py] |
| from typing import Callable |
| import b |
| |
| def dec(x: Callable[[], None]) -> Callable[[], None]: |
| return x |
| |
| @dec |
| def f() -> None: |
| 1 + '' |
| [file b.py] |
| [file b.py.2] |
| 1 |
| [file b.py.3] |
| 2 |
| [file a.py.4] |
| from typing import Callable |
| import b |
| |
| def dec(f: Callable[[], None]) -> Callable[[], None]: |
| return f |
| |
| @dec |
| def f() -> None: |
| 1 + 2 |
| [out] |
| a.py:9: error: Unsupported operand types for + ("int" and "str") |
| == |
| a.py:9: error: Unsupported operand types for + ("int" and "str") |
| == |
| a.py:9: error: Unsupported operand types for + ("int" and "str") |
| == |
| |
| [case testPreviousErrorInDecoratedMethodOverride] |
| import a |
| [file a.py] |
| from typing import Callable |
| from b import B |
| |
| def dec(x: Callable[['A'], int]) -> Callable[['A'], int]: |
| return x |
| |
| class A(B): |
| @dec |
| def foo(self) -> int: return 12 |
| |
| [file b.py] |
| class B: |
| def foo(self) -> str: return 'hi' |
| [file c.py.2] |
| [file c.py.3] |
| 1 |
| [file b.py.4] |
| class B: |
| def foo(self) -> int: return 12 |
| [out] |
| a.py:9: error: Return type "int" of "foo" incompatible with return type "str" in supertype "B" |
| == |
| a.py:9: error: Return type "int" of "foo" incompatible with return type "str" in supertype "B" |
| == |
| a.py:9: error: Return type "int" of "foo" incompatible with return type "str" in supertype "B" |
| == |
| |
| [case testPreviousErrorInMethodSemanal1] |
| import a |
| [file a.py] |
| class A: |
| def foo() -> int: pass |
| [file c.py.2] |
| [file c.py.3] |
| 1 |
| [file a.py.4] |
| class A: |
| def foo(self) -> int: pass |
| [out] |
| a.py:2: error: Method must have at least one argument |
| == |
| a.py:2: error: Method must have at least one argument |
| == |
| a.py:2: error: Method must have at least one argument |
| == |
| |
| [case testPreviousErrorInMethodSemanal2] |
| import a |
| [file a.py] |
| class A: |
| def foo(self) -> None: |
| nothing |
| [file c.py.2] |
| [file c.py.3] |
| 1 |
| [file a.py.4] |
| class A: |
| def foo(self) -> int: pass |
| [out] |
| a.py:3: error: Name 'nothing' is not defined |
| == |
| a.py:3: error: Name 'nothing' is not defined |
| == |
| a.py:3: error: Name 'nothing' is not defined |
| == |
| |
| [case testPreviousErrorInMethodSemanalPass3] |
| import a |
| [file a.py] |
| from typing import List |
| class A: |
| def __init__(self) -> None: |
| self.x = [] # type: List[int, str] |
| [file c.py.2] |
| [file c.py.3] |
| 1 |
| [file a.py.4] |
| from typing import List |
| class A: |
| def __init__(self) -> None: |
| self.x = [] # type: List[int] |
| [builtins fixtures/list.pyi] |
| [out] |
| a.py:4: error: "list" expects 1 type argument, but 2 given |
| == |
| a.py:4: error: "list" expects 1 type argument, but 2 given |
| == |
| a.py:4: error: "list" expects 1 type argument, but 2 given |
| == |
| |
| [case testPreviousErrorInOverloadedFunctionSemanalPass3] |
| import a |
| [file a.py] |
| from typing import overload, List |
| @overload |
| def f(x: str) -> None: ... |
| @overload |
| def f(x: int) -> List[int, str]: ... |
| def f(x: object) -> object: |
| pass |
| [file c.py.2] |
| [file c.py.3] |
| 1 |
| [file a.py.4] |
| from typing import overload, List |
| @overload |
| def f(x: str) -> None: ... |
| @overload |
| def f(x: int) -> List[int]: ... |
| def f(x: object) -> object: |
| pass |
| [builtins fixtures/list.pyi] |
| [out] |
| a.py:5: error: "list" expects 1 type argument, but 2 given |
| == |
| a.py:5: error: "list" expects 1 type argument, but 2 given |
| == |
| a.py:5: error: "list" expects 1 type argument, but 2 given |
| == |
| |
| [case testPreviousErrorInOverloadedFunction] |
| import a |
| [file a.py] |
| from typing import overload |
| @overload |
| def f(x: str) -> None: ... |
| @overload |
| def f(x: int) -> int: ... |
| def f(x: object) -> None: |
| pass |
| [file b.py] |
| [file b.py.2] |
| 1 |
| [file b.py.3] |
| 2 |
| [file a.py.4] |
| from typing import overload |
| @overload |
| def f(x: str) -> None: ... |
| @overload |
| def f(x: int) -> None: ... |
| def f(x: object) -> None: |
| pass |
| [out] |
| a.py:6: error: Overloaded function implementation cannot produce return type of signature 2 |
| == |
| a.py:6: error: Overloaded function implementation cannot produce return type of signature 2 |
| == |
| a.py:6: error: Overloaded function implementation cannot produce return type of signature 2 |
| == |
| |
| [case testPreviousErrorInOverloadedFunctionSemanal] |
| import a |
| [file a.py] |
| from typing import overload |
| @overload |
| def f(x: str) -> None: ... |
| @overload |
| def f(x: int) -> None: ... |
| [file b.py] |
| [file b.py.2] |
| 1 |
| [file b.py.3] |
| 2 |
| [file a.py.4] |
| from typing import overload |
| @overload |
| def f(x: str) -> None: ... |
| @overload |
| def f(x: int) -> None: ... |
| def f(x: object) -> None: |
| pass |
| [out] |
| a.py:2: error: An overloaded function outside a stub file must have an implementation |
| == |
| a.py:2: error: An overloaded function outside a stub file must have an implementation |
| == |
| a.py:2: error: An overloaded function outside a stub file must have an implementation |
| == |
| |
| [case testPreviousErrorInDecoratedMethodSemanalPass3] |
| import a |
| [file a.py] |
| from typing import Callable, TypeVar, Any, List |
| |
| T = TypeVar('T', bound=Callable) |
| def dec(x: T) -> T: |
| return x |
| |
| @dec |
| def foo(self) -> List[str, int]: return [] |
| |
| [file c.py.2] |
| [file c.py.3] |
| [file a.py.4] |
| from typing import Callable, TypeVar, Any, List |
| |
| T = TypeVar('T', bound=Callable[..., Any]) |
| def dec(x: T) -> T: |
| return x |
| |
| @dec |
| def foo(self) -> List[str]: return [] |
| [builtins fixtures/list.pyi] |
| [out] |
| a.py:8: error: "list" expects 1 type argument, but 2 given |
| == |
| a.py:8: error: "list" expects 1 type argument, but 2 given |
| == |
| a.py:8: error: "list" expects 1 type argument, but 2 given |
| == |
| |
| [case testDecoratorUpdateMod] |
| import a |
| [file a.py] |
| import mod |
| |
| @mod.deca |
| @mod.decb(mod.C()) |
| def func(x: mod.B) -> mod.B: |
| x.x |
| return x |
| [file mod.py] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[[B], B]) -> Callable[[str], str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| pass |
| class B: |
| x: int |
| [file mod.py.2] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[[str], str]) -> Callable[[str], str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| pass |
| class B: |
| x: int |
| [file mod.py.3] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[[B], B]) -> Callable[[str], str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| pass |
| class B: |
| y: int |
| [file mod.py.4] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[[B], B]) -> Callable[[str], str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| def __init__(self, x: int) -> None: |
| pass |
| class B: |
| x: int |
| [out] |
| == |
| a.py:3: error: Argument 1 to "deca" has incompatible type "Callable[[B], B]"; expected "Callable[[str], str]" |
| == |
| a.py:6: error: "B" has no attribute "x" |
| == |
| a.py:4: error: Missing positional argument "x" in call to "C" |
| |
| [case testDecoratorUpdateFunc] |
| import a |
| [file a.py] |
| import mod |
| |
| def outer() -> None: |
| @mod.deca |
| @mod.decb(mod.C()) |
| def func(x: mod.B) -> mod.B: |
| x.x |
| return x |
| [file mod.py] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[[B], B]) -> Callable[[str], str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| pass |
| class B: |
| x: int |
| [file mod.py.2] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[[str], str]) -> Callable[[str], str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| pass |
| class B: |
| x: int |
| [file mod.py.3] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[[B], B]) -> Callable[[str], str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| pass |
| class B: |
| y: int |
| [file mod.py.4] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[[B], B]) -> Callable[[str], str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| def __init__(self, x: int) -> None: |
| pass |
| class B: |
| x: int |
| [out] |
| == |
| a.py:4: error: Argument 1 to "deca" has incompatible type "Callable[[B], B]"; expected "Callable[[str], str]" |
| == |
| a.py:7: error: "B" has no attribute "x" |
| == |
| a.py:5: error: Missing positional argument "x" in call to "C" |
| |
| [case DecoratorUpdateMethod] |
| import a |
| [file a.py] |
| import mod |
| |
| class D: |
| @mod.deca |
| @mod.decb(mod.C()) |
| def func(self, x: mod.B) -> mod.B: |
| x.x |
| return x |
| [file mod.py] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[..., B]) -> Callable[..., str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| pass |
| class B: |
| x: int |
| [file mod.py.2] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[..., str]) -> Callable[..., str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| pass |
| class B: |
| x: int |
| [file mod.py.3] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[..., B]) -> Callable[..., str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| pass |
| class B: |
| y: int |
| [file mod.py.4] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| |
| def deca(func: Callable[..., B]) -> Callable[..., str]: |
| pass |
| def decb(arg: C) -> Callable[[F], F]: |
| pass |
| class C: |
| def __init__(self, x: int) -> None: |
| pass |
| class B: |
| x: int |
| [out] |
| == |
| a.py:4: error: Argument 1 to "deca" has incompatible type "Callable[[D, B], B]"; expected "Callable[..., str]" |
| == |
| a.py:7: error: "B" has no attribute "x" |
| == |
| a.py:5: error: Missing positional argument "x" in call to "C" |
| |
| [case testDecoratorUpdateDeeepNested] |
| import a |
| [file a.py] |
| import mod |
| |
| def outer() -> None: |
| def inner() -> None: |
| @mod.dec |
| def func(x: int) -> int: |
| pass |
| [file mod.py] |
| from typing import Callable |
| def dec(func: Callable[[int], int]) -> Callable[[str], str]: |
| pass |
| [file mod.py.2] |
| from typing import Callable |
| def dec(func: Callable[[str], str]) -> Callable[[str], str]: |
| pass |
| [out] |
| == |
| a.py:5: error: Argument 1 to "dec" has incompatible type "Callable[[int], int]"; expected "Callable[[str], str]" |
| |
| [case testDecoratorUpdateNestedClass] |
| import a |
| [file a.py] |
| import mod |
| |
| class Outer: |
| class Inner: |
| c = mod.C() |
| @c.dec |
| def func(self, x: int) -> int: |
| pass |
| [file mod.py] |
| from typing import Callable |
| class C: |
| def dec(self, func: Callable[..., int]) -> Callable[..., str]: |
| pass |
| [file mod.py.2] |
| from typing import Callable |
| class C: |
| def dec(self, func: Callable[..., str]) -> Callable[..., str]: |
| pass |
| [out] |
| == |
| a.py:6: error: Argument 1 to "dec" of "C" has incompatible type "Callable[[Inner, int], int]"; expected "Callable[..., str]" |
| |
| [case testDecoratorUpdateClassInFunction] |
| import a |
| [file a.py] |
| import mod |
| |
| def outer() -> None: |
| class Inner: |
| c = mod.C() |
| @c.dec |
| def func(self, x: mod.B) -> int: |
| return x.x |
| [file mod.py] |
| from typing import Callable |
| class C: |
| def dec(self, func: Callable[..., int]) -> Callable[..., str]: |
| pass |
| class B: |
| x: int |
| [file mod.py.2] |
| from typing import Callable |
| class C: |
| def dec(self, func: Callable[..., str]) -> Callable[..., str]: |
| pass |
| class B: |
| x: int |
| [file mod.py.3] |
| from typing import Callable |
| class C: |
| def dec(self, func: Callable[..., int]) -> Callable[..., str]: |
| pass |
| class B: |
| x: str |
| [out] |
| == |
| a.py:6: error: Argument 1 to "dec" of "C" has incompatible type "Callable[[Inner, B], int]"; expected "Callable[..., str]" |
| == |
| a.py:8: error: Incompatible return value type (got "str", expected "int") |
| |
| [case testDecoratorUpdateMROUpdated] |
| import a |
| [file a.py] |
| import mod |
| |
| @mod.dec |
| def func(x: mod.B) -> int: |
| pass |
| [file mod.py] |
| from typing import Callable |
| class B: |
| pass |
| class C(B): |
| pass |
| def dec(f: Callable[[C], int]) -> Callable[[int], int]: |
| pass |
| [file mod.py.2] |
| from typing import Callable |
| class B: |
| pass |
| class C: |
| pass |
| def dec(f: Callable[[C], int]) -> Callable[[int], int]: |
| pass |
| [out] |
| == |
| a.py:3: error: Argument 1 to "dec" has incompatible type "Callable[[B], int]"; expected "Callable[[C], int]" |
| |
| [case testOverloadRefresh] |
| from typing import overload |
| import m |
| |
| @overload |
| def f(x: m.A) -> None: ... |
| @overload |
| def f(x: int) -> None: ... |
| def f(x: object) -> None: |
| from n import g |
| [file m.py] |
| class A: pass |
| [file n.py] |
| def g() -> None: pass |
| [delete m.py.2] |
| [delete n.py.2] |
| [out] |
| == |
| main:2: error: Cannot find implementation or library stub for module named "m" |
| main:2: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports |
| main:7: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader |
| main:9: error: Cannot find implementation or library stub for module named "n" |
| |
| [case testOverloadSpecialCase] |
| from typing import overload |
| import m |
| import sys |
| |
| class C: |
| if sys.platform == 'nonexistent': |
| def f(self, x): pass |
| else: |
| @overload |
| def f(self, x: m.A) -> None: pass |
| @overload |
| def f(self, x: int) -> None: pass |
| def f(self, x: object) -> None: |
| from n import g |
| [file m.py] |
| class A: pass |
| [file n.py] |
| def g() -> None: pass |
| [delete m.py.2] |
| [delete n.py.2] |
| [builtins fixtures/ops.pyi] |
| [out] |
| == |
| main:2: error: Cannot find implementation or library stub for module named "m" |
| main:2: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports |
| main:12: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader |
| main:14: error: Cannot find implementation or library stub for module named "n" |
| |
| [case testOverloadClassmethodDisappears] |
| from typing import overload |
| from m import Wrapper |
| reveal_type(Wrapper.foo(3)) |
| [file m.pyi] |
| from typing import overload |
| class Wrapper: |
| @overload |
| @classmethod |
| def foo(self, x: int) -> int: ... |
| @overload |
| @classmethod |
| def foo(self, x: str) -> str: ... |
| [file m.pyi.2] |
| from typing import overload |
| class Wrapper: |
| @overload |
| def foo(cls, x: int) -> int: ... |
| @overload |
| def foo(cls, x: str) -> str: ... |
| [builtins fixtures/classmethod.pyi] |
| [out] |
| main:3: note: Revealed type is 'builtins.int' |
| == |
| main:3: error: No overload variant of "foo" of "Wrapper" matches argument type "int" |
| main:3: note: Possible overload variants: |
| main:3: note: def foo(cls: Wrapper, x: int) -> int |
| main:3: note: def foo(cls: Wrapper, x: str) -> str |
| main:3: note: Revealed type is 'Any' |
| |
| [case testRefreshGenericClass] |
| from typing import TypeVar, Generic |
| from a import A |
| |
| X = TypeVar('X') |
| |
| class C(Generic[X]): |
| def f(self, x: A) -> X: ... |
| [file a.py] |
| class A: pass |
| [file a.py.2] |
| [file a.py.3] |
| class A: pass |
| [out] |
| == |
| main:2: error: Module 'a' has no attribute 'A' |
| == |
| |
| [case testRefreshGenericAndFailInPass3] |
| # Failure in semantic analysis pass 3 |
| from a import C |
| a: C[int] |
| [file a.py] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class C(Generic[T]): pass |
| [file a.py.2] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class C(Generic[T, S]): pass |
| [file a.py.3] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class C(Generic[T]): pass |
| [out] |
| == |
| main:3: error: "C" expects 2 type arguments, but 1 given |
| == |
| |
| [case testPrintStatement_python2] |
| # flags: --py2 |
| import a |
| [file a.py] |
| def f(x): # type: (int) -> int |
| return 1 |
| print f(1) |
| [file a.py.2] |
| def f(x): # type: (int) -> int |
| return 1 |
| print f('') |
| [out] |
| == |
| a.py:3: error: Argument 1 to "f" has incompatible type "str"; expected "int" |
| |
| [case testUnannotatedClass] |
| import a |
| [file a.py] |
| class A: |
| def f(self, x): |
| self.y = x |
| self.g() |
| |
| def g(self): pass |
| [file a.py.2] |
| class A: |
| def f(self, x, y): |
| self.y = x |
| self.z = y |
| self.g() |
| |
| def g(self): pass |
| [triggered] |
| 2: <a.A.f>, <a.A.z>, <a.A[wildcard]> |
| [out] |
| == |
| |
| [case testSuperBasics] |
| import a |
| [file a.py] |
| class A: |
| def f(self) -> None: pass |
| class B(A): |
| def f(self) -> None: |
| super(B, self).f() |
| [file a.py.2] |
| class A: |
| def f(self) -> None: pass |
| class B(A): |
| def f(self) -> None: |
| super(B, self).f() |
| [out] |
| == |
| |
| [case testErrorInTypeCheckSecondPassThroughPropagation] |
| import a |
| |
| def f() -> None: |
| x = a.C() |
| [file a.py] |
| [file a.py.2] |
| from typing import Generic, TypeVar |
| T = TypeVar('T') |
| class C(Generic[T]): pass |
| [out] |
| main:4: error: "object" has no attribute "C" |
| == |
| main:4: error: Need type annotation for "x" |
| |
| [case testPartialTypeInNestedClass] |
| import a |
| class C: |
| def f(self) -> None: |
| a.g() |
| class D: |
| def __init__(self) -> None: |
| self.x = {} |
| def meth(self) -> None: |
| self.x['a'] = 'b' |
| [file a.py] |
| def g() -> None: pass |
| [file a.py.2] |
| def g() -> int: pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| main:7: error: Need type annotation for "x" (hint: "x: Dict[<type>, <type>] = ...") |
| == |
| main:7: error: Need type annotation for "x" (hint: "x: Dict[<type>, <type>] = ...") |
| |
| [case testRefreshPartialTypeInClass] |
| import a |
| class D: |
| def __init__(self) -> None: |
| a.g() |
| self.x = {} |
| def meth(self) -> None: |
| self.x['a'] = 'b' |
| [file a.py] |
| def g() -> None: pass |
| [file a.py.2] |
| def g() -> int: pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| main:5: error: Need type annotation for "x" (hint: "x: Dict[<type>, <type>] = ...") |
| == |
| main:5: error: Need type annotation for "x" (hint: "x: Dict[<type>, <type>] = ...") |
| |
| [case testRefreshPartialTypeInferredAttributeIndex] |
| from c import C |
| reveal_type(C().a) |
| [file c.py] |
| from b import f |
| class C: |
| def __init__(self) -> None: |
| self.a = {} |
| if bool(): |
| self.a[0] = f() |
| [file b.py] |
| def f() -> int: ... |
| [file b.py.2] |
| from typing import List |
| def f() -> str: ... |
| [builtins fixtures/dict.pyi] |
| [out] |
| main:2: note: Revealed type is 'builtins.dict[builtins.int, builtins.int]' |
| == |
| main:2: note: Revealed type is 'builtins.dict[builtins.int, builtins.str]' |
| |
| [case testRefreshPartialTypeInferredAttributeAssign] |
| from c import C |
| reveal_type(C().a) |
| [file c.py] |
| from b import f |
| class C: |
| def __init__(self) -> None: |
| self.a = [] |
| if bool(): |
| self.a = f() |
| [file b.py] |
| from typing import List |
| def f() -> List[int]: ... |
| [file b.py.2] |
| from typing import List |
| def f() -> List[str]: ... |
| [builtins fixtures/list.pyi] |
| [out] |
| main:2: note: Revealed type is 'builtins.list[builtins.int]' |
| == |
| main:2: note: Revealed type is 'builtins.list[builtins.str]' |
| |
| [case testRefreshPartialTypeInferredAttributeAppend] |
| from c import C |
| reveal_type(C().a) |
| [file c.py] |
| from b import f |
| class C: |
| def __init__(self) -> None: |
| self.a = [] |
| if bool(): |
| self.a.append(f()) |
| [file b.py] |
| def f() -> int: ... |
| [file b.py.2] |
| def f() -> str: ... |
| [builtins fixtures/list.pyi] |
| [out] |
| main:2: note: Revealed type is 'builtins.list[builtins.int]' |
| == |
| main:2: note: Revealed type is 'builtins.list[builtins.str]' |
| |
| [case testRefreshTryExcept] |
| import a |
| def f() -> None: |
| a.g() |
| try: |
| pass |
| except BaseException as e: |
| e |
| [file a.py] |
| def g() -> int: pass |
| [file a.py.2] |
| def g() -> str: pass |
| [builtins fixtures/exception.pyi] |
| [out] |
| == |
| |
| [case testMroSpecialCase] |
| import b |
| import a |
| |
| [file a.py] |
| class C: pass |
| class D(C): |
| 1() |
| class E(D): pass |
| |
| [file b.py] |
| import a |
| |
| [file a.py.2] |
| class C: pass |
| class D(C): |
| 1() |
| class E(D): pass |
| # Something needs to change |
| |
| [file b.py.2] |
| import a |
| # Something needs to change |
| |
| [triggered] |
| 2: a, a |
| [out] |
| a.py:3: error: "int" not callable |
| == |
| a.py:3: error: "int" not callable |
| |
| [case testMetaclassDefinition_python2] |
| # flags: --py2 |
| import abc |
| import m |
| m.f() |
| |
| class A: |
| __metaclass__ = abc.ABCMeta |
| [file m.py] |
| def f(): pass |
| [file m.py.2] |
| def f(x=1): pass |
| [out] |
| == |
| |
| [case testMetaclassAttributes] |
| import a |
| [file a.py] |
| from mod import C |
| from typing import Type |
| def f(arg: Type[C]) -> None: |
| arg.x = int() |
| [file mod.py] |
| import submod |
| class C(metaclass=submod.M): |
| pass |
| [file submod.py] |
| class M(type): |
| x: int |
| [file submod.py.2] |
| class M(type): |
| x: str |
| [file submod.py.3] |
| class M(type): |
| y: str |
| [file submod.py.4] |
| class M(type): |
| x: int |
| [out] |
| == |
| a.py:4: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| == |
| a.py:4: error: "Type[C]" has no attribute "x" |
| == |
| |
| [case testMetaclassAttributesDirect] |
| import a |
| [file a.py] |
| from mod import C |
| def f() -> None: |
| C.x = int() |
| [file mod.py] |
| import submod |
| class C(metaclass=submod.M): |
| pass |
| [file submod.py] |
| class M(type): |
| x: int |
| [file submod.py.2] |
| class M(type): |
| x: str |
| [file submod.py.3] |
| class M(type): |
| y: str |
| [file submod.py.4] |
| class M(type): |
| x: int |
| [out] |
| == |
| a.py:3: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| == |
| a.py:3: error: "Type[C]" has no attribute "x" |
| == |
| |
| [case testMetaclassOperators] |
| import a |
| [file a.py] |
| from mod import C |
| from typing import Type |
| def f(arg: Type[C]) -> None: |
| arg + arg |
| [file mod.py] |
| import submod |
| class C(metaclass=submod.M): |
| pass |
| [file submod.py] |
| class M(type): |
| def __add__(self, other: M) -> M: |
| pass |
| [file submod.py.2] |
| class M(type): |
| def __add__(self, other: int) -> M: |
| pass |
| [out] |
| == |
| a.py:4: error: Unsupported operand types for + ("Type[C]" and "Type[C]") |
| |
| [case testMetaclassOperatorsDirect] |
| import a |
| [file a.py] |
| from mod import C |
| def f() -> None: |
| C + C |
| [file mod.py] |
| import submod |
| class C(metaclass=submod.M): |
| pass |
| [file submod.py] |
| class M(type): |
| def __add__(self, other: int) -> M: |
| pass |
| [file submod.py.2] |
| class M(type): |
| def __add__(self, other: M) -> M: |
| pass |
| [out] |
| a.py:3: error: Unsupported operand types for + ("Type[C]" and "Type[C]") |
| == |
| |
| [case testMetaclassAttributesDirect_python2] |
| # flags: --py2 |
| import a |
| [file a.py] |
| from mod import C |
| def f(): |
| # type: () -> None |
| C.x = int() |
| [file mod.py] |
| import submod |
| class C: |
| __metaclass__ = submod.M |
| [file submod.py] |
| class M(type): |
| x = None # type: int |
| [file submod.py.2] |
| class M(type): |
| x = None # type: str |
| [file submod.py.3] |
| class M(type): |
| y = None # type: str |
| [file submod.py.4] |
| class M(type): |
| x = None # type: int |
| [out] |
| == |
| a.py:4: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| == |
| a.py:4: error: "Type[C]" has no attribute "x" |
| == |
| |
| [case testMetaclassOperators_python2] |
| # flags: --py2 |
| import a |
| [file a.py] |
| from mod import C |
| from typing import Type |
| def f(arg): |
| # type: (Type[C]) -> None |
| arg + arg |
| [file mod.py] |
| import submod |
| class C: |
| __metaclass__ = submod.M |
| [file submod.py] |
| class M(type): |
| def __add__(self, other): |
| # type: (M) -> M |
| pass |
| [file submod.py.2] |
| class M(type): |
| def __add__(self, other): |
| # type: (int) -> M |
| pass |
| [out] |
| == |
| a.py:5: error: Unsupported operand types for + ("Type[C]" and "Type[C]") |
| |
| [case testFineMetaclassUpdate] |
| import a |
| [file a.py] |
| from c import M |
| import b |
| def f(arg: M) -> None: |
| pass |
| |
| f(b.B) |
| [file b.py] |
| import c |
| class B: pass |
| |
| [file b.py.2] |
| import c |
| class B(metaclass=c.M): pass |
| |
| [file c.py] |
| class M(type): |
| pass |
| [out] |
| a.py:6: error: Argument 1 to "f" has incompatible type "Type[B]"; expected "M" |
| == |
| |
| [case testFineMetaclassRecalculation] |
| import a |
| [file a.py] |
| from b import B |
| class M2(type): pass |
| class D(B, metaclass=M2): pass |
| [file b.py] |
| import c |
| class B: pass |
| |
| [file b.py.2] |
| import c |
| class B(metaclass=c.M): pass |
| |
| [file c.py] |
| class M(type): |
| pass |
| [out] |
| == |
| a.py:3: error: Inconsistent metaclass structure for 'D' |
| |
| [case testFineMetaclassDeclaredUpdate] |
| import a |
| [file a.py] |
| import b |
| class B(metaclass=b.M): pass |
| class D(B, metaclass=b.M2): pass |
| [file b.py] |
| class M(type): pass |
| class M2(M): pass |
| [file b.py.2] |
| class M(type): pass |
| class M2(type): pass |
| [out] |
| == |
| a.py:3: error: Inconsistent metaclass structure for 'D' |
| |
| [case testFineMetaclassRemoveFromClass] |
| import a |
| [file a.py] |
| import b |
| def func() -> int: |
| return b.B.x |
| [file b.py] |
| from c import M |
| class B(metaclass=M): |
| pass |
| [file b.py.2] |
| from c import M |
| class B: |
| pass |
| [file c.py] |
| class M(type): |
| x: int |
| [out] |
| == |
| a.py:3: error: "Type[B]" has no attribute "x" |
| |
| [case testFineMetaclassRemoveFromClass2] |
| import a |
| [file a.py] |
| import b |
| def func() -> None: |
| b.test(b.B) |
| [file b.py] |
| import c |
| def test(cls: c.M) -> None: |
| pass |
| class B(metaclass=c.M): |
| pass |
| [file b.py.2] |
| import c |
| def test(cls: c.M) -> None: |
| pass |
| class B: |
| pass |
| [file c.py] |
| class M(type): |
| x: int |
| [out] |
| == |
| a.py:3: error: Argument 1 to "test" has incompatible type "Type[B]"; expected "M" |
| |
| [case testBadMetaclassCorrected] |
| import a |
| [file a.py] |
| import b |
| class C(metaclass=b.M): |
| pass |
| [file b.py] |
| from c import M |
| [file c.py] |
| M = 1 |
| [file c.py.2] |
| class M(type): |
| pass |
| [out] |
| a.py:2: error: Invalid metaclass 'b.M' |
| == |
| |
| [case testFixedAttrOnAddedMetaclass] |
| import a |
| [file a.py] |
| import b |
| def fun() -> None: |
| x: int = b.C.x |
| [file b.py] |
| import c |
| class C: |
| pass |
| [file b.py.2] |
| import c |
| class C(metaclass=c.M): |
| pass |
| [file c.py] |
| class M(type): |
| x: int |
| [out] |
| a.py:3: error: "Type[C]" has no attribute "x" |
| == |
| |
| [case testIndirectSubclassReferenceMetaclass] |
| import a |
| [file a.py] |
| import b |
| def f() -> None: |
| b.x = int() |
| [file b.py] |
| import bb |
| x = bb.D.x |
| [file bb.py] |
| import mod |
| class D(mod.C): |
| pass |
| [file mod.py] |
| import submod |
| class C(metaclass=submod.M): |
| pass |
| [file submod.py] |
| class M(type): |
| x: int |
| [file submod.py.2] |
| class M(type): |
| x: str |
| [file submod.py.3] |
| class M(type): |
| y: str |
| [file submod.py.4] |
| class M(type): |
| x: int |
| [out] |
| == |
| a.py:3: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| == |
| b.py:2: error: "Type[D]" has no attribute "x" |
| == |
| |
| [case testMetaclassDeletion] |
| import a |
| [file a.py] |
| import b |
| def func() -> None: |
| b.B.x |
| [file b.py] |
| import c |
| class B(metaclass=c.M): |
| pass |
| [file c.py] |
| class M(type): |
| x: int |
| [file c.py.2] |
| whatever: int |
| [out] |
| == |
| b.py:2: error: Name 'c.M' is not defined |
| a.py:3: error: "Type[B]" has no attribute "x" |
| |
| [case testFixMissingMetaclass] |
| import a |
| [file a.py] |
| import b |
| def func() -> None: |
| b.B.x |
| [file b.py] |
| import c |
| class B(metaclass=c.M): |
| pass |
| [file c.py] |
| whatever: int |
| [file c.py.2] |
| class M(type): |
| x: int |
| [out] |
| b.py:2: error: Name 'c.M' is not defined |
| a.py:3: error: "Type[B]" has no attribute "x" |
| == |
| |
| [case testGoodMetaclassSpoiled] |
| import a |
| [file a.py] |
| import b |
| class C(metaclass=b.M): |
| pass |
| [file b.py] |
| class M(type): |
| pass |
| [file b.py.2] |
| M = 1 |
| [out] |
| == |
| a.py:2: error: Invalid metaclass 'b.M' |
| |
| [case testRefreshGenericSubclass] |
| from typing import Generic, TypeVar |
| import m |
| m.x |
| |
| T = TypeVar('T') |
| |
| class C(Generic[T]): |
| def __init__(self, x: T) -> None: |
| pass |
| |
| class D(C[T]): |
| def __init__(self, x: T) -> None: |
| m.x |
| super(D, self).__init__(x) |
| [file m.py] |
| x = 0 |
| [file m.py.2] |
| x = '' |
| [out] |
| == |
| |
| [case testRefreshNamedTupleSubclass] |
| from typing import NamedTuple |
| import m |
| m.x |
| |
| N = NamedTuple('N', [('x', int)]) |
| |
| class C(N): |
| pass |
| [file m.py] |
| x = 0 |
| [file m.py.2] |
| x = '' |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| |
| [case testNewTypeRefresh] |
| import a |
| |
| [file a.py] |
| from typing import Dict, NewType |
| |
| class A: pass |
| N = NewType('N', A) |
| |
| a: Dict[N, int] |
| |
| def f(self, x: N) -> None: |
| a.get(x) |
| |
| [file a.py.2] |
| from typing import Dict, NewType # dummy change |
| |
| class A: pass |
| N = NewType('N', A) |
| |
| a: Dict[N, int] |
| |
| def f(self, x: N) -> None: |
| a.get(x) |
| |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| |
| [case testRefreshFunctionalEnum] |
| import a |
| |
| [file a.py] |
| from typing import Dict |
| from enum import Enum |
| |
| N = Enum('N', 'x') |
| a: Dict[N, int] |
| |
| def f(self, x: N) -> None: |
| a.get(x) |
| |
| [file a.py.2] |
| from typing import Dict |
| from enum import Enum |
| |
| N = Enum('N', 'x') |
| a: Dict[N, int] |
| |
| def f(self, x: N) -> None: |
| a.get(x) |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| |
| [case testFineGrainedCallable] |
| import a |
| [file a.py] |
| def f(o: object) -> None: |
| if callable(o): |
| o() |
| [file a.py.2] |
| def f(o: object) -> None: |
| if callable(o): |
| o() |
| [builtins fixtures/callable.pyi] |
| [out] |
| == |
| |
| [case testRefreshFunctionalNamedTuple] |
| import a |
| |
| [file a.py] |
| from typing import NamedTuple |
| from b import L |
| |
| A = NamedTuple('A', []) |
| a: A |
| |
| def g() -> None: |
| x = L(A()) |
| x.f(a) |
| |
| [file b.pyi] |
| from typing import TypeVar, Generic, overload |
| |
| T = TypeVar('T') |
| |
| class L(Generic[T]): |
| def __init__(self, x: T) -> None: pass |
| @overload |
| def f(self) -> None: pass |
| @overload |
| def f(self, a: T) -> None: pass |
| |
| [file a.py.2] |
| from typing import NamedTuple |
| from b import L |
| |
| A = NamedTuple('A', []) |
| a: A |
| |
| def g() -> None: |
| x = L(A()) |
| x.f(a) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| |
| [case testRefreshSubclassNestedInFunction1] |
| from a import C |
| def f() -> None: |
| class D(C): pass |
| [file a.py] |
| class C: pass |
| [file a.py.2] |
| [out] |
| == |
| main:1: error: Module 'a' has no attribute 'C' |
| |
| [case testRefreshSubclassNestedInFunction2] |
| from a import C |
| def f() -> None: |
| class D(C): |
| def g(self) -> None: |
| super().__init__() |
| d = D() |
| [file a.py] |
| class C: |
| def __init__(self) -> None: pass |
| [file a.py.2] |
| class C: |
| def __init__(self, x: int) -> None: pass |
| [out] |
| == |
| main:5: error: Missing positional argument "x" in call to "__init__" of "C" |
| main:6: error: Missing positional argument "x" in call to "D" |
| |
| [case testInferAttributeTypeAndMultipleStaleTargets] |
| import a |
| |
| class A: |
| def g(self) -> None: |
| a.x |
| self.x = 1 |
| |
| def f(self) -> None: |
| a.x |
| b = self.x |
| self.x = 1 |
| |
| [file a.py] |
| x = 0 |
| [file a.py.2] |
| x = '' |
| [out] |
| == |
| |
| [case testNamedTupleUpdate] |
| import b |
| [file a.py] |
| from typing import NamedTuple |
| N = NamedTuple('N', [('x', int)]) |
| x = N(1) |
| [file a.py.2] |
| from typing import NamedTuple |
| N = NamedTuple('N', [('x', str)]) |
| x = N('hi') |
| [file b.py] |
| import a |
| def f(x: a.N) -> None: |
| pass |
| f(a.x) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| |
| [case testNamedTupleUpdate2] |
| import b |
| [file a.py] |
| from typing import NamedTuple |
| N = NamedTuple('N', [('x', int)]) |
| x = N(1) |
| [file a.py.2] |
| from typing import NamedTuple |
| N = NamedTuple('N', [('y', int)]) |
| x = N(2) |
| [file b.py] |
| import a |
| def f(x: a.N) -> None: |
| pass |
| f(a.x) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| |
| [case testNamedTupleUpdate3] |
| import c |
| [file a.py] |
| from typing import NamedTuple |
| N = NamedTuple('N', [('x', int)]) |
| x = N(1) |
| [file a.py.2] |
| from typing import NamedTuple |
| N = NamedTuple('N', [('x', str)]) |
| x = N('hi') |
| [file b.py] |
| import a |
| from typing import NamedTuple |
| M = NamedTuple('M', [('z', 'a.N')]) |
| x = M(a.x) |
| [file c.py] |
| import a |
| import b |
| from typing import Tuple |
| def lol(n: Tuple[Tuple[int]]) -> None: |
| pass |
| def f(x: b.M) -> None: |
| lol(x) |
| f(b.x) |
| lol(b.x) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| c.py:7: error: Argument 1 to "lol" has incompatible type "M"; expected "Tuple[Tuple[int]]" |
| c.py:9: error: Argument 1 to "lol" has incompatible type "M"; expected "Tuple[Tuple[int]]" |
| |
| [case testNamedTupleUpdate4] |
| import b |
| [file a.py] |
| from typing import NamedTuple |
| class N(NamedTuple): |
| x: int |
| x = N(1) |
| [file a.py.2] |
| from typing import NamedTuple |
| class N(NamedTuple): |
| x: str |
| x = N('hi') |
| [file b.py] |
| import a |
| def f(x: a.N) -> None: |
| pass |
| f(a.x) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| |
| [case testTypedDictRefresh] |
| [builtins fixtures/dict.pyi] |
| import a |
| [file a.py] |
| from mypy_extensions import TypedDict |
| Point = TypedDict('Point', {'x': int, 'y': int}) |
| p = Point(dict(x=42, y=1337)) |
| [file a.py.2] |
| from mypy_extensions import TypedDict |
| Point = TypedDict('Point', {'x': int, 'y': int}) |
| p = Point(dict(x=42, y=1337)) # dummy change |
| [out] |
| == |
| |
| [case testTypedDictUpdate] |
| import b |
| [file a.py] |
| from mypy_extensions import TypedDict |
| Point = TypedDict('Point', {'x': int, 'y': int}) |
| p = Point(dict(x=42, y=1337)) |
| [file a.py.2] |
| from mypy_extensions import TypedDict |
| Point = TypedDict('Point', {'x': int, 'y': str}) |
| p = Point(dict(x=42, y='lurr')) |
| [file b.py] |
| from a import Point |
| def foo(x: Point) -> int: |
| return x['x'] + x['y'] |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| b.py:3: error: Unsupported operand types for + ("int" and "str") |
| |
| [case testTypedDictUpdate2] |
| import b |
| [file a.py] |
| from mypy_extensions import TypedDict |
| class Point(TypedDict): |
| x: int |
| y: int |
| p = Point(dict(x=42, y=1337)) |
| [file a.py.2] |
| from mypy_extensions import TypedDict |
| class Point(TypedDict): |
| x: int |
| y: str |
| p = Point(dict(x=42, y='lurr')) |
| [file b.py] |
| from a import Point |
| def foo(x: Point) -> int: |
| return x['x'] + x['y'] |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| b.py:3: error: Unsupported operand types for + ("int" and "str") |
| |
| [case testBasicAliasUpdate] |
| import b |
| [file a.py] |
| N = int |
| x = 1 |
| [file a.py.2] |
| N = str |
| x = 'hi' |
| [file b.py] |
| import a |
| def f(x: a.N) -> None: |
| pass |
| f(a.x) |
| [out] |
| == |
| |
| [case testBasicAliasUpdateGeneric] |
| import b |
| [file a.py] |
| from typing import Dict, TypeVar |
| T = TypeVar('T') |
| D = Dict[int, T] |
| x = {1: 1} |
| [file a.py.2] |
| from typing import Dict, TypeVar |
| T = TypeVar('T') |
| D = Dict[str, T] |
| x = {'hi': 1} |
| [file b.py] |
| import a |
| def f(x: a.D[int]) -> None: |
| pass |
| f(a.x) |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| |
| [case testAliasFineNormalMod] |
| import b |
| [file a.py] |
| A = int |
| [file a.py.2] |
| A = str |
| [file b.py] |
| import a |
| x: a.A = int() |
| [out] |
| == |
| b.py:2: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testAliasFineNormalFunc] |
| import b |
| [file a.py] |
| A = int |
| [file a.py.2] |
| A = str |
| [file b.py] |
| import a |
| def f(x: a.A): |
| if int(): |
| x = int() |
| [out] |
| == |
| b.py:4: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testAliasFineNormalClass] |
| import b |
| [file a.py] |
| A = int |
| [file a.py.2] |
| A = str |
| [file b.py] |
| import a |
| class C: |
| x: a.A |
| c = C() |
| c.x = int() |
| [out] |
| == |
| b.py:5: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testAliasFineNormalClassBases] |
| import b |
| [file a.py] |
| import c |
| A = c.BaseI |
| [file a.py.2] |
| import c |
| A = c.BaseS |
| [file b.py] |
| import a |
| class C(a.A): |
| x = int() |
| [file c.py] |
| class BaseI: |
| x: int |
| class BaseS: |
| x: str |
| [out] |
| == |
| b.py:3: error: Incompatible types in assignment (expression has type "int", base class "BaseS" defined the type as "str") |
| |
| [case testAliasFineGenericMod] |
| import b |
| [file a.py] |
| from typing import Dict |
| A = Dict[str, int] |
| [file a.py.2] |
| from typing import Dict |
| A = Dict[str, str] |
| [file b.py] |
| import a |
| x: a.A = {str(): int()} |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| b.py:2: error: Dict entry 0 has incompatible type "str": "int"; expected "str": "str" |
| |
| [case testAliasFineGenericFunc] |
| import b |
| [file a.py] |
| from typing import Dict |
| A = Dict[str, int] |
| [file a.py.2] |
| from typing import Dict |
| A = Dict[str, str] |
| [file b.py] |
| import a |
| def f(x: a.A): |
| pass |
| f({str(): int()}) |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| b.py:4: error: Dict entry 0 has incompatible type "str": "int"; expected "str": "str" |
| |
| [case testAliasFineForwardMod] |
| import b |
| [file b.py] |
| x: A = int() |
| A = int |
| [file b.py.2] |
| x: A = int() |
| A = str |
| [out] |
| == |
| b.py:1: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testAliasFineForwardFunc] |
| import b |
| [file b.py] |
| def f(x: A): |
| x = int() |
| A = int |
| [file b.py.2] |
| def f(x: A): |
| if int(): |
| x = int() |
| A = str |
| [out] |
| == |
| b.py:3: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testAliasFineChainedFunc] |
| import b |
| [file a.py] |
| A = int |
| [file a.py.2] |
| A = str |
| [file aa.py] |
| import a |
| B = a.A |
| [file b.py] |
| import aa |
| def f(x: aa.B): |
| if int(): |
| x = int() |
| [out] |
| == |
| b.py:4: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testAliasFineChainedClass] |
| import b |
| [file a.py] |
| A = int |
| [file a.py.2] |
| A = str |
| [file aa.py] |
| import a |
| B = a.A |
| [file b.py] |
| import aa |
| class C: |
| x: aa.B |
| c = C() |
| c.x = int() |
| [out] |
| == |
| b.py:5: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testAliasFineNestedMod] |
| import b |
| [file a.py] |
| from typing import Dict |
| A = Dict[str, int] |
| [file a.py.2] |
| from typing import Dict |
| A = Dict[str, str] |
| [file aa.py] |
| from typing import Dict |
| import a |
| B = Dict[str, a.A] |
| [file b.py] |
| import aa |
| |
| x: aa.B = {'first': {str(): int()}} |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| b.py:3: error: Dict entry 0 has incompatible type "str": "int"; expected "str": "str" |
| |
| [case testAliasFineNestedFunc] |
| import b |
| [file a.py] |
| from typing import Dict |
| A = Dict[str, int] |
| [file a.py.2] |
| from typing import Dict |
| A = Dict[str, str] |
| [file aa.py] |
| from typing import Dict |
| import a |
| B = Dict[str, a.A] |
| [file b.py] |
| import aa |
| def f(x: aa.B): |
| if int(): |
| x = {'first': {str(): int()}} |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| b.py:4: error: Dict entry 0 has incompatible type "str": "int"; expected "str": "str" |
| |
| [case testAliasFineNestedFuncDirect] |
| import b |
| [file a.py] |
| from typing import Dict |
| A = Dict[str, int] |
| [file a.py.2] |
| from typing import Dict |
| A = Dict[str, str] |
| [file aa.py] |
| from typing import Dict |
| import a |
| E = Dict |
| [file b.py] |
| import aa |
| def f(x: aa.E[str, aa.a.A]): |
| if int(): |
| x = {'first': {str(): int()}} |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| b.py:4: error: Dict entry 0 has incompatible type "str": "int"; expected "str": "str" |
| |
| [case testAliasFineNonGenericToGeneric] |
| import b |
| [file a.py] |
| from typing import Dict, TypeVar |
| T = TypeVar('T') |
| A = Dict[T, int] |
| [file a.py.2] |
| A = str |
| [file b.py] |
| import a |
| def f(x: a.A[str]): |
| pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| b.py:2: error: "str" expects no type arguments, but 1 given |
| |
| [case testAliasFineGenericToNonGeneric] |
| import b |
| [file a.py] |
| A = str |
| [file a.py.2] |
| from typing import Dict, TypeVar |
| T = TypeVar('T') |
| A = Dict[T, int] |
| [file b.py] |
| import a |
| def f(x: a.A): |
| pass |
| reveal_type(f) |
| [builtins fixtures/dict.pyi] |
| [out] |
| b.py:4: note: Revealed type is 'def (x: builtins.str) -> Any' |
| == |
| b.py:4: note: Revealed type is 'def (x: builtins.dict[Any, builtins.int]) -> Any' |
| |
| [case testAliasFineChangedNumberOfTypeVars] |
| import b |
| [file a.py] |
| from typing import Dict, TypeVar |
| T = TypeVar('T') |
| A = Dict[T, int] |
| [file a.py.2] |
| from typing import Dict, TypeVar |
| T = TypeVar('T') |
| S = TypeVar('S') |
| A = Dict[T, S] |
| [file b.py] |
| import a |
| def f(x: a.A[str]): |
| pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| b.py:2: error: Bad number of arguments for type alias, expected: 2, given: 1 |
| |
| [case testAliasFineAdded] |
| import b |
| [file a.py] |
| [file a.py.2] |
| A = int |
| [file b.py] |
| import a |
| x: a.A |
| [out] |
| b.py:2: error: Name 'a.A' is not defined |
| == |
| |
| [case testAliasFineDeleted] |
| import b |
| [file a.py] |
| A = int |
| [file a.py.2] |
| [file b.py] |
| import a |
| x: a.A |
| [out] |
| == |
| b.py:2: error: Name 'a.A' is not defined |
| |
| [case testAliasFineClassToAlias] |
| import b |
| [file a.py] |
| class A: pass |
| [file a.py.2] |
| A = int |
| [file b.py] |
| import a |
| x: a.A |
| x = 1 |
| [out] |
| b.py:3: error: Incompatible types in assignment (expression has type "int", variable has type "A") |
| == |
| |
| [case testAliasFineAliasToClass] |
| import b |
| [file a.py] |
| A = int |
| [file a.py.2] |
| class A: pass |
| [file b.py] |
| import a |
| x: a.A |
| x = 1 |
| [out] |
| == |
| b.py:3: error: Incompatible types in assignment (expression has type "int", variable has type "A") |
| |
| [case testAliasFineComponentDeleted] |
| import b |
| [file a.py] |
| class B: pass |
| [file a.py.2] |
| x = 1 |
| [file b.py] |
| import a |
| from typing import Dict, TypeVar |
| T = TypeVar('T') |
| A = Dict[T, a.B] |
| def f(x: A[int]): |
| pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| b.py:4: error: Name 'a.B' is not defined |
| |
| [case testAliasFineTargetDeleted] |
| import c |
| [file a.py] |
| A = int |
| [file b.py] |
| import a |
| B = a.A |
| [file b.py.2] |
| x = 1 |
| [file c.py] |
| import b |
| def f(x: b.B): |
| pass |
| [out] |
| == |
| c.py:2: error: Name 'b.B' is not defined |
| |
| [case testAliasFineClassInFunction] |
| import b |
| [file a.py] |
| A = int |
| [file a.py.2] |
| A = str |
| [file b.py] |
| import a |
| def f() -> None: |
| class C: |
| x: a.A = int() |
| [out] |
| == |
| b.py:4: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testAliasFineInitNormalMod] |
| import c |
| [file a.py] |
| class A: |
| def __init__(self, x: int) -> None: |
| pass |
| [file a.py.2] |
| class A: |
| def __init__(self, x: str) -> None: |
| pass |
| [file b.py] |
| import a |
| B = a.A |
| [file c.py] |
| from b import B |
| B(int()) |
| [out] |
| == |
| c.py:2: error: Argument 1 to "A" has incompatible type "int"; expected "str" |
| |
| [case testAliasFineInitNormalFunc] |
| import c |
| [file a.py] |
| class A: |
| def __init__(self, x: int) -> None: |
| pass |
| [file a.py.2] |
| class A: |
| def __init__(self, x: str) -> None: |
| pass |
| [file b.py] |
| import a |
| B = a.A |
| [file c.py] |
| from b import B |
| def f() -> None: |
| B(int()) |
| [out] |
| == |
| c.py:3: error: Argument 1 to "A" has incompatible type "int"; expected "str" |
| |
| [case testAliasFineInitGenericMod] |
| import c |
| [file a.py] |
| from typing import Generic, TypeVar |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class A(Generic[T, S]): |
| def __init__(self, x: T) -> None: |
| pass |
| [file a.py.2] |
| from typing import Generic, TypeVar |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class A(Generic[T, S]): |
| def __init__(self, x: S) -> None: |
| pass |
| [file b.py] |
| import a |
| B = a.A[int, str] |
| [file c.py] |
| from b import B |
| B(int()) |
| [out] |
| == |
| c.py:2: error: Argument 1 to "A" has incompatible type "int"; expected "str" |
| |
| [case testAliasFineInitGenericFunc] |
| import c |
| [file a.py] |
| from typing import Generic, TypeVar |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class A(Generic[T, S]): |
| def __init__(self, x: T) -> None: |
| pass |
| [file a.py.2] |
| from typing import Generic, TypeVar |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class A(Generic[T, S]): |
| def __init__(self, x: S) -> None: |
| pass |
| [file b.py] |
| import a |
| B = a.A[int, str] |
| [file c.py] |
| from b import B |
| def f() -> None: |
| B(str()) |
| [out] |
| c.py:3: error: Argument 1 to "A" has incompatible type "str"; expected "int" |
| == |
| |
| [case testAliasFineInitChainedMod] |
| import d |
| [file a.py] |
| class A: |
| def __init__(self, x: int) -> None: |
| pass |
| [file a.py.2] |
| class A: |
| def __init__(self, x: str) -> None: |
| pass |
| [file b.py] |
| import a |
| B = a.A |
| [file c.py] |
| import b |
| C = b.B |
| [file d.py] |
| from c import C |
| C(int()) |
| [out] |
| == |
| d.py:2: error: Argument 1 to "A" has incompatible type "int"; expected "str" |
| |
| [case testAliasFineInitChainedFunc] |
| import d |
| [file a.py] |
| class A: |
| def __init__(self, x: int) -> None: |
| pass |
| [file a.py.2] |
| class A: |
| def __init__(self, x: str) -> None: |
| pass |
| [file b.py] |
| import a |
| B = a.A |
| [file c.py] |
| import b |
| C = b.B |
| [file d.py] |
| from c import C |
| def f() -> None: |
| C(str()) |
| [out] |
| d.py:3: error: Argument 1 to "A" has incompatible type "str"; expected "int" |
| == |
| |
| [case testNonePartialType1] |
| import a |
| a.y |
| |
| x = None |
| |
| def f() -> None: |
| global x |
| x = 1 |
| [file a.py] |
| y = 0 |
| [file a.py.2] |
| y = '' |
| [out] |
| main:4: error: Need type annotation for "x" |
| == |
| main:4: error: Need type annotation for "x" |
| |
| [case testNonePartialType2] |
| import a |
| a.y |
| |
| x = None |
| |
| def f(): |
| global x |
| x = 1 |
| [file a.py] |
| y = 0 |
| [file a.py.2] |
| y = '' |
| [out] |
| main:4: error: Need type annotation for "x" |
| == |
| main:4: error: Need type annotation for "x" |
| |
| [case testNonePartialType3] |
| import a |
| [file a.py] |
| [file a.py.2] |
| y = None |
| def f() -> None: |
| global y |
| y = '' |
| [out] |
| == |
| a.py:1: error: Need type annotation for "y" |
| |
| [case testNonePartialType4] |
| import a |
| [file a.py] |
| y = None |
| def f() -> None: |
| global y |
| y = '' |
| [file a.py.2] |
| from typing import Optional |
| y: Optional[str] = None |
| def f() -> None: |
| global y |
| y = '' |
| [out] |
| a.py:1: error: Need type annotation for "y" |
| == |
| |
| [case testSkippedClass1] |
| import a |
| [file a.py] |
| class A: pass |
| [file a.py.2] |
| import sys |
| if sys.platform == 'xyz': |
| class A: pass |
| [builtins fixtures/ops.pyi] |
| [out] |
| == |
| |
| [case testSkippedClass2] |
| import a |
| [file a.py] |
| import sys |
| if sys.platform == 'xyz': |
| class A: pass |
| [file a.py.2] |
| import sys |
| if sys.platform == 'xyz': |
| class A: pass |
| [builtins fixtures/ops.pyi] |
| [out] |
| == |
| |
| [case testSkippedClass3] |
| import a |
| [file a.py] |
| import sys |
| if sys.platform == 'xyz': |
| class A: pass |
| [file a.py.2] |
| class A: pass |
| [builtins fixtures/ops.pyi] |
| [out] |
| == |
| |
| [case testSkippedClass4] |
| import a |
| [file a.py] |
| import sys |
| if sys.platform == 'xyz': |
| class A: pass |
| else: |
| class A: pass |
| [file a.py.2] |
| import sys |
| if sys.platform == 'xyz': |
| class A: pass |
| else: |
| class A: pass |
| [builtins fixtures/ops.pyi] |
| [out] |
| == |
| |
| [case testNewTypeDependencies1] |
| from a import N |
| |
| def f(x: N) -> None: |
| x.y = 1 |
| [file a.py] |
| from typing import NewType |
| from b import C |
| |
| N = NewType('N', C) |
| [file b.py] |
| class C: |
| y: int |
| [file b.py.2] |
| class C: |
| y: str |
| [out] |
| == |
| main:4: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testNewTypeDependencies2] |
| from a import N |
| from b import C, D |
| |
| def f(x: C) -> None: pass |
| |
| def g(x: N) -> None: |
| f(x) |
| [file a.py] |
| from typing import NewType |
| from b import D |
| |
| N = NewType('N', D) |
| [file b.py] |
| class C: pass |
| class D(C): pass |
| [file b.py.2] |
| class C: pass |
| class D: pass |
| [out] |
| == |
| main:7: error: Argument 1 to "f" has incompatible type "N"; expected "C" |
| |
| [case testNewTypeDependencies3] |
| from a import N |
| |
| def f(x: N) -> None: |
| x.y |
| [file a.py] |
| from typing import NewType |
| from b import C |
| N = NewType('N', C) |
| [file a.py.2] |
| from typing import NewType |
| from b import D |
| N = NewType('N', D) |
| [file b.py] |
| class C: |
| y: int |
| class D: |
| pass |
| [out] |
| == |
| main:4: error: "N" has no attribute "y" |
| |
| [case testNamedTupleWithinFunction] |
| from typing import NamedTuple |
| import b |
| def f() -> None: |
| b.x |
| n = NamedTuple('n', []) |
| [file b.py] |
| x = 0 |
| [file b.py.2] |
| x = '' |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| |
| [case testNamedTupleFallback] |
| # This test will fail without semantic analyzer pass 2 patches |
| import a |
| [file a.py] |
| import b |
| [file b.py] |
| from typing import NamedTuple |
| import c |
| c.x |
| class N(NamedTuple): |
| count: int |
| [file c.py] |
| x = 0 |
| [file c.py.2] |
| x = '' |
| [builtins fixtures/tuple.pyi] |
| [out] |
| b.py:5: error: Incompatible types in assignment (expression has type "int", base class "tuple" defined the type as "Callable[[Tuple[int, ...], object], int]") |
| == |
| b.py:5: error: Incompatible types in assignment (expression has type "int", base class "tuple" defined the type as "Callable[[Tuple[int, ...], object], int]") |
| |
| [case testReprocessEllipses1] |
| import a |
| [file a.py] |
| from typing import Tuple |
| def foo(x: Tuple[int, ...]) -> None: pass |
| [file a.py.2] |
| from typing import Tuple |
| def foo(x: Tuple[int, ...]) -> None: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| |
| [case testReprocessEllipses2] |
| import a |
| [file a.py] |
| from typing import Callable |
| def foo(x: Callable[..., int]) -> None: pass |
| [file a.py.2] |
| from typing import Callable |
| def foo(x: Callable[..., int]) -> None: pass |
| [out] |
| == |
| |
| [case testReprocessCallableArg] |
| import a |
| [file a.py] |
| from typing import Callable |
| from mypy_extensions import Arg |
| def a(f: Callable[[Arg(int, 'x')], int]) -> None: pass |
| [file a.py.2] |
| from typing import Callable |
| from mypy_extensions import Arg |
| def a(f: Callable[[Arg(int, 'x')], int]) -> None: pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| |
| [case testImplicitTuple1] |
| import a |
| [file a.py] |
| # Bogus annotation in nested function masked because outer function |
| # isn't annotated |
| def unchecked(): |
| def inner(): |
| # type: () -> (str, int) |
| return 'lol', 10 |
| [file a.py.2] |
| # dummy change |
| def unchecked(): |
| def inner(): |
| # type: () -> (str, int) |
| return 'lol', 10 |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| |
| [case testImplicitTuple2] |
| import a |
| [file a.py] |
| def inner(): |
| # type: () -> (str, int) |
| return 'lol', 10 |
| [file a.py.2] |
| # dummy change |
| def inner(): |
| # type: () -> (str, int) |
| return 'lol', 10 |
| [builtins fixtures/tuple.pyi] |
| [out] |
| a.py:1: error: Syntax error in type annotation |
| a.py:1: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn) |
| == |
| a.py:2: error: Syntax error in type annotation |
| a.py:2: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn) |
| |
| [case testImplicitTuple3] |
| import a |
| [file a.py] |
| (x, y) = 1, 'hi' # type: (int, str) |
| [file a.py.2] |
| # dummy change |
| (x, y) = 1, 'hi' # type: (int, str) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| |
| [case testCastConfusion] |
| import b |
| [file a.py] |
| from typing import cast |
| class Thing: |
| def foo(self) -> None: pass |
| |
| thing = cast(Thing, Thing()) |
| |
| [file b.py] |
| from typing import Optional |
| from a import Thing, thing |
| class User: |
| def __init__(self, x: Optional[Thing]) -> None: |
| self.x = x if x else thing |
| def use(self) -> None: self.x.foo() |
| |
| [file a.py.2] |
| from typing import cast |
| class Thing: |
| def foo(self) -> None: pass |
| |
| thing = cast(Thing, Thing()) |
| # update |
| |
| [file b.py.2] |
| from typing import Optional |
| from a import Thing, thing |
| class User: |
| def __init__(self, x: Optional[Thing]) -> None: |
| self.x = x if x else thing |
| def use(self) -> None: self.x.foo() |
| # update |
| [builtins fixtures/ops.pyi] |
| [out] |
| == |
| |
| [case testNoStrictOptionalModule] |
| import a |
| a.y = a.x |
| [file a.py] |
| from typing import Optional |
| x: int |
| y: int |
| [file a.py.2] |
| from typing import Optional |
| x: Optional[int] |
| y: int |
| [file a.py.3] |
| from typing import Optional |
| x: Optional[str] |
| y: int |
| [out] |
| == |
| == |
| main:2: error: Incompatible types in assignment (expression has type "Optional[str]", variable has type "int") |
| |
| [case testNoStrictOptionalFunction] |
| import a |
| from typing import Optional |
| def f() -> None: |
| x: Optional[int] |
| a.g(x) |
| [file a.py] |
| from typing import Optional |
| def g(x: Optional[int]) -> None: |
| pass |
| [file a.py.2] |
| from typing import Optional |
| def g(x: int) -> None: |
| pass |
| [file a.py.3] |
| from typing import Optional |
| def g(x: str) -> None: |
| pass |
| [out] |
| == |
| == |
| main:5: error: Argument 1 to "g" has incompatible type "Optional[int]"; expected "str" |
| |
| [case testNoStrictOptionalMethod] |
| import a |
| from typing import Optional |
| class C: |
| def f(self) -> None: |
| x: Optional[int] |
| a.B().g(x) |
| [file a.py] |
| from typing import Optional |
| class B: |
| def g(self, x: Optional[int]) -> None: |
| pass |
| [file a.py.2] |
| from typing import Optional |
| class B: |
| def g(self, x: int) -> None: |
| pass |
| [file a.py.3] |
| from typing import Optional |
| class B: |
| def g(self, x: str) -> None: |
| pass |
| [out] |
| == |
| == |
| main:6: error: Argument 1 to "g" of "B" has incompatible type "Optional[int]"; expected "str" |
| |
| [case testStrictOptionalModule] |
| # flags: --strict-optional |
| import a |
| a.y = a.x |
| [file a.py] |
| from typing import Optional |
| x: int |
| y: int |
| [file a.py.2] |
| from typing import Optional |
| x: Optional[int] |
| y: int |
| [out] |
| == |
| main:3: error: Incompatible types in assignment (expression has type "Optional[int]", variable has type "int") |
| |
| [case testStrictOptionalFunction] |
| # flags: --strict-optional |
| import a |
| from typing import Optional |
| def f() -> None: |
| x: Optional[int] |
| a.g(x) |
| [file a.py] |
| from typing import Optional |
| def g(x: Optional[int]) -> None: |
| pass |
| [file a.py.2] |
| from typing import Optional |
| def g(x: int) -> None: |
| pass |
| [out] |
| == |
| main:6: error: Argument 1 to "g" has incompatible type "Optional[int]"; expected "int" |
| |
| [case testStrictOptionalMethod] |
| # flags: --strict-optional |
| import a |
| from typing import Optional |
| class C: |
| def f(self) -> None: |
| x: Optional[int] |
| a.B().g(x) |
| [file a.py] |
| from typing import Optional |
| class B: |
| def g(self, x: Optional[int]) -> None: |
| pass |
| [file a.py.2] |
| from typing import Optional |
| class B: |
| def g(self, x: int) -> None: |
| pass |
| [out] |
| == |
| main:7: error: Argument 1 to "g" of "B" has incompatible type "Optional[int]"; expected "int" |
| |
| [case testPerFileStrictOptionalModule] |
| import a |
| [file mypy.ini] |
| \[mypy] |
| strict_optional = False |
| \[mypy-a.*] |
| strict_optional = True |
| [file a.py] |
| from typing import Optional |
| import b |
| x: int |
| y: int = x |
| [file b.py] |
| from typing import Optional |
| x: int |
| y: int = x |
| [file b.py.2] |
| from typing import Optional |
| x: Optional[int] |
| y: int = x |
| [file a.py.3] |
| from typing import Optional |
| import b |
| x: Optional[int] |
| y: int = x |
| [out] |
| == |
| == |
| a.py:4: error: Incompatible types in assignment (expression has type "Optional[int]", variable has type "int") |
| |
| [case testPerFileStrictOptionalModuleOnly] |
| import a |
| [file mypy.ini] |
| \[mypy] |
| strict_optional = False |
| \[mypy-a.*] |
| strict_optional = True |
| [file a.py] |
| from typing import Optional |
| import b |
| y: int = b.x |
| class Dummy: |
| def f(self) -> None: |
| pass |
| [file b.py] |
| from typing import Optional |
| import c |
| x: int |
| y: int = c.x |
| class Dummy: |
| def f(self) -> None: |
| pass |
| [file c.py] |
| from typing import Optional |
| x: int |
| [file c.py.2] |
| from typing import Optional |
| x: Optional[int] |
| [file b.py.3] |
| from typing import Optional |
| import c |
| x: Optional[int] |
| y: int = c.x |
| [file a.py.4] |
| from typing import Optional |
| import b |
| y: Optional[int] = b.x |
| class Dummy: |
| def f(self) -> None: |
| pass |
| [out] |
| == |
| == |
| a.py:3: error: Incompatible types in assignment (expression has type "Optional[int]", variable has type "int") |
| == |
| |
| [case testPerFileStrictOptionalFunction] |
| import a |
| [file mypy.ini] |
| \[mypy] |
| strict_optional = False |
| \[mypy-b.*] |
| strict_optional = True |
| [file a.py] |
| from typing import Optional |
| import b |
| def f() -> None: |
| x: int |
| x = b.g(x) |
| [file b.py] |
| from typing import Optional |
| import c |
| def g(x: Optional[int]) -> Optional[int]: |
| return c.h(x) |
| [file c.py] |
| from typing import Optional |
| def h(x: Optional[int]) -> int: |
| pass |
| [file c.py.2] |
| from typing import Optional |
| def h(x: int) -> int: |
| pass |
| [file b.py.3] |
| from typing import Optional |
| import c |
| def g(x: int) -> Optional[int]: |
| return c.h(x) |
| [out] |
| == |
| b.py:4: error: Argument 1 to "h" has incompatible type "Optional[int]"; expected "int" |
| == |
| |
| [case testPerFileStrictOptionalMethod] |
| import a |
| [file mypy.ini] |
| \[mypy] |
| strict_optional = False |
| \[mypy-b.*] |
| strict_optional = True |
| [file a.py] |
| from typing import Optional |
| import b |
| class A: |
| def f(self) -> None: |
| x: int |
| x = b.B().g(x) |
| [file b.py] |
| from typing import Optional |
| import c |
| class B: |
| def g(self, x: Optional[int]) -> Optional[int]: |
| return c.C().h(x) |
| [file c.py] |
| from typing import Optional |
| class C: |
| def h(self, x: Optional[int]) -> int: |
| pass |
| [file c.py.2] |
| from typing import Optional |
| class C: |
| def h(self, x: int) -> int: |
| pass |
| [file b.py.3] |
| from typing import Optional |
| import c |
| class B: |
| def g(self, x: int) -> Optional[int]: |
| return c.C().h(x) |
| [out] |
| == |
| b.py:5: error: Argument 1 to "h" of "C" has incompatible type "Optional[int]"; expected "int" |
| == |
| |
| [case testTypeVarValuesFunction] |
| import a |
| [file a.py] |
| from typing import TypeVar |
| from c import A, B |
| T = TypeVar('T', A, B) |
| |
| def f(x: T) -> T: |
| x.x = int() |
| return x |
| [file c.py] |
| class A: |
| x: int |
| class B: |
| x: int |
| [file c.py.2] |
| class A: |
| x: int |
| class B: |
| x: str |
| [out] |
| == |
| a.py:6: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testTypeVarValuesClass] |
| import a |
| [file a.py] |
| import c |
| class C: |
| x: c.D[c.A] |
| [file c.py] |
| from typing import TypeVar, Generic |
| class A: pass |
| class B: pass |
| class C: pass |
| T = TypeVar('T', A, B, C) |
| class D(Generic[T]): |
| pass |
| [file c.py.2] |
| from typing import TypeVar, Generic |
| class A: pass |
| class B: pass |
| class C: pass |
| T = TypeVar('T', B, C) |
| class D(Generic[T]): |
| pass |
| [out] |
| == |
| a.py:3: error: Value of type variable "T" of "D" cannot be "A" |
| |
| [case testTypeVarValuesMethod1] |
| import a |
| [file a.py] |
| from typing import Generic |
| import c |
| class G(Generic[c.T]): |
| def f(self, x: c.T) -> None: |
| x.x = int() |
| [file c.py] |
| from typing import TypeVar |
| class A: |
| x: int |
| class B: |
| x: int |
| class C: |
| x: str |
| T = TypeVar('T', A, B, C) |
| [file c.py.2] |
| from typing import TypeVar |
| class A: |
| x: int |
| class B: |
| x: int |
| class C: |
| x: str |
| T = TypeVar('T', A, B) |
| [out] |
| a.py:5: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| == |
| |
| [case testTypeVarValuesMethod2] |
| import a |
| [file a.py] |
| from typing import Generic |
| import c |
| class G(Generic[c.T]): |
| def f(self, x: c.T) -> None: |
| x.x = int() |
| [file c.py] |
| from typing import TypeVar |
| class A: |
| x: int |
| class B: |
| x: int |
| T = TypeVar('T', A, B) |
| [file c.py.2] |
| from typing import TypeVar |
| class A: |
| x: int |
| class B: |
| x: str |
| T = TypeVar('T', A, B) |
| [out] |
| == |
| a.py:5: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testTypeVarBoundFunction] |
| import a |
| [file a.py] |
| from typing import TypeVar |
| from c import B |
| T = TypeVar('T', bound=B) |
| |
| def f(x: T) -> T: |
| x.x = int() |
| return x |
| [file c.py] |
| class B: |
| x: int |
| [file c.py.2] |
| class B: |
| x: str |
| [out] |
| == |
| a.py:6: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testTypeVarBoundClass] |
| import a |
| [file a.py] |
| import c |
| class C: |
| x: c.D[c.A] |
| [file c.py] |
| from typing import TypeVar, Generic |
| class A: pass |
| class B: pass |
| T = TypeVar('T', bound=A) |
| class D(Generic[T]): |
| pass |
| [file c.py.2] |
| from typing import TypeVar, Generic |
| class A: pass |
| class B: pass |
| T = TypeVar('T', bound=B) |
| class D(Generic[T]): |
| pass |
| [out] |
| == |
| a.py:3: error: Type argument "c.A" of "D" must be a subtype of "c.B" |
| |
| [case testTypeVarValuesRuntime] |
| from mod import I, S, D |
| A = I |
| x = D[S, A]() |
| [file mod.py] |
| import submod |
| from typing import Generic |
| class D(Generic[submod.T, submod.U]): pass |
| class I: pass |
| class S: pass |
| [file submod.py] |
| from typing import TypeVar |
| T = TypeVar('T') |
| U = TypeVar('U') |
| [file submod.py.2] |
| from typing import TypeVar |
| T = TypeVar('T', int, str) |
| U = TypeVar('U', int, str) |
| [out] |
| == |
| main:3: error: Value of type variable "submod.T" of "D" cannot be "S" |
| main:3: error: Value of type variable "submod.U" of "D" cannot be "I" |
| |
| [case testTypeVarBoundRuntime] |
| from mod import I, S, D |
| A = I |
| x = D[S, A]() |
| [file mod.py] |
| import submod |
| from typing import Generic |
| class D(Generic[submod.T, submod.U]): pass |
| class I: pass |
| class S: pass |
| [file submod.py] |
| from typing import TypeVar |
| T = TypeVar('T', bound=int) |
| U = TypeVar('U', bound=int) |
| [file submod.py.2] |
| from typing import TypeVar |
| T = TypeVar('T') |
| U = TypeVar('U') |
| [out] |
| main:3: error: Value of type variable "submod.T" of "D" cannot be "S" |
| main:3: error: Value of type variable "submod.U" of "D" cannot be "I" |
| == |
| |
| [case testGenericFineCallableNormal] |
| import a |
| [file a.py] |
| import b |
| x: int = b.f(int()) |
| [file b.py] |
| from c import g |
| f = g |
| [file c.py] |
| from typing import TypeVar |
| class B: pass |
| T = TypeVar('T') |
| def g(x: T) -> T: |
| pass |
| [file c.py.2] |
| from typing import TypeVar |
| class B: pass |
| T = TypeVar('T', str, B) |
| def g(x: T) -> T: |
| pass |
| [out] |
| == |
| a.py:2: error: Value of type variable "T" of function cannot be "int" |
| |
| [case testGenericFineCallableNamed] |
| import a |
| [file a.py] |
| import b |
| x: int = b.f(x=int()) |
| [file b.py] |
| from c import g |
| f = g |
| [file c.py] |
| from typing import TypeVar |
| class B: pass |
| T = TypeVar('T') |
| def g(x: T) -> T: |
| pass |
| [file c.py.2] |
| from typing import TypeVar |
| class B: pass |
| T = TypeVar('T') |
| def g(y: T) -> T: |
| pass |
| [out] |
| == |
| a.py:2: error: Unexpected keyword argument "x" |
| c.py:4: note: Called function defined here |
| |
| [case testGenericFineCallableInBound] |
| import a |
| [file a.py] |
| import b |
| x: int = b.f()(int()) |
| [file b.py] |
| from c import g |
| f = g |
| [file c.py] |
| from typing import Callable, TypeVar |
| class B: pass |
| T = TypeVar('T') |
| def g() -> Callable[[T], T]: |
| pass |
| [file c.py.2] |
| from typing import Callable, TypeVar |
| class B: pass |
| T = TypeVar('T', str, B) |
| def g() -> Callable[[T], T]: |
| pass |
| [out] |
| == |
| a.py:2: error: Value of type variable "T" of function cannot be "int" |
| |
| [case testGenericFineCallableAddedBound] |
| import a |
| [file a.py] |
| import b |
| x: int = b.f(int()) |
| [file b.py] |
| from c import g |
| f = g |
| [file c.py] |
| from typing import TypeVar |
| class B: pass |
| T = TypeVar('T') |
| def g(x: T) -> T: |
| pass |
| [file c.py.2] |
| from typing import TypeVar |
| class B: pass |
| T = TypeVar('T', bound=B) |
| def g(x: T) -> T: |
| pass |
| [out] |
| == |
| a.py:2: error: Value of type variable "T" of function cannot be "int" |
| |
| [case testGenericFineCallableBoundDeleted-only_when_cache] |
| # See https://github.com/python/mypy/issues/4783 |
| import a |
| [file a.py] |
| import b |
| x: int = b.f(int()) |
| [file b.py] |
| from c import g |
| f = g |
| [file c.py] |
| from typing import TypeVar |
| import d |
| T = TypeVar('T', bound=d.B) |
| def g(x: T) -> T: |
| pass |
| [file d.py] |
| class B: |
| pass |
| [file d.py.2] |
| # empty |
| [out] |
| a.py:2: error: Value of type variable "T" of function cannot be "int" |
| == |
| c.py:3: error: Name 'd.B' is not defined |
| |
| [case testGenericFineCallableToNonGeneric] |
| import a |
| [file a.py] |
| import b |
| x: int = b.f(x=int()) |
| [file b.py] |
| from c import g |
| f = g |
| [file c.py] |
| from typing import TypeVar |
| T = TypeVar('T') |
| def g(x: T) -> T: |
| pass |
| [file c.py.2] |
| from typing import TypeVar |
| class T: pass |
| def g(x: T) -> T: |
| pass |
| [out] |
| == |
| a.py:2: error: Incompatible types in assignment (expression has type "T", variable has type "int") |
| a.py:2: error: Argument "x" has incompatible type "int"; expected "T" |
| |
| [case testGenericFineCallableToGenericClass] |
| import a |
| [file a.py] |
| import b |
| x: int = b.f(x=int()) |
| [file b.py] |
| from c import g |
| f = g |
| [file c.py] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| def g(x: T) -> T: |
| pass |
| [file c.py.2] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class g(Generic[T]): |
| def __init__(self, x: T) -> None: |
| pass |
| [out] |
| == |
| a.py:2: error: Incompatible types in assignment (expression has type "g[int]", variable has type "int") |
| |
| [case testMakeClassNoLongerAbstract1] |
| [file z.py] |
| from abc import abstractmethod, ABCMeta |
| class I(metaclass=ABCMeta): |
| @abstractmethod |
| def f(self) -> None: pass |
| [file b.py] |
| from z import I |
| class Foo(I): |
| pass |
| def x() -> Foo: return None |
| [file z.py.2] |
| from abc import abstractmethod, ABCMeta |
| class I(metaclass=ABCMeta): |
| pass |
| [file b.py.2] |
| from z import I |
| class Foo(I): |
| pass |
| def x() -> Foo: return Foo() |
| [out] |
| == |
| |
| [case testMakeClassNoLongerAbstract2] |
| -- this version never failed, but it is just a file-renaming |
| -- away from the above test that did |
| [file a.py] |
| from abc import abstractmethod, ABCMeta |
| class I(metaclass=ABCMeta): |
| @abstractmethod |
| def f(self) -> None: pass |
| [file b.py] |
| from a import I |
| class Foo(I): |
| pass |
| def x() -> Foo: return None |
| [file a.py.2] |
| from abc import abstractmethod, ABCMeta |
| class I(metaclass=ABCMeta): |
| pass |
| [file b.py.2] |
| from a import I |
| class Foo(I): |
| pass |
| def x() -> Foo: return Foo() |
| [out] |
| == |
| |
| [case testRefreshClassBasedEnum] |
| import aa |
| [file aa.py] |
| import a |
| [file a.py] |
| from enum import Enum |
| import b |
| b.x |
| class C(Enum): |
| X = 0 |
| [file b.py] |
| x = 0 |
| [file b.py.2] |
| x = '' |
| [file aa.py.3] |
| from a import C |
| c: C |
| c = C.X |
| if int(): |
| c = 1 |
| [out] |
| == |
| == |
| aa.py:5: error: Incompatible types in assignment (expression has type "int", variable has type "C") |
| |
| [case testRefreshClassBasedIntEnum] |
| import aa |
| [file aa.py] |
| import a |
| [file a.py] |
| from enum import IntEnum |
| import b |
| b.x |
| class C(IntEnum): |
| X = 0 |
| x: int |
| x = C.X |
| [file b.py] |
| x = 0 |
| [file b.py.2] |
| x = '' |
| [file aa.py.3] |
| from a import C |
| c: C |
| c = C.X |
| if int(): |
| c = 1 |
| n: int |
| n = C.X |
| if int(): |
| n = c |
| [out] |
| == |
| == |
| aa.py:5: error: Incompatible types in assignment (expression has type "int", variable has type "C") |
| |
| [case testClassBasedEnumPropagation1] |
| import a |
| [file a.py] |
| from b import C |
| |
| def f(x: C) -> None: pass |
| f(C.X) |
| f(C.Y) |
| [file b.py] |
| from enum import Enum |
| |
| class C(Enum): |
| X = 0 |
| Y = 1 |
| [file b.py.2] |
| from enum import Enum |
| |
| class C(Enum): |
| X = 0 |
| [typing fixtures/typing-medium.pyi] |
| [out] |
| == |
| a.py:5: error: "Type[C]" has no attribute "Y" |
| |
| [case testClassBasedEnumPropagation2] |
| import a |
| [file a.py] |
| from b import C |
| |
| def f(x: int) -> None: pass |
| f(C.X) |
| f(C.Y) |
| [file b.py] |
| class C: |
| X = 0 |
| Y = 1 |
| [file b.py.2] |
| from enum import Enum |
| class C(Enum): |
| X = 0 |
| Y = 1 |
| [out] |
| == |
| a.py:4: error: Argument 1 to "f" has incompatible type "C"; expected "int" |
| a.py:5: error: Argument 1 to "f" has incompatible type "C"; expected "int" |
| |
| [case testRefreshFuncBasedEnum] |
| import aa |
| [file aa.py] |
| import a |
| [file a.py] |
| from enum import Enum |
| import b |
| b.x |
| C = Enum('C', [('X', 0)]) |
| [file b.py] |
| x = 0 |
| [file b.py.2] |
| x = '' |
| [file aa.py.3] |
| from a import C |
| c: C |
| c = C.X |
| if int(): |
| c = 1 |
| [out] |
| == |
| == |
| aa.py:5: error: Incompatible types in assignment (expression has type "int", variable has type "C") |
| |
| [case testRefreshFuncBasedIntEnum] |
| import aa |
| [file aa.py] |
| import a |
| [file a.py] |
| from enum import IntEnum |
| import b |
| b.x |
| C = IntEnum('C', 'X') |
| x: int |
| x = C.X |
| [file b.py] |
| x = 0 |
| [file b.py.2] |
| x = '' |
| [file aa.py.3] |
| from a import C |
| c: C |
| c = C.X |
| if int(): |
| c = 1 # Error |
| n: int |
| n = C.X |
| n = c |
| [out] |
| == |
| == |
| aa.py:5: error: Incompatible types in assignment (expression has type "int", variable has type "C") |
| |
| [case testFuncBasedEnumPropagation1] |
| import a |
| [file a.py] |
| from b import C |
| |
| def f(x: C) -> None: pass |
| f(C.X) |
| f(C.Y) |
| [file b.py] |
| from enum import Enum |
| |
| C = Enum('C', 'X Y') |
| [file b.py.2] |
| from enum import Enum |
| |
| C = Enum('C', 'X') |
| [typing fixtures/typing-medium.pyi] |
| [out] |
| == |
| a.py:5: error: "Type[C]" has no attribute "Y" |
| |
| [case testFuncBasedEnumPropagation2] |
| import a |
| [file a.py] |
| from b import C |
| |
| def f(x: int) -> None: pass |
| f(C.X) |
| f(C.Y) |
| [file b.py] |
| class C: |
| X = 0 |
| Y = 1 |
| [file b.py.2] |
| from enum import Enum |
| C = Enum('C', [('X', 0), ('Y', 1)]) |
| [out] |
| == |
| a.py:4: error: Argument 1 to "f" has incompatible type "C"; expected "int" |
| a.py:5: error: Argument 1 to "f" has incompatible type "C"; expected "int" |
| |
| [case testChangeTypeVarToFunction] |
| |
| import a |
| from typing import Generic |
| Alias = C[C[a.T]] |
| |
| class C(Generic[a.T]): |
| def meth(self, x: a.T) -> None: |
| pass |
| def outer() -> None: |
| def func(x: a.T) -> Alias[a.T]: |
| pass |
| [file a.py] |
| from typing import TypeVar |
| T = TypeVar('T') |
| [file a.py.2] |
| from typing import TypeVar |
| def T() -> None: |
| pass |
| [out] |
| == |
| main:4: error: "C" expects no type arguments, but 1 given |
| main:4: error: Function "a.T" is not valid as a type |
| main:4: note: Perhaps you need "Callable[...]" or a callback protocol? |
| main:6: error: Free type variable expected in Generic[...] |
| main:7: error: Function "a.T" is not valid as a type |
| main:7: note: Perhaps you need "Callable[...]" or a callback protocol? |
| main:10: error: Function "a.T" is not valid as a type |
| main:10: note: Perhaps you need "Callable[...]" or a callback protocol? |
| main:10: error: Bad number of arguments for type alias, expected: 0, given: 1 |
| |
| [case testChangeTypeVarToModule] |
| |
| import a |
| from typing import Generic |
| Alias = C[C[a.T]] |
| |
| class C(Generic[a.T]): |
| def meth(self, x: a.T) -> None: |
| pass |
| def outer() -> None: |
| def func(x: a.T) -> Alias[a.T]: |
| pass |
| [file a.py] |
| from typing import TypeVar |
| T = TypeVar('T') |
| [file T.py.2] |
| [file a.py.3] |
| from typing import TypeVar |
| import T |
| [out] |
| == |
| == |
| main:4: error: "C" expects no type arguments, but 1 given |
| main:4: error: Module "T" is not valid as a type |
| main:6: error: Free type variable expected in Generic[...] |
| main:7: error: Module "T" is not valid as a type |
| main:10: error: Module "T" is not valid as a type |
| main:10: error: Bad number of arguments for type alias, expected: 0, given: 1 |
| |
| [case testChangeClassToModule] |
| |
| import a |
| x: a.C |
| def f() -> None: |
| a.C() |
| class A: |
| def meth(self) -> None: |
| def inner() -> a.C: |
| pass |
| [file a.py] |
| class C: |
| pass |
| [file C.py.2] |
| [file a.py.3] |
| import C |
| [builtins fixtures/module.pyi] |
| [out] |
| == |
| == |
| main:3: error: Module "C" is not valid as a type |
| main:5: error: Module not callable |
| main:8: error: Module "C" is not valid as a type |
| |
| [case testChangeTypeVarToTypeAlias] |
| |
| import a |
| from typing import Generic |
| Alias = C[C[a.T]] |
| |
| class C(Generic[a.T]): |
| def meth(self, x: a.T) -> None: |
| pass |
| def outer() -> None: |
| def func(x: a.T) -> Alias[a.T]: |
| pass |
| [file a.py] |
| from typing import TypeVar |
| T = TypeVar('T') |
| [file a.py.2] |
| from typing import TypeVar |
| T = int |
| [out] |
| == |
| main:4: error: "C" expects no type arguments, but 1 given |
| main:6: error: Free type variable expected in Generic[...] |
| main:10: error: Bad number of arguments for type alias, expected: 0, given: 1 |
| |
| [case testChangeTypeAliasToModule] |
| |
| import a |
| x: a.C |
| def f() -> None: |
| a.C() |
| class A: |
| def meth(self) -> None: |
| def inner() -> a.C: |
| pass |
| [file a.py] |
| import b |
| C = b.D |
| [file b.py] |
| class D: |
| pass |
| [file D.py.2] |
| [file b.py.3] |
| import D |
| [builtins fixtures/module.pyi] |
| [out] |
| == |
| == |
| main:3: error: Module "D" is not valid as a type |
| main:5: error: Module not callable |
| main:8: error: Module "D" is not valid as a type |
| |
| [case testChangeTypeAliasToModuleUnqualified] |
| |
| from a import C |
| x: C |
| def f() -> None: |
| C() |
| class A: |
| def meth(self) -> None: |
| def inner() -> C: |
| pass |
| [file a.py] |
| from b import D |
| C = D |
| [file b.py] |
| class D: |
| pass |
| [file D.py.2] |
| [file b.py.3] |
| import D |
| [builtins fixtures/module.pyi] |
| [out] |
| == |
| == |
| main:3: error: Module "D" is not valid as a type |
| main:5: error: Module not callable |
| main:8: error: Module "D" is not valid as a type |
| |
| [case testChangeFunctionToVariableAndRefreshUsingStaleDependency] |
| import a |
| import c |
| [file a.py] |
| import c |
| def f() -> c.A: pass |
| [file a.py.2] |
| f = 1 |
| [file c.py] |
| class A: pass |
| [file c.py.3] |
| [out] |
| == |
| == |
| |
| [case testChangeFunctionToTypeVarAndRefreshUsingStaleDependency] |
| import a |
| import c |
| [file a.py] |
| import c |
| def f() -> c.A: pass |
| [file a.py.2] |
| from typing import TypeVar |
| f = TypeVar('f') |
| [file c.py] |
| class A: pass |
| [file c.py.3] |
| [out] |
| == |
| == |
| |
| [case testChangeFunctionToModuleAndRefreshUsingStaleDependency] |
| import a |
| import c |
| [file a.py] |
| import c |
| def f() -> c.A: pass |
| [file a.py.2] |
| import c as f |
| [file c.py] |
| class A: pass |
| [file c.py.3] |
| [out] |
| == |
| == |
| |
| [case testChangeFunctionToTypeAliasAndRefreshUsingStaleDependency1] |
| import a |
| import c |
| [file a.py] |
| import c |
| def f() -> c.A: pass |
| [file a.py.2] |
| f = int |
| [file c.py] |
| class A: pass |
| [file c.py.3] |
| [out] |
| == |
| == |
| |
| [case testChangeFunctionToTypeAliasAndRefreshUsingStaleDependency2] |
| import a |
| import c |
| [file a.py] |
| import c |
| def f() -> c.A: pass |
| [file a.py.2] |
| from typing import List |
| f = List[int] |
| [file c.py] |
| class A: pass |
| [file c.py.3] |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| == |
| |
| [case testChangeFunctionToClassAndRefreshUsingStaleDependency] |
| import a |
| import c |
| [file a.py] |
| import c |
| def f() -> c.A: pass |
| [file a.py.2] |
| class f: pass |
| [file c.py] |
| class A: pass |
| [file c.py.3] |
| [out] |
| == |
| == |
| |
| [case testClassToVariableAndRefreshUsingStaleDependency] |
| import a |
| import c |
| [file a.py] |
| import c |
| class A: |
| def f(self) -> c.A: pass |
| [file a.py.2] |
| A = 0 |
| [file c.py] |
| class A: pass |
| [file c.py.3] |
| [out] |
| == |
| == |
| |
| [case testFunctionToImportedFunctionAndRefreshUsingStaleDependency] |
| import a |
| import c |
| [file a.py] |
| import c |
| def f() -> c.A: pass |
| [file a.py.2] |
| from d import f |
| [file c.py] |
| class A: pass |
| [file c.py.3] |
| [file d.py] |
| def g() -> None: pass |
| def f() -> None: |
| g() |
| [out] |
| == |
| == |
| |
| [case testMethodToVariableAndRefreshUsingStaleDependency] |
| import a |
| import c |
| [file a.py] |
| import c |
| class B: |
| def f(self) -> c.A: pass |
| [file a.py.2] |
| class B: |
| f = 0 |
| [file c.py] |
| class A: pass |
| [file c.py.3] |
| [out] |
| == |
| == |
| |
| [case testChangeGenericFunctionToVariable] |
| import a |
| x: int |
| y: int = a.f(x) |
| class Dummy: |
| def g(self) -> None: |
| a.f(x) |
| [file a.py] |
| from typing import TypeVar |
| T = TypeVar('T') |
| def f(x: T) -> T: |
| pass |
| [file a.py.2] |
| from typing import TypeVar |
| T = TypeVar('T') |
| f = 42 |
| [out] |
| == |
| main:3: error: "int" not callable |
| main:6: error: "int" not callable |
| |
| [case testChangeGenericClassToVariable] |
| import a |
| x: int |
| a.A(x) |
| class Dummy: |
| def g(self) -> None: |
| a.A(x) |
| [file a.py] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class A(Generic[T]): |
| def __init__(self, x: T) -> None: |
| pass |
| [file a.py.2] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| A = 'no way' |
| [out] |
| == |
| main:3: error: "str" not callable |
| main:6: error: "str" not callable |
| |
| [case testChangeGenericMethodToVariable] |
| import a |
| x: int |
| y: int = a.A(x).f() |
| class Dummy: |
| def g(self) -> None: |
| a.A(x).f() |
| [file a.py] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class A(Generic[T]): |
| def __init__(self, x: T) -> None: |
| pass |
| def f(self) -> T: |
| pass |
| [file a.py.2] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class A(Generic[T]): |
| f: T |
| def __init__(self, x: T) -> None: |
| pass |
| [out] |
| == |
| main:3: error: "int" not callable |
| main:6: error: "int" not callable |
| |
| [case testRefreshNestedClassWithSelfReference] |
| import a |
| [file a.py] |
| import b |
| |
| def f(self) -> None: |
| b.y |
| class C: |
| z: C |
| [file b.py] |
| y = 0 |
| [file b.py.2] |
| y = '' |
| [file b.py.3] |
| y = 0 |
| [out] |
| == |
| == |
| |
| [case testMultipleAssignment] |
| import a |
| [file a.py] |
| from b import f |
| |
| def h(x: str) -> None: pass |
| |
| class C: |
| def __init__(self) -> None: |
| self.a, self.b = f() |
| |
| def g(self) -> None: |
| h(self.a) |
| [file b.py] |
| from typing import Tuple |
| def f() -> Tuple[str, int]: pass |
| [file b.py.2] |
| from typing import Tuple |
| def f() -> Tuple[int, object]: pass |
| [file b.py.3] |
| from typing import Tuple |
| def f() -> Tuple[str, int]: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| a.py:10: error: Argument 1 to "h" has incompatible type "int"; expected "str" |
| == |
| |
| [case testMultipleLvalues] |
| import a |
| [file a.py] |
| from b import f |
| |
| def h(x: str) -> None: pass |
| |
| class C: |
| def __init__(self) -> None: |
| self.a = self.b = f() |
| |
| def g(self) -> None: |
| h(self.a) |
| h(self.b) |
| [file b.py] |
| def f() -> str: pass |
| [file b.py.2] |
| def f() -> int: pass |
| [file b.py.3] |
| def f() -> str: pass |
| [out] |
| == |
| a.py:10: error: Argument 1 to "h" has incompatible type "int"; expected "str" |
| a.py:11: error: Argument 1 to "h" has incompatible type "int"; expected "str" |
| == |
| |
| [case testNoOpUpdateFineGrainedIncremental1] |
| # cmd: mypy a.py |
| [file a.py] |
| 1() |
| [file b.py.2] |
| # Note: this file is not part of the build |
| [file a.py.3] |
| x = 1 |
| [out] |
| a.py:1: error: "int" not callable |
| == |
| a.py:1: error: "int" not callable |
| == |
| |
| [case testNoOpUpdateFineGrainedIncremental2] |
| # cmd: mypy a.py |
| [file a.py] |
| 1() |
| [file a.py.2] |
| 1() |
| [file a.py.3] |
| x = 1 |
| [file a.py.4] |
| x = 1 |
| [out] |
| a.py:1: error: "int" not callable |
| == |
| a.py:1: error: "int" not callable |
| == |
| == |
| |
| [case testNonExistentFileOnCommandLine1] |
| # cmd: mypy a.py nonexistent.py |
| [file a.py] |
| [file a.py.2] |
| 1() |
| [out] |
| mypy: can't read file 'tmp/nonexistent.py': No such file or directory |
| == |
| mypy: can't read file 'tmp/nonexistent.py': No such file or directory |
| |
| [case testNonExistentFileOnCommandLine2] |
| # cmd: mypy a.py |
| # cmd2: mypy a.py nonexistent.py |
| [file a.py] |
| [file a.py.2] |
| 1() |
| [out] |
| == |
| a.py:1: error: "int" not callable |
| |
| [case testNonExistentFileOnCommandLine3] |
| # cmd: mypy a.py |
| # cmd2: mypy a.py nonexistent.py |
| [file a.py] |
| [file nonexistent.py] |
| [delete nonexistent.py.2] |
| [out] |
| == |
| |
| [case testNonExistentFileOnCommandLine4] |
| # cmd: mypy a.py nonexistent.py |
| [file a.py] |
| [file nonexistent.py] |
| [delete nonexistent.py.2] |
| [out] |
| == |
| |
| [case testNonExistentFileOnCommandLine5] |
| # cmd: mypy a.py nonexistent_stub.pyi |
| # TODO: Should generate an error for missing file |
| [file a.py] |
| [file nonexistent_stub.pyi] |
| [delete nonexistent_stub.pyi.2] |
| [out] |
| == |
| |
| [case testDunderNewUpdatedMethod] |
| import a |
| [file a.py] |
| import b |
| class A: |
| def func(self) -> None: |
| b.C(int()) |
| [file b.py] |
| class C: |
| def __new__(cls, x: str) -> C: |
| pass |
| [file b.py.2] |
| class C: |
| def __new__(cls, x: int) -> C: |
| pass |
| [out] |
| a.py:4: error: Argument 1 to "C" has incompatible type "int"; expected "str" |
| == |
| |
| [case testDunderNewUpdatedSubclass] |
| import a |
| [file a.py] |
| import b |
| |
| b.D(int()) |
| [file b.py] |
| from c import C |
| class D(C): pass |
| [file c.py] |
| class C: |
| def __new__(cls, x: str) -> C: |
| pass |
| [file c.py.2] |
| class C: |
| def __new__(cls, x: int) -> C: |
| pass |
| [out] |
| a.py:3: error: Argument 1 to "D" has incompatible type "int"; expected "str" |
| == |
| |
| [case testDunderNewUpdatedAlias] |
| import a |
| [file a.py] |
| import b |
| |
| b.D(int()) |
| [file b.py] |
| from c import C |
| D = C |
| [file c.py] |
| class C: |
| def __new__(cls, x: int) -> C: |
| pass |
| [file c.py.2] |
| class C: |
| def __new__(cls, x: str) -> C: |
| pass |
| [out] |
| == |
| a.py:3: error: Argument 1 to "C" has incompatible type "int"; expected "str" |
| |
| [case testDunderNewUpdatedCallable] |
| import a |
| [file a.py] |
| from typing import Callable, Any |
| import b |
| |
| def func(arg: Callable[[int], Any]) -> None: |
| pass |
| func(b.C) |
| [file b.py] |
| class C: |
| def __new__(cls, x: int) -> C: |
| pass |
| [file b.py.2] |
| class C: |
| def __new__(cls, x: str) -> C: |
| pass |
| [out] |
| == |
| a.py:6: error: Argument 1 to "func" has incompatible type "Type[C]"; expected "Callable[[int], Any]" |
| |
| [case testDunderNewDefine] |
| import a |
| [file a.py] |
| import b |
| class A: |
| def func(self) -> None: |
| b.C() |
| [file b.py] |
| class C: |
| pass |
| [file b.py.2] |
| class C: |
| def __new__(cls, x: int) -> C: |
| pass |
| [out] |
| == |
| a.py:4: error: Missing positional argument "x" in call to "C" |
| |
| [case testDunderNewInsteadOfInit] |
| import a |
| [file a.py] |
| import b |
| class A: |
| def func(self) -> None: |
| b.C(int()) |
| [file b.py] |
| class C: |
| def __init__(cls, x: int) -> None: |
| pass |
| [file b.py.2] |
| class C: |
| def __new__(cls, x: int) -> C: |
| pass |
| [file b.py.3] |
| class C: |
| pass |
| [out] |
| == |
| == |
| a.py:4: error: Too many arguments for "C" |
| |
| -- Protocol tests |
| |
| [case testProtocolUpdateTypeInVariable] |
| import a |
| [file a.py] |
| import b |
| class C: |
| x: int |
| x: b.P = C() |
| [file b.py] |
| from typing import Protocol |
| class P(Protocol): |
| x: int |
| [file b.py.2] |
| from typing import Protocol |
| class P(Protocol): |
| x: str |
| [out] |
| == |
| a.py:4: error: Incompatible types in assignment (expression has type "C", variable has type "P") |
| a.py:4: note: Following member(s) of "C" have conflicts: |
| a.py:4: note: x: expected "str", got "int" |
| |
| [case testProtocolUpdateTypeInFunction] |
| import a |
| [file a.py] |
| import b |
| class C: |
| x: int |
| c: C |
| def f() -> None: |
| def g(x: b.P) -> None: |
| pass |
| g(c) |
| [file b.py] |
| from typing import Protocol |
| class P(Protocol): |
| x: int |
| [file b.py.2] |
| from typing import Protocol |
| class P(Protocol): |
| x: str |
| [out] |
| == |
| a.py:8: error: Argument 1 to "g" has incompatible type "C"; expected "P" |
| a.py:8: note: Following member(s) of "C" have conflicts: |
| a.py:8: note: x: expected "str", got "int" |
| |
| [case testProtocolUpdateTypeInClass] |
| import a |
| [file a.py] |
| import b |
| class C: |
| x: int |
| class A: |
| class B: |
| x: b.P |
| y: B |
| A().y.x = C() |
| [file b.py] |
| from typing import Protocol |
| class P(Protocol): |
| x: int |
| [file b.py.2] |
| from typing import Protocol |
| class P(Protocol): |
| x: str |
| [out] |
| == |
| a.py:8: error: Incompatible types in assignment (expression has type "C", variable has type "P") |
| a.py:8: note: Following member(s) of "C" have conflicts: |
| a.py:8: note: x: expected "str", got "int" |
| |
| [case testProtocolAddAttrInFunction] |
| import a |
| [file a.py] |
| import b |
| class C: |
| x: int |
| def f() -> None: |
| c: C |
| def g(x: b.P) -> None: |
| pass |
| g(c) |
| [file b.py] |
| from typing import Protocol |
| class P(Protocol): |
| x: int |
| [file b.py.2] |
| from typing import Protocol |
| class P(Protocol): |
| x: int |
| y: str |
| [out] |
| == |
| a.py:8: error: Argument 1 to "g" has incompatible type "C"; expected "P" |
| a.py:8: note: "C" is missing following "P" protocol member: |
| a.py:8: note: y |
| |
| [case testProtocolRemoveAttrInClass] |
| import a |
| [file a.py] |
| import b |
| class C: |
| x: int |
| class A: |
| class B: |
| x: b.P |
| y: B |
| A().y.x = C() |
| [file b.py] |
| from typing import Protocol |
| class P(Protocol): |
| x: int |
| y: str |
| [file b.py.2] |
| from typing import Protocol |
| class P(Protocol): |
| x: int |
| [out] |
| a.py:8: error: Incompatible types in assignment (expression has type "C", variable has type "P") |
| a.py:8: note: "C" is missing following "P" protocol member: |
| a.py:8: note: y |
| == |
| |
| [case testProtocolConcreteUpdateTypeFunction] |
| import a |
| [file a.py] |
| import b |
| from typing import Protocol |
| class P(Protocol): |
| x: int |
| def f() -> None: |
| def g(x: P) -> None: |
| pass |
| g(b.C()) |
| [file b.py] |
| class C: |
| x: int |
| [file b.py.2] |
| class C: |
| x: str |
| [out] |
| == |
| a.py:8: error: Argument 1 to "g" has incompatible type "C"; expected "P" |
| a.py:8: note: Following member(s) of "C" have conflicts: |
| a.py:8: note: x: expected "int", got "str" |
| |
| [case testProtocolConcreteUpdateTypeMethodGeneric] |
| import a |
| [file a.py] |
| import b |
| from typing import Protocol, TypeVar |
| T = TypeVar('T') |
| class P(Protocol[T]): |
| x: T |
| class C: |
| def g(self, x: P[int]) -> None: |
| pass |
| def do(self) -> None: |
| self.g(b.C()) |
| [file b.py] |
| class C: |
| x: int |
| [file b.py.2] |
| class C: |
| x: str |
| [out] |
| == |
| a.py:10: error: Argument 1 to "g" of "C" has incompatible type "C"; expected "P[int]" |
| a.py:10: note: Following member(s) of "C" have conflicts: |
| a.py:10: note: x: expected "int", got "str" |
| |
| [case testProtocolConcreteRemoveAttrVariable] |
| import a |
| [file a.py] |
| import b, c |
| cc: c.C |
| x: b.P = cc |
| [file b.py] |
| from typing import Protocol |
| class P(Protocol): |
| x: int |
| [file c.py] |
| class C: |
| x: int |
| [file c.py.2] |
| class C: |
| pass |
| [out] |
| == |
| a.py:3: error: Incompatible types in assignment (expression has type "C", variable has type "P") |
| |
| [case testProtocolUpdateBaseGeneric] |
| import a |
| [file a.py] |
| import b, c |
| def g(x: c.P) -> None: |
| pass |
| g(b.C()) |
| [file b.py] |
| class C: |
| x: int |
| [file c.py] |
| from typing import Protocol |
| import d |
| class P(d.PBase[int], Protocol): |
| pass |
| [file c.py.2] |
| from typing import Protocol |
| import d |
| class P(d.PBase[str], Protocol): |
| pass |
| [file d.py] |
| from typing import Protocol, TypeVar |
| T = TypeVar('T') |
| class PBase(Protocol[T]): |
| x: T |
| [out] |
| == |
| a.py:4: error: Argument 1 to "g" has incompatible type "C"; expected "P" |
| a.py:4: note: Following member(s) of "C" have conflicts: |
| a.py:4: note: x: expected "str", got "int" |
| |
| [case testProtocolConcreteUpdateBaseGeneric] |
| import a |
| [file a.py] |
| import b |
| from typing import Protocol |
| class P(Protocol): |
| x: int |
| def f(x: P) -> None: |
| pass |
| f(b.B()) |
| [file b.py] |
| import c |
| class B(c.C[int]): |
| pass |
| [file b.py.2] |
| import c |
| class B(c.C[str]): |
| pass |
| [file c.py] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class C(Generic[T]): |
| x: T |
| [out] |
| == |
| a.py:7: error: Argument 1 to "f" has incompatible type "B"; expected "P" |
| a.py:7: note: Following member(s) of "B" have conflicts: |
| a.py:7: note: x: expected "int", got "str" |
| |
| [case testProtocolChangeGeneric] |
| import a |
| [file a.py] |
| import b, c |
| x: b.P = c.C() |
| [file b.py] |
| import b2 |
| from typing import Protocol |
| class P(b2.P2[str], Protocol): |
| pass |
| [file b2.py] |
| from typing import Protocol, TypeVar |
| T = TypeVar('T') |
| class P2(Protocol[T]): |
| x: T |
| [file b2.py.2] |
| from typing import Protocol, TypeVar |
| T = TypeVar('T') |
| class P2(Protocol): |
| x: int |
| [file c.py] |
| class C: |
| x: int |
| [out] |
| a.py:2: error: Incompatible types in assignment (expression has type "C", variable has type "P") |
| a.py:2: note: Following member(s) of "C" have conflicts: |
| a.py:2: note: x: expected "str", got "int" |
| == |
| b.py:3: error: "P2" expects no type arguments, but 1 given |
| |
| [case testProtocolToNonProtocol] |
| import a |
| [file a.py] |
| import b, c |
| b.f(c.C()) |
| [file b.py] |
| import d |
| def f(x: d.D) -> None: |
| pass |
| [file c.py] |
| import d |
| class C: |
| x: int |
| [file d.py] |
| from typing import Protocol |
| class D(Protocol): |
| x: int |
| [file d.py.2] |
| class D: |
| x: int |
| [file c.py.3] |
| import d |
| class C(d.D): |
| pass |
| [out] |
| == |
| a.py:2: error: Argument 1 to "f" has incompatible type "C"; expected "D" |
| == |
| |
| [case testNonProtocolToProtocol] |
| import a |
| [file a.py] |
| import b, c |
| b.f(c.C()) |
| [file b.py] |
| import d |
| def f(x: d.D) -> None: |
| pass |
| [file c.py] |
| import d |
| class C(d.D): |
| pass |
| [file d.py] |
| class D: |
| x: int |
| [file d.py.2] |
| from typing import Protocol |
| class D(Protocol): |
| x: int |
| [file c.py.3] |
| import d |
| class C: |
| x: int |
| [out] |
| == |
| a.py:2: error: Cannot instantiate abstract class 'C' with abstract attribute 'x' |
| == |
| |
| [case testInvalidateProtocolViaSuperClass] |
| import a |
| [file a.py] |
| import b, c |
| def func(x: c.P) -> None: |
| pass |
| func(b.B()) |
| [file b.py] |
| class B: |
| x: int |
| y: str |
| [file c.py] |
| from typing import Protocol |
| import d |
| class P(d.PBase, Protocol): |
| x: int |
| [file d.py] |
| from typing import Protocol |
| class PBase(Protocol): |
| y: str |
| [file d.py.2] |
| from typing import Protocol |
| class PBase(Protocol): |
| y: int |
| [out] |
| == |
| a.py:4: error: Argument 1 to "func" has incompatible type "B"; expected "P" |
| a.py:4: note: Following member(s) of "B" have conflicts: |
| a.py:4: note: y: expected "int", got "str" |
| |
| [case testProtocolInvalidateConcreteViaSuperClassUpdateType] |
| import a |
| [file a.py] |
| import b |
| def func(x: b.P) -> None: |
| pass |
| func(b.B()) |
| [file b.py] |
| from typing import Protocol |
| import c |
| class P(Protocol): |
| x: int |
| class B(c.C): |
| pass |
| [file c.py] |
| class C: |
| x: int |
| [file c.py.2] |
| class C: |
| x: str |
| [out] |
| == |
| a.py:4: error: Argument 1 to "func" has incompatible type "B"; expected "P" |
| a.py:4: note: Following member(s) of "B" have conflicts: |
| a.py:4: note: x: expected "int", got "str" |
| |
| [case testProtocolInvalidateConcreteViaSuperClassAddAttr] |
| import a |
| [file a.py] |
| import b |
| def func(x: b.P) -> None: |
| pass |
| bb: b.B |
| func(bb) |
| [file b.py] |
| from typing import Protocol |
| import c |
| class P(Protocol): |
| x: int |
| class B(c.C): |
| pass |
| [file c.py] |
| class C: |
| pass |
| [file c.py.2] |
| class C: |
| x: int |
| [out] |
| a.py:5: error: Argument 1 to "func" has incompatible type "B"; expected "P" |
| == |
| |
| [case testProtocolInvalidateConcreteViaSuperClassRemoveAttr] |
| import a |
| [file a.py] |
| import b |
| def func(x: b.P) -> None: |
| pass |
| func(b.B()) |
| [file b.py] |
| from typing import Protocol |
| import c |
| class P(Protocol): |
| x: int |
| class B(c.C): |
| pass |
| [file c.py] |
| class C: |
| x: int |
| [file c.py.2] |
| class C: |
| pass |
| [out] |
| == |
| a.py:4: error: Argument 1 to "func" has incompatible type "B"; expected "P" |
| |
| [case testTwoProtocolsTwoFilesCrossedUpdateType-only_when_nocache] |
| # this test and the next one (TwoProtocolsTwoFilesCrossedDeleteAttr) has errors ordered |
| # opposite way with and without cache, therefore skip one of each. |
| import a |
| [file a.py] |
| import b1 |
| import b2 |
| [file b1.py] |
| import b2, d |
| from typing import Protocol |
| class P1(Protocol): |
| x: int |
| def f(x: b2.P2) -> None: |
| pass |
| f(d.D()) |
| [file b2.py] |
| import b1, d |
| from typing import Protocol |
| class P2(Protocol): |
| x: int |
| def f(x: b1.P1) -> None: |
| pass |
| f(d.D()) |
| [file d.py] |
| class D: |
| x: int |
| [file d.py.2] |
| class D: |
| x: str |
| [out] |
| == |
| b1.py:7: error: Argument 1 to "f" has incompatible type "D"; expected "P2" |
| b1.py:7: note: Following member(s) of "D" have conflicts: |
| b1.py:7: note: x: expected "int", got "str" |
| b2.py:7: error: Argument 1 to "f" has incompatible type "D"; expected "P1" |
| b2.py:7: note: Following member(s) of "D" have conflicts: |
| b2.py:7: note: x: expected "int", got "str" |
| |
| [case testTwoProtocolsTwoFilesCrossedDeleteAttr-only_when_cache] |
| import a |
| [file a.py] |
| import b1 |
| import b2 |
| [file b1.py] |
| import b2, d |
| from typing import Protocol |
| class P1(Protocol): |
| x: int |
| def f(x: b2.P2) -> None: |
| pass |
| f(d.D()) |
| [file b2.py] |
| import b1, d |
| from typing import Protocol |
| class P2(Protocol): |
| x: int |
| def f(x: b1.P1) -> None: |
| pass |
| f(d.D()) |
| [file d.py] |
| class D: |
| x: int |
| [file d.py.2] |
| class D: |
| y: int |
| [out] |
| b2.py:7: error: Argument 1 to "f" has incompatible type "D"; expected "P2" (diff) |
| b1.py:7: error: Argument 1 to "f" has incompatible type "D"; expected "P1" |
| |
| [case testProtocolsInvalidateByRemovingBase] |
| import a |
| [file a.py] |
| import b |
| def func(x: b.P) -> None: |
| pass |
| func(b.B()) |
| [file b.py] |
| from typing import Protocol |
| import c |
| class P(Protocol): |
| x: int |
| class B(c.C): |
| pass |
| [file c.py] |
| import d |
| class C(d.D): |
| pass |
| [file c.py.2] |
| import d |
| class C: |
| pass |
| [file d.py] |
| class D: |
| x: int |
| [out] |
| == |
| a.py:4: error: Argument 1 to "func" has incompatible type "B"; expected "P" |
| |
| [case testProtocolsInvalidateByRemovingMetaclass] |
| import a |
| [file a.py] |
| import b |
| def func(x: b.P) -> None: |
| pass |
| func(b.B) |
| [file b.py] |
| from typing import Protocol |
| import c |
| class P(Protocol): |
| x: int |
| class B(c.C): |
| pass |
| [file c.py] |
| import d |
| class C(metaclass=d.M): |
| pass |
| [file c.py.2] |
| import d |
| class C: |
| pass |
| [file d.py] |
| class M(type): |
| x: int |
| [out] |
| == |
| a.py:4: error: Argument 1 to "func" has incompatible type "Type[B]"; expected "P" |
| |
| [case testProtocolVsProtocolSubUpdated] |
| import a |
| [file a.py] |
| import b, c |
| x: b.SuperP |
| y: c.SubP |
| x = y |
| [file b.py] |
| from typing import Protocol |
| class SuperP(Protocol): |
| x: int |
| [file c.py] |
| from typing import Protocol |
| import d |
| class SubP(d.PBase, Protocol): |
| y: str |
| [file d.py] |
| from typing import Protocol |
| class PBase(Protocol): |
| x: int |
| [file d.py.2] |
| from typing import Protocol |
| class PBase(Protocol): |
| x: str |
| [out] |
| == |
| a.py:4: error: Incompatible types in assignment (expression has type "SubP", variable has type "SuperP") |
| a.py:4: note: Following member(s) of "SubP" have conflicts: |
| a.py:4: note: x: expected "int", got "str" |
| |
| [case testProtocolVsProtocolSuperUpdated] |
| import a |
| [file a.py] |
| import b, c |
| x: b.SuperP |
| y: c.SubP |
| x = y |
| [file b.py] |
| from typing import Protocol |
| import d |
| class SuperP(d.PBase, Protocol): |
| pass |
| [file c.py] |
| from typing import Protocol |
| class SubP(Protocol): |
| x: int |
| [file d.py] |
| from typing import Protocol |
| class PBase(Protocol): |
| x: int |
| [file d.py.2] |
| from typing import Protocol |
| class PBase(Protocol): |
| y: int |
| [out] |
| == |
| a.py:4: error: Incompatible types in assignment (expression has type "SubP", variable has type "SuperP") |
| |
| [case testProtocolVsProtocolSuperUpdated2] |
| import a |
| [file a.py] |
| import b, c |
| x: b.SuperP |
| y: c.SubP |
| x = y |
| [file b.py] |
| from typing import Protocol |
| import d |
| class SuperP(d.PBase, Protocol): |
| x: int |
| [file c.py] |
| from typing import Protocol |
| class SubP(Protocol): |
| x: int |
| y: int |
| [file d.py] |
| from typing import Protocol |
| class PBase(Protocol): |
| y: int |
| [file d.py.2] |
| from typing import Protocol |
| class PBase(Protocol): |
| y: int |
| z: int |
| [out] |
| == |
| a.py:4: error: Incompatible types in assignment (expression has type "SubP", variable has type "SuperP") |
| a.py:4: note: "SubP" is missing following "SuperP" protocol member: |
| a.py:4: note: z |
| |
| [case testProtocolVsProtocolSuperUpdated3] |
| import a |
| [file a.py] |
| import b, c |
| x: b.SuperP |
| y: c.SubP |
| x = y |
| [file b.py] |
| from typing import Protocol |
| import d |
| class SuperP(d.PBase, Protocol): |
| x: int |
| [file c.py] |
| from typing import Protocol |
| class SubP(Protocol): |
| x: int |
| y: int |
| [file d.py] |
| from typing import Protocol |
| import e |
| class PBase(Protocol): |
| y: int |
| [file d.py.2] |
| from typing import Protocol |
| import e |
| class PBase(e.NewP, Protocol): |
| y: int |
| [file e.py] |
| from typing import Protocol |
| class NewP(Protocol): |
| z: int |
| [out] |
| == |
| a.py:4: error: Incompatible types in assignment (expression has type "SubP", variable has type "SuperP") |
| a.py:4: note: "SubP" is missing following "SuperP" protocol member: |
| a.py:4: note: z |
| |
| [case testProtocolMultipleUpdates] |
| import a |
| [file a.py] |
| import b, c |
| x: b.P = c.C() |
| [file b.py] |
| from typing import Protocol |
| import b2 |
| class P(b2.P2, Protocol): |
| x: int |
| [file b2.py] |
| from typing import Protocol |
| class P2(Protocol): |
| y: int |
| [file c.py] |
| import c2 |
| class C(c2.C2): |
| x: int |
| [file c2.py] |
| class C2: |
| y: int |
| [file b2.py.2] |
| from typing import Protocol |
| class P2(Protocol): |
| y: int |
| z: int |
| [file c2.py.3] |
| class C2: |
| y: int |
| z: int |
| [file c2.py.4] |
| class C2: |
| y: int |
| z: str |
| [out] |
| == |
| a.py:2: error: Incompatible types in assignment (expression has type "C", variable has type "P") |
| a.py:2: note: "C" is missing following "P" protocol member: |
| a.py:2: note: z |
| == |
| == |
| a.py:2: error: Incompatible types in assignment (expression has type "C", variable has type "P") |
| a.py:2: note: Following member(s) of "C" have conflicts: |
| a.py:2: note: z: expected "int", got "str" |
| |
| [case testWeAreCarefulWithBuiltinProtocols] |
| import a |
| x: a.A |
| for i in x: |
| pass |
| [file a.py] |
| from typing import Iterator |
| class A: |
| def __iter__(self) -> Iterator[int]: |
| pass |
| [file a.py.2] |
| class A: |
| pass |
| [out] |
| == |
| main:3: error: "A" has no attribute "__iter__" (not iterable) |
| |
| [case testWeAreCarefullWithBuiltinProtocolsBase] |
| import a |
| x: a.A |
| for i in x: |
| pass |
| [file a.py] |
| import b |
| class A(b.B): |
| pass |
| [file a.py.2] |
| class A: |
| pass |
| [file b.py] |
| from typing import Iterator |
| class B: |
| def __iter__(self) -> Iterator[int]: |
| pass |
| [out] |
| == |
| main:3: error: "A" has no attribute "__iter__" (not iterable) |
| |
| [case testOverloadsSimpleFrom] |
| import a |
| [file a.py] |
| import mod |
| def f() -> None: |
| x: str = mod.f(str()) |
| [file mod.py] |
| from typing import overload |
| @overload |
| def f(x: int) -> None: pass |
| @overload |
| def f(x: str) -> str: pass |
| def f(x): |
| pass |
| [file mod.py.2] |
| from typing import overload |
| @overload |
| def f(x: int) -> None: pass |
| @overload |
| def f(x: str) -> int: pass |
| def f(x): |
| pass |
| [out] |
| == |
| a.py:3: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testOverloadsSimpleToNested] |
| from typing import overload, Any |
| import mod |
| def outer() -> None: |
| @overload |
| def f(x: int) -> None: pass |
| @overload |
| def f(x: str) -> str: pass |
| def f(x: Any) -> Any: |
| y: int = mod.f() |
| [file mod.py] |
| def f() -> int: |
| pass |
| [file mod.py.2] |
| def f() -> str: |
| pass |
| [out] |
| == |
| main:9: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testOverloadsRemovedOverload] |
| import mod |
| def f() -> None: |
| x: str = mod.f(str()) |
| [file mod.py] |
| class C: pass |
| from typing import overload |
| @overload |
| def f(x: int) -> None: pass |
| @overload |
| def f(x: str) -> str: pass |
| @overload |
| def f(x: C) -> int: pass |
| def f(x): |
| pass |
| [file mod.py.2] |
| class C: pass |
| from typing import overload |
| @overload |
| def f(x: int) -> None: pass |
| @overload |
| def f(x: C) -> int: pass |
| def f(x): |
| pass |
| [out] |
| == |
| main:3: error: No overload variant of "f" matches argument type "str" |
| main:3: note: Possible overload variants: |
| main:3: note: def f(x: int) -> None |
| main:3: note: def f(x: C) -> int |
| |
| [case testOverloadsDeleted] |
| import mod |
| def f() -> None: |
| x: str = mod.f(str()) |
| [file mod.py] |
| from typing import overload |
| @overload |
| def f(x: int) -> None: pass |
| @overload |
| def f(x: str) -> str: pass |
| def f(x): |
| pass |
| [file mod.py.2] |
| from typing import overload |
| [builtins fixtures/module.pyi] |
| [out] |
| == |
| main:3: error: Module has no attribute "f" |
| |
| [case testOverloadsUpdatedTypeRecheckImplementation] |
| from typing import overload |
| import mod |
| class Outer: |
| @overload |
| def f(self, x: mod.D) -> mod.D: pass |
| @overload |
| def f(self, x: mod.E) -> mod.E: pass |
| def f(self, x: mod.C) -> mod.C: |
| x.x = int() |
| return x |
| [file mod.py] |
| import submod |
| class C(submod.B): |
| pass |
| class D(C): |
| pass |
| class E(C): |
| pass |
| [file submod.py] |
| import base |
| class B(base.AI): |
| pass |
| [file submod.py.2] |
| import base |
| class B(base.AS): |
| pass |
| [file base.py] |
| class AI: |
| x: int |
| class AS: |
| x: str |
| [out] |
| == |
| main:9: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testOverloadsUpdatedTypeRechekConsistency] |
| from typing import overload |
| import mod |
| class Outer: |
| @overload |
| def f(self, x: mod.D) -> mod.D: pass |
| @overload |
| def f(self, x: mod.E) -> mod.E: pass |
| def f(self, x: mod.C) -> mod.C: |
| pass |
| [file mod.py] |
| class C: |
| pass |
| class D(C): |
| pass |
| class E(C): |
| pass |
| [file mod.py.2] |
| class C: |
| pass |
| class D(C): |
| pass |
| class E: |
| pass |
| [out] |
| == |
| main:8: error: Overloaded function implementation does not accept all possible arguments of signature 2 |
| main:8: error: Overloaded function implementation cannot produce return type of signature 2 |
| |
| [case testOverloadsGenericTypevarUpdated] |
| import a |
| [file a.py] |
| import b |
| b.f(int()) |
| [file b.py] |
| from typing import overload |
| import c |
| class C: pass |
| @overload |
| def f(x: C) -> None: pass |
| @overload |
| def f(x: c.T) -> c.T: pass |
| def f(x): |
| pass |
| [file c.py] |
| from typing import TypeVar |
| T = TypeVar('T', int, str) |
| [file c.py.2] |
| from typing import TypeVar |
| T = TypeVar('T', bound=str) |
| [out] |
| == |
| a.py:2: error: No overload variant of "f" matches argument type "int" |
| a.py:2: note: Possible overload variants: |
| a.py:2: note: def f(x: C) -> None |
| a.py:2: note: def [c.T <: str] f(x: c.T) -> c.T |
| |
| [case testOverloadsGenericToNonGeneric] |
| import a |
| [file a.py] |
| import b |
| b.f(int()) |
| [file b.py] |
| from typing import overload |
| import c |
| class C: pass |
| @overload |
| def f(x: C) -> None: pass |
| @overload |
| def f(x: c.T) -> c.T: pass |
| def f(x): |
| pass |
| [file c.py] |
| from typing import TypeVar |
| T = TypeVar('T', bound=int) |
| [file c.py.2] |
| from typing import TypeVar |
| class T: pass |
| [out] |
| == |
| a.py:2: error: No overload variant of "f" matches argument type "int" |
| a.py:2: note: Possible overload variants: |
| a.py:2: note: def f(x: C) -> None |
| a.py:2: note: def f(x: T) -> T |
| |
| [case testOverloadsToNonOverloaded] |
| import a |
| [file a.py] |
| import mod |
| def f() -> None: |
| x: str = mod.f(str()) |
| [file mod.py] |
| from typing import overload |
| @overload |
| def f(x: int) -> None: pass |
| @overload |
| def f(x: str) -> str: pass |
| def f(x): |
| pass |
| [file mod.py.2] |
| from typing import overload |
| def f(x: int) -> int: |
| pass |
| [out] |
| == |
| a.py:3: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| a.py:3: error: Argument 1 to "f" has incompatible type "str"; expected "int" |
| |
| [case testOverloadsUpdateFunctionToOverloaded] |
| import a |
| [file a.py] |
| import mod |
| def f() -> None: |
| x: str = mod.f(str()) |
| [file mod.py] |
| from typing import overload |
| def f(x: str) -> str: |
| pass |
| [file mod.py.2] |
| from typing import overload |
| @overload |
| def f(x: int) -> None: pass |
| @overload |
| def f(x: str) -> int: pass |
| def f(x): |
| pass |
| [out] |
| == |
| a.py:3: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testOverloadedUpdateToClass] |
| import a |
| [file a.py] |
| import mod |
| def f() -> None: |
| x: str = mod.f(str()) |
| [file mod.py] |
| from typing import overload |
| @overload |
| def f(x: int) -> None: pass |
| @overload |
| def f(x: str) -> str: pass |
| def f(x): |
| pass |
| [file mod.py.2] |
| from typing import overload |
| class f: |
| def __init__(self, x: str) -> None: |
| pass |
| [out] |
| == |
| a.py:3: error: Incompatible types in assignment (expression has type "f", variable has type "str") |
| |
| [case testDepsFromOverloadUpdatedAttrRecheckImpl] |
| import mod |
| x = mod.f |
| [file mod.py] |
| from typing import overload, Any |
| import submod |
| @overload |
| def f(x: int) -> submod.A: pass |
| @overload |
| def f(x: str) -> submod.B: pass |
| def f(x) -> Any: |
| y: submod.C |
| y.x = int() |
| [file submod.py] |
| import other |
| class A: pass |
| class B: pass |
| C = other.C |
| [file other.py] |
| class C: |
| x: int |
| [file other.py.2] |
| class C: |
| x: str |
| [out] |
| == |
| mod.py:9: error: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testOverloadedMethodSupertype] |
| from typing import overload, Any |
| import b |
| class Child(b.Parent): |
| @overload |
| def f(self, arg: int) -> int: ... |
| @overload |
| def f(self, arg: str) -> str: ... |
| def f(self, arg: Any) -> Any: ... |
| [file b.py] |
| from typing import overload, Any |
| class C: pass |
| class Parent: |
| @overload |
| def f(self, arg: int) -> int: ... |
| @overload |
| def f(self, arg: str) -> str: ... |
| def f(self, arg: Any) -> Any: ... |
| [file b.py.2] |
| from typing import overload, Any |
| class C: pass |
| class Parent: |
| @overload |
| def f(self, arg: int) -> int: ... |
| @overload |
| def f(self, arg: str) -> C: ... |
| def f(self, arg: Any) -> Any: ... |
| [out] |
| == |
| main:4: error: Signature of "f" incompatible with supertype "Parent" |
| |
| [case testOverloadedInitSupertype] |
| import a |
| [file a.py] |
| from b import B |
| B(int()) |
| [file b.py] |
| import c |
| class B(c.C): |
| pass |
| [file c.py] |
| from typing import overload |
| class C: |
| def __init__(self, x: int) -> None: |
| pass |
| [file c.py.2] |
| from typing import overload |
| class C: |
| @overload |
| def __init__(self, x: str) -> None: pass |
| @overload |
| def __init__(self, x: str, y: int) -> None: pass |
| def __init__(self, *args, **kwargs) -> None: |
| pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| a.py:2: error: No overload variant of "B" matches argument type "int" |
| a.py:2: note: Possible overload variant: |
| a.py:2: note: def __init__(self, x: str) -> B |
| a.py:2: note: <1 more non-matching overload not shown> |
| |
| [case testOverloadedToNormalMethodMetaclass] |
| import a |
| [file a.py] |
| import b |
| b.B.f(int()) |
| [file b.py] |
| import c |
| class B(metaclass=c.M): |
| pass |
| [file c.py] |
| from typing import overload |
| class M(type): |
| @overload |
| def f(cls, x: str) -> str: pass |
| @overload |
| def f(cls, x: int) -> None: pass |
| def f(cls, x): |
| pass |
| [file c.py.2] |
| from typing import overload |
| class M(type): |
| def f(cls, x: str) -> str: |
| pass |
| [out] |
| == |
| a.py:2: error: Argument 1 to "f" of "M" has incompatible type "int"; expected "str" |
| |
| [case testYieldFrom] |
| from typing import Iterator |
| from a import f |
| |
| def g() -> Iterator[int]: |
| a = "string" |
| if int(): |
| a = yield from f() |
| |
| [file a.py] |
| from typing import Generator |
| |
| def f() -> Generator[int, None, str]: |
| yield 5 |
| return "ham" |
| |
| [file a.py.2] |
| from typing import Generator |
| |
| class A: pass |
| |
| def f() -> Generator[int, None, A]: |
| yield 5 |
| return A() |
| |
| [out] |
| == |
| main:7: error: Incompatible types in assignment (expression has type "A", variable has type "str") |
| |
| [case testFString] |
| from a import g |
| f'{g(1)}' |
| [file a.py] |
| def g(x: int) -> str: pass |
| [file a.py.2] |
| def g(x: str) -> str: pass |
| [builtins fixtures/f_string.pyi] |
| [out] |
| == |
| main:2: error: Argument 1 to "g" has incompatible type "int"; expected "str" |
| |
| [case testExtendedUnpacking-only_when_nocache] |
| from typing import List |
| from a import g |
| def f() -> List[int]: |
| a, *b = g() |
| return b |
| |
| [file a.py] |
| from typing import Tuple |
| def g() -> Tuple[str, int, int]: pass |
| |
| [file a.py.2] |
| from typing import Tuple |
| def g() -> Tuple[str, str]: pass |
| |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| main:5: error: Incompatible return value type (got "List[str]", expected "List[int]") |
| |
| [case testUnpackInExpression1-only_when_nocache] |
| from typing import Tuple, List |
| from a import t |
| |
| def f() -> Tuple[int, int]: |
| return (1, *t()) |
| |
| def g() -> List[int]: |
| return [1, *t()] |
| |
| [file a.py] |
| from typing import Tuple |
| def t() -> Tuple[int]: ... |
| |
| [file a.py.2] |
| from typing import Tuple |
| def t() -> Tuple[str]: ... |
| |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:5: error: Incompatible return value type (got "Tuple[int, str]", expected "Tuple[int, int]") |
| main:8: error: List item 1 has incompatible type "Tuple[str]"; expected "int" |
| |
| [case testUnpackInExpression2-only_when_nocache] |
| from typing import Set |
| from a import t |
| |
| def f() -> Set[int]: |
| return {1, *t()} |
| |
| [file a.py] |
| from typing import Tuple |
| def t() -> Tuple[int]: pass |
| |
| [file a.py.2] |
| from typing import Tuple |
| def t() -> Tuple[str]: pass |
| |
| [builtins fixtures/set.pyi] |
| [out] |
| == |
| main:5: error: Argument 2 to <set> has incompatible type "*Tuple[str]"; expected "int" |
| |
| [case testUnpackInExpression3-only_when_nocache] |
| from typing import Dict |
| from a import d |
| |
| def f() -> Dict[int, str]: |
| return {1: '', **d()} |
| |
| [file a.py] |
| from typing import Dict |
| def d() -> Dict[int, str]: pass |
| |
| [file a.py.2] |
| from typing import Dict |
| def d() -> Dict[int, int]: pass |
| |
| [builtins fixtures/dict.pyi] |
| [out] |
| == |
| main:5: error: Argument 1 to "update" of "dict" has incompatible type "Dict[int, int]"; expected "Mapping[int, str]" |
| |
| [case testAwaitAndAsyncDef-only_when_nocache] |
| from a import g |
| |
| async def f() -> int: |
| return await g() |
| |
| [file a.py] |
| async def g() -> int: |
| return 0 |
| |
| [file a.py.2] |
| async def g() -> str: |
| return '' |
| |
| [builtins fixtures/async_await.pyi] |
| [typing fixtures/typing-async.pyi] |
| [out] |
| == |
| main:4: error: Incompatible return value type (got "str", expected "int") |
| |
| [case testAwaitAnd__await__-only_when_nocache] |
| from a import C |
| |
| async def f(c: C) -> int: |
| return await c |
| |
| [file a.py] |
| from typing import Any, Generator |
| class C: |
| def __await__(self) -> Generator[Any, None, int]: |
| yield |
| return 0 |
| |
| [file a.py.2] |
| from typing import Any, Generator |
| class C: |
| def __await__(self) -> Generator[Any, None, str]: |
| yield |
| return '' |
| |
| [builtins fixtures/async_await.pyi] |
| [typing fixtures/typing-async.pyi] |
| [out] |
| == |
| main:4: error: Incompatible return value type (got "str", expected "int") |
| |
| [case test__aiter__and__anext__] |
| from a import C |
| |
| async def f() -> int: |
| async for x in C(): |
| pass |
| return x |
| |
| [file a.py] |
| class C: |
| def __aiter__(self) -> D: pass |
| class D: |
| def __aiter__(self) -> D: pass |
| async def __anext__(self) -> int: return 0 |
| |
| [file a.py.2] |
| class C: |
| def __aiter__(self) -> D: pass |
| class D: |
| def __aiter__(self) -> D: pass |
| async def __anext__(self) -> str: return '' |
| |
| [file a.py.3] |
| class C: |
| def __aiter__(self) -> E: pass |
| class E: |
| def __aiter__(self) -> E: pass |
| async def __anext__(self) -> object: return 0 |
| |
| [builtins fixtures/async_await.pyi] |
| [typing fixtures/typing-async.pyi] |
| [out] |
| == |
| main:6: error: Incompatible return value type (got "str", expected "int") |
| == |
| main:6: error: Incompatible return value type (got "object", expected "int") |
| |
| [case testAsyncWith2-only_when_nocache] |
| from a import C |
| |
| async def f() -> int: |
| async with C() as x: |
| return x |
| |
| async def g() -> None: |
| async with C(): pass |
| |
| [file a.py] |
| class C: |
| async def __aenter__(self) -> int: pass |
| async def __aexit__(self, x, y, z) -> None: pass |
| |
| [file a.py.2] |
| class C: |
| async def __aenter__(self) -> str: pass |
| async def __aexit__(self, x, y, z) -> None: pass |
| |
| [file a.py.3] |
| from typing import Awaitable |
| class C: |
| async def __aenter__(self) -> int: pass |
| async def __aexit__(self, x, y, z) -> None: pass |
| |
| [file a.py.4] |
| from typing import Awaitable |
| class C: |
| async def __aenter__(self) -> int: pass |
| |
| [builtins fixtures/async_await.pyi] |
| [typing fixtures/typing-async.pyi] |
| [out] |
| == |
| main:5: error: Incompatible return value type (got "str", expected "int") |
| == |
| == |
| main:4: error: "C" has no attribute "__aexit__" |
| main:8: error: "C" has no attribute "__aexit__" |
| |
| [case testLiskovFineVariable] |
| import b |
| class A(b.B): |
| x: str |
| def f(x: b.B) -> None: |
| x.x + int() |
| f(A()) |
| [file b.py] |
| class B: |
| x: str |
| [file b.py.2] |
| class B: |
| x: int |
| [builtins fixtures/primitives.pyi] |
| [out] |
| main:5: error: Unsupported operand types for + ("str" and "int") |
| == |
| main:3: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int") |
| |
| [case testLiskovFineVariableInFunction] |
| from b import B |
| def outer() -> None: |
| class A(B): |
| x: str |
| def f(x: B) -> None: |
| x.x + int() |
| [file b.py] |
| class B: |
| x: str |
| [file b.py.2] |
| class B: |
| x: int |
| [builtins fixtures/primitives.pyi] |
| [out] |
| main:6: error: Unsupported operand types for + ("str" and "int") |
| == |
| main:4: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int") |
| |
| [case testLiskovFineDecorator] |
| import b |
| from c import deco |
| class A(b.B): |
| @deco |
| def m(self) -> str: pass |
| def f(x: b.B) -> None: |
| x.m() + int() |
| f(A()) |
| [file b.py] |
| from c import deco |
| class B: |
| @deco |
| def m(self) -> str: pass |
| [file b.py.2] |
| from c import deco |
| class B: |
| @deco |
| def m(self) -> int: pass |
| [file c.py] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| def deco(f: F) -> F: |
| pass |
| [builtins fixtures/primitives.pyi] |
| [out] |
| main:7: error: Unsupported operand types for + ("str" and "int") |
| == |
| main:5: error: Return type "str" of "m" incompatible with return type "int" in supertype "B" |
| |
| [case testLiskovFineVariableClean-only_when_nocache] |
| import b |
| class A(b.B): |
| x: str |
| [file b.py] |
| class B: |
| x: str |
| [file b.py.2] |
| class B: |
| x: int |
| [out] |
| == |
| main:3: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int") |
| |
| [case testLiskovFineVariableCleanDefInMethod-only_when_nocache] |
| import b |
| class A(b.B): |
| def meth(self) -> None: |
| self.x: str |
| [file b.py] |
| class B: |
| x: str |
| [file b.py.2] |
| class B: |
| x: int |
| [out] |
| == |
| main:4: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int") |
| |
| [case testLiskovFineVariableCleanDefInMethodStar-only_when_nocache] |
| from typing import List |
| import b |
| class A(b.B): |
| def meth(self) -> None: |
| self.x, *self.y = None, None # type: str, List[str] |
| [file b.py] |
| from typing import List |
| class B: |
| y: List[str] |
| [file b.py.2] |
| from typing import List |
| class B: |
| y: List[int] |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:5: error: Incompatible types in assignment (expression has type "List[str]", base class "B" defined the type as "List[int]") |
| |
| [case testLiskovFineVariableCleanDefInMethodNested-only_when_nocache] |
| from b import B |
| def outer() -> None: |
| class A(B): |
| def meth(self) -> None: |
| self.x: str |
| [file b.py] |
| class B: |
| x: str |
| [file b.py.2] |
| class B: |
| x: int |
| [out] |
| == |
| main:5: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int") |
| |
| [case testLiskovFineVariableInFunctionClean-only_when_nocache] |
| from b import B |
| def outer() -> None: |
| class A(B): |
| x: str |
| [file b.py] |
| class B: |
| x: str |
| [file b.py.2] |
| class B: |
| x: int |
| [out] |
| == |
| main:4: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int") |
| |
| [case testLiskovFineDecoratorClean-only_when_nocache] |
| import b |
| from c import deco |
| class A(b.B): |
| @deco |
| def m(self) -> str: pass |
| [file b.py] |
| from c import deco |
| class B: |
| @deco |
| def m(self) -> str: pass |
| [file b.py.2] |
| from c import deco |
| class B: |
| @deco |
| def m(self) -> int: pass |
| [file c.py] |
| from typing import Callable, TypeVar |
| F = TypeVar('F', bound=Callable) |
| def deco(f: F) -> F: |
| pass |
| [out] |
| == |
| main:5: error: Return type "str" of "m" incompatible with return type "int" in supertype "B" |
| |
| [case testAddAbstractMethod] |
| from b import D |
| D() |
| [file b.py] |
| from a import C |
| class D(C): |
| def f(self) -> None: pass |
| [file a.py] |
| from abc import abstractmethod |
| class C: |
| @abstractmethod |
| def f(self) -> None: pass |
| [file a.py.2] |
| from abc import abstractmethod |
| class C: |
| @abstractmethod |
| def f(self) -> None: pass |
| @abstractmethod |
| def g(self) -> None: pass |
| [file a.py.3] |
| from abc import abstractmethod |
| class C: |
| @abstractmethod |
| def f(self) -> None: pass |
| def g(self) -> None: pass |
| [out] |
| == |
| main:2: error: Cannot instantiate abstract class 'D' with abstract attribute 'g' |
| == |
| |
| [case testMakeClassAbstract] |
| from a import C |
| c = C() |
| [file a.py] |
| from abc import abstractmethod |
| class C: pass |
| [file a.py.2] |
| from abc import abstractmethod |
| class C: |
| @abstractmethod |
| def f(self) -> None: pass |
| [out] |
| == |
| main:2: error: Cannot instantiate abstract class 'C' with abstract attribute 'f' |
| |
| [case testMakeMethodNoLongerAbstract1] |
| [file z.py] |
| from abc import abstractmethod, ABCMeta |
| class I(metaclass=ABCMeta): |
| @abstractmethod |
| def f(self) -> None: pass |
| @abstractmethod |
| def g(self) -> None: pass |
| [file b.py] |
| import z |
| def x() -> Foo: return Foo() |
| class Foo(z.I): |
| def f(self) -> None: pass |
| def g(self) -> None: pass |
| |
| [file z.py.2] |
| from abc import abstractmethod, ABCMeta |
| class I(metaclass=ABCMeta): |
| def f(self) -> None: pass |
| @abstractmethod |
| def g(self) -> None: pass |
| |
| [file b.py.2] |
| import z |
| def x() -> Foo: return Foo() |
| class Foo(z.I): |
| def g(self) -> None: pass |
| [out] |
| == |
| |
| [case testMakeMethodNoLongerAbstract2] |
| -- this version never failed, but it is just a file-renaming |
| -- away from the above test that did |
| [file a.py] |
| from abc import abstractmethod, ABCMeta |
| class I(metaclass=ABCMeta): |
| @abstractmethod |
| def f(self) -> None: pass |
| @abstractmethod |
| def g(self) -> None: pass |
| [file b.py] |
| import a |
| def x() -> Foo: return Foo() |
| class Foo(a.I): |
| def f(self) -> None: pass |
| def g(self) -> None: pass |
| |
| [file a.py.2] |
| from abc import abstractmethod, ABCMeta |
| class I(metaclass=ABCMeta): |
| def f(self) -> None: pass |
| @abstractmethod |
| def g(self) -> None: pass |
| |
| [file b.py.2] |
| import a |
| def x() -> Foo: return Foo() |
| class Foo(a.I): |
| def g(self) -> None: pass |
| [out] |
| == |
| |
| [case testImplicitOptionalRefresh1] |
| # flags: --strict-optional |
| from x import f |
| def foo(x: int = None) -> None: |
| f() |
| [file x.py] |
| def f() -> int: return 0 |
| [file x.py.2] |
| def f() -> str: return '0' |
| [out] |
| == |
| |
| [case testRefreshIgnoreErrors1] |
| [file mypy.ini] |
| \[mypy] |
| \[mypy-b] |
| ignore_errors = True |
| [file a.py] |
| y = '1' |
| [file a.py.2] |
| y = 1 |
| [file b.py] |
| from a import y |
| def fu() -> None: |
| 1+'lurr' |
| y |
| [out] |
| == |
| |
| [case testRefreshIgnoreErrors2] |
| [file mypy.ini] |
| \[mypy] |
| \[mypy-b] |
| ignore_errors = True |
| [file b.py] |
| def fu() -> int: |
| 1+'lurr' |
| return 1 |
| [file b.py.2] |
| def fu() -> int: |
| 1+'lurr' |
| return 2 |
| [out] |
| == |
| |
| [case testRefreshOptions] |
| [file mypy.ini] |
| \[mypy] |
| disallow_any_generics = True |
| \[mypy-b] |
| disallow_any_generics = False |
| [file a.py] |
| y = '1' |
| [file a.py.2] |
| y = 1 |
| [file b.py] |
| from typing import List |
| from a import y |
| x = [] # type: List |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| |
| [case testNamedTupleFallbackModule] |
| import b |
| [file b.py] |
| from a import A |
| def f(a: A): |
| pass |
| [file b.py.2] |
| from a import A |
| def f(a: A): |
| reveal_type(a) |
| [file a.py] |
| from typing import NamedTuple |
| |
| F = [('x', int)] |
| A = NamedTuple('A', F) # type: ignore |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| b.py:3: note: Revealed type is 'Tuple[, fallback=a.A]' |
| |
| [case testImportOnTopOfAlias1] |
| from a import A |
| x: A |
| [file a.py] |
| from typing import TypeVar, List |
| T = TypeVar('T') |
| A = List[T] |
| [file a.py.2] |
| from typing import TypeVar, List |
| T = TypeVar('T') |
| A = List[T] |
| from b import A |
| [file b.py] |
| # empty |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| a.py:4: error: Module 'b' has no attribute 'A' |
| a.py:4: error: Name 'A' already defined on line 3 |
| |
| -- the order of errors is different with cache |
| [case testImportOnTopOfAlias2] |
| from a import A |
| x: A |
| [file a.py] |
| from typing import TypeVar, List |
| T = TypeVar('T') |
| A = List[T] |
| [file a.py.2] |
| from typing import TypeVar, List |
| T = TypeVar('T') |
| A = List[T] |
| from b import A as A |
| [file b.py] |
| def A(x: str) -> str: pass |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| a.py:4: error: Incompatible import of "A" (imported name has type "Callable[[str], str]", local name has type "Type[List[Any]]") |
| |
| [case testFakeOverloadCrash] |
| import b |
| [file a.py] |
| def dec(fun): |
| pass |
| a = 1 |
| [file a.py.2] |
| def dec(fun): |
| pass |
| a = 2 |
| [file b.py] |
| from a import dec |
| @dec |
| def a(): |
| pass |
| @dec |
| def a(): |
| pass |
| [out] |
| b.py:5: error: Name 'a' already defined on line 2 |
| == |
| b.py:5: error: Name 'a' already defined on line 2 |
| |
| [case testFakeOverloadCrash2] |
| |
| # this test just should not crash |
| import a |
| [file a.py] |
| T = TypeVar("T") |
| |
| def foo(func): |
| return func |
| |
| @foo |
| def bar(x: T) -> T: |
| pass |
| |
| @foo |
| def bar(x: T) -> T: |
| pass |
| [file a.py.2] |
| T = TypeVar("T") |
| |
| def foo(func): |
| return func |
| |
| @foo |
| def bar(x: T) -> T: |
| pass |
| |
| @foo |
| def bar(x: T) -> T: |
| pass |
| x = 1 |
| [out] |
| a.py:1: error: Name 'TypeVar' is not defined |
| a.py:1: note: Did you forget to import it from "typing"? (Suggestion: "from typing import TypeVar") |
| a.py:7: error: Variable "a.T" is not valid as a type |
| a.py:7: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases |
| a.py:10: error: Name 'bar' already defined on line 6 |
| a.py:11: error: Variable "a.T" is not valid as a type |
| a.py:11: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases |
| == |
| a.py:1: error: Name 'TypeVar' is not defined |
| a.py:1: note: Did you forget to import it from "typing"? (Suggestion: "from typing import TypeVar") |
| a.py:7: error: Variable "a.T" is not valid as a type |
| a.py:7: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases |
| a.py:10: error: Name 'bar' already defined on line 6 |
| a.py:11: error: Variable "a.T" is not valid as a type |
| a.py:11: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases |
| |
| [case testRefreshForWithTypeComment1] |
| [file a.py] |
| from typing import List |
| import b |
| def foo(l: List[int]) -> None: |
| for x in l: # type: object |
| pass |
| x = object() |
| b.x |
| [file b.py] |
| x = 1 |
| [file b.py.2] |
| x = '1' |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| |
| [case testRefreshForWithTypeComment2] |
| from typing import List, Any |
| import m |
| def f(x: List[Any]) -> None: |
| for a in x: # type: m.A |
| pass |
| [file m.py] |
| class A: pass |
| [file m.py.2] |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| main:4: error: Name 'm.A' is not defined |
| |
| [case testIdLikeDecoForwardCrash] |
| import b |
| [file b.py] |
| from typing import Callable, Any, TypeVar |
| |
| F = TypeVar('F_BadName', bound=Callable[..., Any]) # type: ignore |
| def deco(func: F) -> F: # type: ignore |
| pass |
| |
| @deco |
| def test(x: int, y: int) -> str: |
| pass |
| [file b.py.2] |
| from typing import Callable, Any, TypeVar |
| |
| F = TypeVar('F_BadName', bound=Callable[..., Any]) # type: ignore |
| def deco(func: F) -> F: # type: ignore |
| pass |
| |
| @deco |
| def test(x: int, y: int) -> str: |
| pass |
| x = 1 |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| |
| [case testIdLikeDecoForwardCrashAlias] |
| import b |
| [file b.py] |
| from typing import Callable, Any, TypeVar |
| |
| F = TypeVar('F', bound=Func) |
| def deco(func: F) -> F: |
| pass |
| |
| @deco |
| def test(x: int, y: int) -> str: |
| pass |
| Func = Callable[..., Any] |
| [file b.py.2] |
| from typing import Callable, Any, TypeVar |
| |
| F = TypeVar('F', bound=Func) |
| def deco(func: F) -> F: |
| pass |
| |
| @deco |
| def test(x: int, y: int) -> str: |
| pass |
| x = 1 |
| Func = Callable[..., Any] |
| [out] |
| == |
| |
| [case testIdLikeDecoForwardCrash_python2] |
| # flags: --py2 |
| import b |
| [file b.py] |
| from typing import Callable, Any, TypeVar |
| |
| F = TypeVar('F_BadName', bound=Callable[..., Any]) # type: ignore |
| def deco(func): # type: ignore |
| # type: (F) -> F |
| pass |
| |
| @deco |
| def test(x, y): |
| # type: (int, int) -> str |
| pass |
| [file b.py.2] |
| from typing import Callable, Any, TypeVar |
| |
| F = TypeVar('F_BadName', bound=Callable[..., Any]) # type: ignore |
| def deco(func): # type: ignore |
| # type: (F) -> F |
| pass |
| |
| @deco |
| def test(x, y): |
| # type: (int, int) -> str |
| pass |
| x = 1 |
| [out] |
| == |
| |
| [case testIdLikeDecoForwardCrashAlias_python2] |
| # flags: --py2 |
| import b |
| [file b.py] |
| from typing import Callable, Any, TypeVar |
| |
| F = TypeVar('F', bound=Func) |
| def deco(func): |
| # type: (F) -> F |
| pass |
| |
| @deco |
| def test(x, y): |
| # type: (int, int) -> str |
| pass |
| Func = Callable[..., Any] |
| [file b.py.2] |
| from typing import Callable, Any, TypeVar |
| |
| F = TypeVar('F', bound=Func) |
| def deco(func): |
| # type: (F) -> F |
| pass |
| |
| @deco |
| def test(x, y): |
| # type: (int, int) -> str |
| pass |
| x = 1 |
| Func = Callable[..., Any] |
| [out] |
| == |
| |
| -- Test cases for final qualifier |
| |
| [case testFinalAddFinalVarAssignFine] |
| import mod |
| from a import D |
| from mod import x |
| |
| x = 2 |
| def outer() -> None: |
| mod.x = 2 |
| x = 2 # This is OK because it creates a local variable |
| d: D |
| d.y = 2 |
| d.z = 2 |
| D.y = 2 |
| [file a.py] |
| import mod |
| |
| class D(mod.C): |
| pass |
| [file mod.py] |
| x = 1 |
| class C: |
| y = 1 |
| def __init__(self) -> None: |
| self.z = 1 |
| |
| [file mod.py.2] |
| from typing import Final |
| |
| x: Final = 1 |
| class C: |
| y: Final = 1 |
| def __init__(self) -> None: |
| self.z: Final = 1 |
| [out] |
| == |
| main:5: error: Cannot assign to final name "x" |
| main:7: error: Cannot assign to final name "x" |
| main:10: error: Cannot assign to final attribute "y" |
| main:11: error: Cannot assign to final attribute "z" |
| main:12: error: Cannot assign to final attribute "y" |
| |
| [case testFinalAddFinalVarOverrideFine] |
| from mod import C |
| |
| class D(C): |
| x = 2 |
| def __init__(self) -> None: |
| self.y = 2 |
| class E(C): |
| y = 2 |
| def __init__(self) -> None: |
| self.x = 2 |
| |
| [file mod.py] |
| class C: |
| x = 1 |
| def __init__(self) -> None: |
| self.y = 1 |
| |
| [file mod.py.2] |
| from typing import Final |
| |
| class C: |
| x: Final = 1 |
| def __init__(self) -> None: |
| self.y: Final = 1 |
| [out] |
| == |
| main:4: error: Cannot assign to final name "x" |
| main:6: error: Cannot assign to final attribute "y" |
| main:8: error: Cannot assign to final name "y" |
| main:10: error: Cannot assign to final attribute "x" |
| |
| [case testFinalAddFinalMethodOverrideFine] |
| from mod import C |
| |
| class D(C): |
| def meth(self) -> int: ... |
| |
| [file mod.py] |
| class C: |
| def meth(self) -> int: ... |
| |
| [file mod.py.2] |
| from typing import final |
| |
| class C: |
| @final |
| def meth(self) -> int: ... |
| [out] |
| == |
| main:4: error: Cannot override final attribute "meth" (previously declared in base class "C") |
| |
| [case testFinalAddFinalMethodOverrideWithVarFine] |
| from mod import C |
| from typing import Any |
| |
| class D(C): |
| meth: Any = 2 |
| def __init__(self) -> None: |
| self.other: Any = 2 |
| |
| [file mod.py] |
| class C: |
| def meth(self) -> int: ... |
| def other(self) -> int: ... |
| |
| [file mod.py.2] |
| from typing import final |
| |
| class C: |
| @final |
| def meth(self) -> int: ... |
| @final |
| def other(self) -> int: ... |
| [out] |
| == |
| main:5: error: Cannot override final attribute "meth" (previously declared in base class "C") |
| main:7: error: Cannot assign to final attribute "other" |
| main:7: error: Cannot override final attribute "other" (previously declared in base class "C") |
| |
| [case testFinalAddFinalMethodOverrideOverloadFine] |
| from typing import overload |
| from mod import C |
| |
| def outer() -> None: |
| class D(C): |
| @overload |
| def meth(self, x: int) -> int: ... |
| @overload |
| def meth(self, x: str) -> str: ... |
| def meth(self, x): |
| pass |
| |
| [file mod.pyi] |
| from typing import overload |
| class C: |
| @overload |
| def meth(self, x: int) -> int: ... |
| @overload |
| def meth(self, x: str) -> str: ... |
| |
| [file mod.pyi.2] |
| from typing import final, overload |
| |
| class C: |
| @final |
| @overload |
| def meth(self, x: int) -> int: ... |
| @overload |
| def meth(self, x: str) -> str: ... |
| [out] |
| == |
| main:6: error: Cannot override final attribute "meth" (previously declared in base class "C") |
| |
| [case testFinalAddFinalPropertyWithVarFine] |
| from mod import C |
| |
| def outer() -> None: |
| class D(C): |
| p = 2 |
| class E(C): |
| def __init__(self) -> None: |
| self.p: int = 2 |
| |
| [file mod.py] |
| class C: |
| @property |
| def p(self) -> int: |
| pass |
| |
| [file mod.py.2] |
| from typing import final |
| |
| class C: |
| @final |
| @property |
| def p(self) -> int: |
| pass |
| [builtins fixtures/property.pyi] |
| [out] |
| == |
| main:5: error: Cannot override final attribute "p" (previously declared in base class "C") |
| main:8: error: Cannot assign to final attribute "p" |
| main:8: error: Cannot override final attribute "p" (previously declared in base class "C") |
| |
| [case testFinalBodyReprocessedAndStillFinal] |
| import a |
| [file a.py] |
| from c import C |
| class A: |
| def meth(self) -> None: ... |
| |
| [file a.py.3] |
| from c import C |
| class A(C): |
| def meth(self) -> None: ... |
| |
| [file c.py] |
| from typing import final |
| from d import D |
| |
| class C: |
| @final |
| def meth(self) -> None: |
| D(int()) |
| [file d.py] |
| class D: |
| def __init__(self, x: int) -> None: ... |
| [file d.py.2] |
| from typing import Optional |
| class D: |
| def __init__(self, x: Optional[int]) -> None: ... |
| [out] |
| == |
| == |
| a.py:3: error: Cannot override final attribute "meth" (previously declared in base class "C") |
| |
| [case testFinalBodyReprocessedAndStillFinalOverloaded] |
| import a |
| [file a.py] |
| from c import C |
| class A: |
| def meth(self) -> None: ... |
| |
| [file a.py.3] |
| from c import C |
| class A(C): |
| def meth(self) -> None: ... |
| |
| [file c.py] |
| from typing import final, overload, Union |
| from d import D |
| |
| class C: |
| @overload |
| def meth(self, x: int) -> int: ... |
| @overload |
| def meth(self, x: str) -> str: ... |
| @final |
| def meth(self, x: Union[int, str]) -> Union[int, str]: |
| D(int()) |
| return x |
| [file d.py] |
| class D: |
| def __init__(self, x: int) -> None: ... |
| [file d.py.2] |
| from typing import Optional |
| class D: |
| def __init__(self, x: Optional[int]) -> None: ... |
| [out] |
| == |
| == |
| a.py:3: error: Cannot override final attribute "meth" (previously declared in base class "C") |
| a.py:3: error: Signature of "meth" incompatible with supertype "C" |
| |
| [case testIfMypyUnreachableClass] |
| from a import x |
| |
| MYPY = False |
| if MYPY: |
| pass |
| else: |
| class A: |
| pass |
| y: int = x |
| [file a.py] |
| x = 1 |
| [file a.py.2] |
| x = 2 |
| [builtins fixtures/bool.pyi] |
| [out] |
| == |
| |
| [case testIfTypeCheckingUnreachableClass] |
| from a import x |
| from typing import TYPE_CHECKING |
| |
| if not TYPE_CHECKING: |
| class A(int): |
| pass |
| else: |
| A = int |
| |
| y: A = x |
| [file a.py] |
| x = 1 |
| [file a.py.2] |
| x = 2 |
| [file a.py.3] |
| x = 'no way' |
| [builtins fixtures/bool.pyi] |
| [typing fixtures/typing-medium.pyi] |
| [out] |
| == |
| == |
| main:10: error: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testNamedTupleForwardFunctionDirect] |
| # flags: --ignore-missing-imports |
| from typing import NamedTuple |
| from b import B |
| |
| NT = NamedTuple('NT', [('x', B)]) |
| [file b.py.2] |
| def func(x): pass |
| B = func |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| main:5: error: Variable "b.B" is not valid as a type |
| main:5: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases |
| |
| [case testNamedTupleForwardFunctionIndirect] |
| # flags: --ignore-missing-imports |
| from typing import NamedTuple |
| from a import A |
| |
| NT = NamedTuple('NT', [('x', A)]) |
| [file a.py] |
| from b import B |
| A = B |
| [file b.py.2] |
| def func(x): pass |
| B = func |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| main:5: error: Variable "a.A" is not valid as a type |
| main:5: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases |
| |
| [case testNamedTupleForwardFunctionIndirectReveal] |
| # flags: --ignore-missing-imports |
| import m |
| [file m.py] |
| from typing import NamedTuple |
| from a import A |
| |
| NT = NamedTuple('NT', [('x', A)]) |
| [file m.py.3] |
| from typing import NamedTuple |
| from a import A |
| |
| NT = NamedTuple('NT', [('x', A)]) |
| reveal_type(NT.x) |
| x: NT |
| reveal_type(x.x) |
| [file a.py] |
| from b import B |
| A = B |
| [file b.py.2] |
| def func(x): pass |
| B = func |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| m.py:4: error: Variable "a.A" is not valid as a type |
| m.py:4: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases |
| == |
| m.py:4: error: Variable "a.A" is not valid as a type |
| m.py:4: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases |
| m.py:5: note: Revealed type is 'Any' |
| m.py:7: note: Revealed type is 'Any' |
| |
| [case testAliasForwardFunctionDirect] |
| # flags: --ignore-missing-imports |
| from typing import Optional |
| from b import B |
| |
| Alias = Optional[B] |
| [file b.py.2] |
| def func(x): pass |
| B = int() |
| [out] |
| == |
| main:5: error: Variable "b.B" is not valid as a type |
| main:5: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases |
| |
| [case testAliasForwardFunctionIndirect] |
| # flags: --ignore-missing-imports |
| from typing import Optional |
| from a import A |
| |
| Alias = Optional[A] |
| [file a.py] |
| from b import B |
| A = B |
| [file b.py.2] |
| def func(x): pass |
| B = func |
| [out] |
| == |
| main:5: error: Variable "a.A" is not valid as a type |
| main:5: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases |
| |
| [case testLiteralFineGrainedVarConversion] |
| import mod |
| reveal_type(mod.x) |
| [file mod.py] |
| x = 1 |
| [file mod.py.2] |
| from typing_extensions import Literal |
| x: Literal[1] = 1 |
| [file mod.py.3] |
| from typing_extensions import Literal |
| x: Literal[1] = 2 |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:2: note: Revealed type is 'builtins.int' |
| == |
| main:2: note: Revealed type is 'Literal[1]' |
| == |
| mod.py:2: error: Incompatible types in assignment (expression has type "Literal[2]", variable has type "Literal[1]") |
| main:2: note: Revealed type is 'Literal[1]' |
| |
| [case testLiteralFineGrainedFunctionConversion] |
| from mod import foo |
| foo(3) |
| [file mod.py] |
| def foo(x: int) -> None: pass |
| [file mod.py.2] |
| from typing_extensions import Literal |
| def foo(x: Literal[3]) -> None: pass |
| [file mod.py.3] |
| from typing_extensions import Literal |
| def foo(x: Literal[4]) -> None: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| == |
| main:2: error: Argument 1 to "foo" has incompatible type "Literal[3]"; expected "Literal[4]" |
| |
| [case testLiteralFineGrainedAlias] |
| from mod import Alias |
| a: Alias = 1 |
| [file mod.py] |
| Alias = int |
| [file mod.py.2] |
| from typing_extensions import Literal |
| Alias = Literal[1] |
| [file mod.py.3] |
| from typing_extensions import Literal |
| Alias = Literal[2] |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| == |
| main:2: error: Incompatible types in assignment (expression has type "Literal[1]", variable has type "Literal[2]") |
| |
| [case testLiteralFineGrainedOverload] |
| from mod import foo |
| reveal_type(foo(4)) |
| [file mod.py] |
| from typing import overload |
| from typing_extensions import Literal |
| @overload |
| def foo(x: int) -> str: ... |
| @overload |
| def foo(x: Literal['bar']) -> int: ... |
| def foo(x): pass |
| [file mod.py.2] |
| from typing import overload |
| from typing_extensions import Literal |
| @overload |
| def foo(x: Literal[4]) -> Literal['foo']: ... |
| @overload |
| def foo(x: int) -> str: ... |
| @overload |
| def foo(x: Literal['bar']) -> int: ... |
| def foo(x): pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:2: note: Revealed type is 'builtins.str' |
| == |
| main:2: note: Revealed type is 'Literal['foo']' |
| |
| [case testLiteralFineGrainedChainedDefinitions] |
| from mod1 import foo |
| from typing_extensions import Literal |
| def expect_3(x: Literal[3]) -> None: pass |
| expect_3(foo) |
| [file mod1.py] |
| from mod2 import bar |
| foo = bar |
| [file mod2.py] |
| from mod3 import qux as bar |
| [file mod3.py] |
| from typing_extensions import Literal |
| qux: Literal[3] |
| [file mod3.py.2] |
| from typing_extensions import Literal |
| qux: Literal[4] |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| main:4: error: Argument 1 to "expect_3" has incompatible type "Literal[4]"; expected "Literal[3]" |
| |
| [case testLiteralFineGrainedChainedAliases] |
| from mod1 import Alias1 |
| from typing_extensions import Literal |
| x: Alias1 |
| def expect_3(x: Literal[3]) -> None: pass |
| expect_3(x) |
| [file mod1.py] |
| from mod2 import Alias2 |
| Alias1 = Alias2 |
| [file mod2.py] |
| from mod3 import Alias3 |
| Alias2 = Alias3 |
| [file mod3.py] |
| from typing_extensions import Literal |
| Alias3 = Literal[3] |
| [file mod3.py.2] |
| from typing_extensions import Literal |
| Alias3 = Literal[4] |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| main:5: error: Argument 1 to "expect_3" has incompatible type "Literal[4]"; expected "Literal[3]" |
| |
| [case testLiteralFineGrainedChainedFunctionDefinitions] |
| from mod1 import func1 |
| from typing_extensions import Literal |
| def expect_3(x: Literal[3]) -> None: pass |
| expect_3(func1()) |
| [file mod1.py] |
| from mod2 import func2 as func1 |
| [file mod2.py] |
| from mod3 import func3 |
| func2 = func3 |
| [file mod3.py] |
| from typing_extensions import Literal |
| def func3() -> Literal[3]: pass |
| [file mod3.py.2] |
| from typing_extensions import Literal |
| def func3() -> Literal[4]: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| main:4: error: Argument 1 to "expect_3" has incompatible type "Literal[4]"; expected "Literal[3]" |
| |
| [case testLiteralFineGrainedChainedTypeVarInference] |
| from mod1 import foo |
| reveal_type(foo) |
| [file mod1.py] |
| from typing import TypeVar |
| from mod2 import bar |
| T = TypeVar('T', bound=int) |
| def func(x: T) -> T: return x |
| foo = func(bar) |
| [file mod2.py] |
| bar = 3 |
| [file mod2.py.2] |
| from typing_extensions import Literal |
| bar: Literal[3] = 3 |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:2: note: Revealed type is 'builtins.int*' |
| == |
| main:2: note: Revealed type is 'Literal[3]' |
| |
| [case testLiteralFineGrainedChainedViaFinal] |
| from mod1 import foo |
| from typing_extensions import Literal |
| def expect_3(x: Literal[3]) -> None: pass |
| expect_3(foo) |
| [file mod1.py] |
| from typing_extensions import Final |
| from mod2 import bar |
| foo: Final = bar |
| [file mod2.py] |
| from mod3 import qux as bar |
| [file mod3.py] |
| from typing_extensions import Final |
| qux: Final = 3 |
| [file mod3.py.2] |
| from typing_extensions import Final |
| qux: Final = 4 |
| [file mod3.py.3] |
| from typing_extensions import Final |
| qux: Final[int] = 4 |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| main:4: error: Argument 1 to "expect_3" has incompatible type "Literal[4]"; expected "Literal[3]" |
| == |
| main:4: error: Argument 1 to "expect_3" has incompatible type "int"; expected "Literal[3]" |
| |
| [case testLiteralFineGrainedStringConversionPython3] |
| from mod1 import foo |
| reveal_type(foo) |
| [file mod1.py] |
| from mod2 import bar |
| foo = bar() |
| [file mod2.py] |
| from typing_extensions import Literal |
| def bar() -> Literal["foo"]: pass |
| [file mod2.py.2] |
| from typing_extensions import Literal |
| def bar() -> Literal[u"foo"]: pass |
| [file mod2.py.3] |
| from typing_extensions import Literal |
| def bar() -> Literal[b"foo"]: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:2: note: Revealed type is 'Literal['foo']' |
| == |
| main:2: note: Revealed type is 'Literal['foo']' |
| == |
| main:2: note: Revealed type is 'Literal[b'foo']' |
| |
| [case testLiteralFineGrainedStringConversionPython2] |
| # flags: --python-version 2.7 |
| from mod1 import foo |
| reveal_type(foo) |
| [file mod1.py] |
| from mod2 import bar |
| foo = bar() |
| [file mod2.py] |
| from typing_extensions import Literal |
| def bar(): |
| # type: () -> Literal["foo"] |
| pass |
| [file mod2.py.2] |
| from typing_extensions import Literal |
| def bar(): |
| # type: () -> Literal[b"foo"] |
| pass |
| [file mod2.py.3] |
| from __future__ import unicode_literals |
| from typing_extensions import Literal |
| def bar(): |
| # type: () -> Literal["foo"] |
| pass |
| [file mod2.py.4] |
| from __future__ import unicode_literals |
| from typing_extensions import Literal |
| def bar(): |
| # type: () -> Literal[b"foo"] |
| pass |
| [file mod2.py.5] |
| from typing_extensions import Literal |
| def bar(): |
| # type: () -> Literal[u"foo"] |
| pass |
| [out] |
| main:3: note: Revealed type is 'Literal['foo']' |
| == |
| main:3: note: Revealed type is 'Literal['foo']' |
| == |
| main:3: note: Revealed type is 'Literal[u'foo']' |
| == |
| main:3: note: Revealed type is 'Literal['foo']' |
| == |
| main:3: note: Revealed type is 'Literal[u'foo']' |
| |
| [case testReprocessModuleTopLevelWhileMethodDefinesAttr] |
| import a |
| [file a.py] |
| from b import B |
| |
| B().x |
| |
| [file a.py.3] |
| from b import B |
| |
| x = B().x |
| |
| [file b.py] |
| from c import f |
| f(int()) |
| |
| class B: |
| def meth(self) -> None: |
| self.x: int |
| |
| [file c.py] |
| def f(x: int) -> None: ... |
| |
| [file c.py.2] |
| from typing import Union |
| def f(x: Union[int, str]) -> None: ... |
| |
| [targets2 c, b] |
| [targets3 a] |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| == |
| |
| [case testCheckReprocessedTargets-only_when_nocache] |
| from b import B |
| |
| class C(B): |
| def meth(self) -> None: |
| from b import f |
| f() |
| |
| [file b.py] |
| class B: ... |
| def f() -> int: ... |
| |
| [file b.py.2] |
| class A: ... |
| class B(A): ... |
| def f() -> int: ... |
| |
| [file b.py.3] |
| class A: ... |
| class B(A): ... |
| def f() -> str: ... |
| |
| [targets2 b, __main__, __main__.C.meth, __main__, __main__.C.meth] |
| [targets3 b, __main__.C.meth] |
| [out] |
| == |
| == |
| |
| [case testReprocessModuleTopLevelWhileMethodDefinesAttrExplicit] |
| import a |
| [file a.py] |
| from b import B |
| |
| B().x |
| |
| [file b.py] |
| from c import f |
| f(int()) |
| |
| class A: |
| x: int |
| |
| class B(A): |
| def meth(self) -> None: |
| self.x: int |
| |
| [file c.py] |
| def f(x: int) -> None: ... |
| |
| [file c.py.2] |
| from typing import Union |
| def f(x: Union[int, str]) -> None: ... |
| |
| [file a.py.3] |
| from b import B |
| |
| # Double-check the variable is still accessible. |
| B().x |
| |
| [targets2 c, b] |
| [targets3 a] |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| == |
| |
| [case testReprocessModuleTopLevelWhileMethodDefinesAttrBothExplicitAndInClass] |
| import a |
| [file a.py] |
| from b import B |
| |
| B().x |
| |
| [file b.py] |
| from c import f |
| f(int()) |
| |
| class A: |
| x: int |
| |
| class B(A): |
| x: int |
| def meth(self) -> None: |
| self.x: int |
| |
| [file c.py] |
| def f(x: int) -> None: ... |
| |
| [file c.py.2] |
| from typing import Union |
| def f(x: Union[int, str]) -> None: ... |
| |
| [file a.py.3] |
| from b import B |
| |
| # Double-check the variable is still accessible. |
| B().x |
| |
| [targets2 c, b] |
| [targets3 a] |
| [builtins fixtures/tuple.pyi] |
| [out] |
| == |
| == |
| |
| [case testReprocessModuleTopLevelWhileMethodDefinesAttrProtocol] |
| import a |
| [file a.py] |
| from b import B |
| |
| B().x |
| |
| [file b.py] |
| from typing import Protocol |
| from c import f |
| f(int()) |
| |
| class A(Protocol): |
| x: int |
| |
| class B(A): |
| def meth(self) -> None: |
| self.x = 42 |
| |
| [file c.py] |
| def f(x: int) -> None: ... |
| |
| [file c.py.2] |
| from typing import Union |
| def f(x: Union[int, str]) -> None: ... |
| |
| [file a.py.3] |
| from b import B |
| |
| # Double-check the variable is still accessible. |
| B().x |
| |
| [targets2 c, b] |
| [targets3 a] |
| [out] |
| == |
| == |
| |
| [case testNewSemanticAnalyzerUpdateMethodAndClass] |
| |
| import m |
| |
| m.x |
| |
| class A: |
| def f(self) -> None: |
| self.x = 0 |
| m.y |
| |
| def g(self) -> None: |
| m.x |
| |
| [file m.py] |
| x = 0 |
| y = 0 |
| |
| [file m.py.2] |
| x = '' |
| y = 0 |
| |
| [file m.py.3] |
| x = '' |
| y = '' |
| |
| [out] |
| == |
| == |
| |
| [case testInlineConfigFineGrained1] |
| |
| import a |
| [file a.py] |
| # mypy: no-warn-no-return |
| |
| from typing import List |
| def foo() -> List: |
| 20 |
| |
| [file a.py.2] |
| # mypy: disallow-any-generics, no-warn-no-return |
| |
| from typing import List |
| def foo() -> List: |
| 20 |
| |
| [file a.py.3] |
| # mypy: no-warn-no-return |
| |
| from typing import List |
| def foo() -> List: |
| 20 |
| |
| [file a.py.4] |
| from typing import List |
| def foo() -> List: |
| 20 |
| [out] |
| == |
| a.py:4: error: Missing type parameters for generic type "List" |
| == |
| == |
| a.py:2: error: Missing return statement |
| |
| [builtins fixtures/list.pyi] |
| |
| [case testInlineConfigFineGrained2] |
| import a |
| [file a.py] |
| # mypy: bogus-flag |
| |
| [file b.py.2] |
| |
| [out] |
| a.py:1: error: Unrecognized option: bogus_flag = True |
| == |
| a.py:1: error: Unrecognized option: bogus_flag = True |
| |
| [case testWrongNumberOfArguments] |
| |
| [file a.py] |
| def bar(x): |
| # type: () -> None |
| pass |
| |
| def baz(x): |
| # type: () -> None |
| pass |
| |
| def f(): |
| # type: () -> None |
| def g(x): |
| # type: () -> None |
| pass |
| |
| [file c.py] |
| def bar(x): |
| # type: () -> None |
| pass |
| |
| [file b.py] |
| x = '' |
| |
| [file b.py.2] |
| x = 1 |
| |
| [out] |
| c.py:1: error: Type signature has too few arguments |
| a.py:1: error: Type signature has too few arguments |
| a.py:5: error: Type signature has too few arguments |
| a.py:11: error: Type signature has too few arguments |
| == |
| a.py:1: error: Type signature has too few arguments |
| a.py:5: error: Type signature has too few arguments |
| a.py:11: error: Type signature has too few arguments |
| c.py:1: error: Type signature has too few arguments |
| |
| [case testErrorReportingNewAnalyzer] |
| # flags: --disallow-any-generics |
| from a import A |
| |
| def f() -> None: |
| x: A |
| [file a.py] |
| class A: ... |
| |
| [file a.py.2] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class A(Generic[T]): ... |
| [out] |
| == |
| main:5: error: Missing type parameters for generic type "A" |
| |
| [case testStripNewAnalyzer] |
| # flags: --ignore-missing-imports |
| import a |
| [file a.py] |
| from typing import List |
| from b import B |
| |
| class A: |
| def __init__(self) -> None: |
| self.x: List[int] = [] |
| |
| def method(self) -> None: |
| B() |
| self.x = [] |
| |
| [file b.py] |
| class B: ... |
| [delete b.py.2] |
| |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| |
| [case testClassVariableOrderingRefresh] |
| |
| from b import bar |
| |
| def foo(x: str) -> None: pass |
| |
| class Something: |
| def run(self) -> None: |
| bar() |
| foo(self.IDS[0]) |
| |
| IDS = [87] |
| |
| [file b.py] |
| def bar() -> int: return 0 |
| [file b.py.2] |
| def bar() -> str: return '0' |
| [builtins fixtures/list.pyi] |
| [out] |
| main:9: error: Argument 1 to "foo" has incompatible type "int"; expected "str" |
| == |
| main:9: error: Argument 1 to "foo" has incompatible type "int"; expected "str" |
| |
| [case testInfiniteLoop] |
| |
| [file a.py] |
| from b import f |
| from typing import Callable, TypeVar |
| |
| F = TypeVar('F', bound=Callable) |
| def dec(x: F) -> F: return x |
| |
| @dec |
| def foo(self): |
| class A: |
| @classmethod |
| def asdf(cls, x: 'A') -> None: pass |
| |
| @dec |
| def bar(self): |
| class B: |
| @classmethod |
| def asdf(cls, x: 'B') -> None: pass |
| f() |
| |
| [file b.py] |
| def f() -> int: pass |
| [file b.py.2] |
| def f() -> str: pass |
| [builtins fixtures/classmethod.pyi] |
| [out] |
| == |
| |
| [case testInfiniteLoop2] |
| |
| [file a.py] |
| from b import f |
| from typing import Callable, TypeVar, NamedTuple |
| |
| F = TypeVar('F', bound=Callable) |
| def dec(x: F) -> F: return x |
| |
| @dec |
| def foo(self): |
| N = NamedTuple('N', [('x', int)]) |
| def g(x: N) -> None: pass |
| |
| @dec |
| def bar(self): |
| N = NamedTuple('N', [('x', int)]) |
| def g(x: N) -> None: pass |
| f() |
| |
| [file b.py] |
| def f() -> int: pass |
| [file b.py.2] |
| def f() -> str: pass |
| [builtins fixtures/classmethod.pyi] |
| [out] |
| == |
| |
| [case testFileAddedAndImported] |
| # flags: --ignore-missing-imports --follow-imports=skip |
| # cmd: mypy a.py |
| # cmd2: mypy a.py b.py |
| |
| [file a.py] |
| from b import bad |
| x = 42 |
| |
| [file b.py.2] |
| def good() -> None: ... |
| [out] |
| == |
| a.py:1: error: Module 'b' has no attribute 'bad' |
| |
| [case testFileAddedAndImported2] |
| # flags: --ignore-missing-imports --follow-imports=skip |
| # cmd: mypy -m a |
| # cmd2: mypy -m a b |
| [file a.py] |
| x = 42 |
| |
| [file a.py.2] |
| from b import bad |
| x = 42 |
| |
| [file b.py.2] |
| def good() -> None: ... |
| [out] |
| == |
| a.py:1: error: Module 'b' has no attribute 'bad' |
| |
| [case testTypedDictCrashFallbackAfterDeletedMeet] |
| # flags: --ignore-missing-imports |
| |
| from z import get_data |
| from a import Data |
| |
| for it in get_data()['things']: |
| it['id'] |
| |
| [file z.py] |
| from a import Data |
| |
| def get_data() -> Data: ... |
| |
| [file a.py] |
| from typing import TypedDict, List, Union |
| |
| class File(TypedDict): |
| id: int |
| name: str |
| |
| class User(TypedDict): |
| id: int |
| path: str |
| |
| class Data(TypedDict): |
| things: List[Union[File, User]] |
| |
| [delete a.py.2] |
| [builtins fixtures/dict.pyi] |
| [typing fixtures/typing-typeddict.pyi] |
| [out] |
| == |
| |
| [case testTypedDictCrashFallbackAfterDeletedJoin] |
| # flags: --ignore-missing-imports |
| |
| from z import get_data |
| from a import Data |
| |
| x = [get_data()[0], get_data()[1]] |
| |
| [file z.py] |
| from a import Data |
| |
| def get_data() -> Data: ... |
| |
| [file a.py] |
| from typing import TypedDict, Tuple |
| |
| class File(TypedDict): |
| id: int |
| name: str |
| |
| class User(TypedDict): |
| id: int |
| path: str |
| |
| Data = Tuple[User, File] |
| |
| [delete a.py.2] |
| [builtins fixtures/dict.pyi] |
| [typing fixtures/typing-typeddict.pyi] |
| [out] |
| == |
| |
| [case testClassRedef] |
| # An issue involved serializing these caused crashes in the past |
| |
| [file a.py] |
| class A: |
| pass |
| |
| x = 0 |
| |
| [file a.py.2] |
| class A: |
| a = A() |
| |
| x = '0' |
| |
| [file b.py] |
| from a import A, x |
| |
| class A: # type: ignore |
| pass |
| |
| [out] |
| == |
| |
| [case testAddAttributeThroughNewBaseClass] |
| import a |
| |
| [file a.py] |
| class C: |
| def __init__(self) -> None: |
| self.x = 0 |
| |
| [file a.py.2] |
| from b import B |
| |
| class C(B): |
| def __init__(self) -> None: |
| self.x = 0 |
| |
| [file b.py.2] |
| class B: |
| def __init__(self) -> None: |
| self.x = 0 |
| [out] |
| == |
| |
| [case testGenericChange1] |
| import a |
| [file a.py] |
| import b |
| def f() -> b.C: pass |
| [file b.py] |
| import a |
| class C: pass |
| [file b.py.2] |
| from typing import TypeVar, Generic, List |
| import a |
| |
| T = TypeVar('T') |
| class C(Generic[T]): pass |
| |
| reveal_type(a.f) |
| c: C[int] |
| l = a.f() if True else c |
| d = a.f() |
| d = c |
| c = d |
| |
| x: List[C] = [a.f(), a.f()] |
| |
| [out] |
| == |
| b.py:7: note: Revealed type is 'def () -> b.C[Any]' |
| [builtins fixtures/list.pyi] |
| |
| [case testGenericChange2] |
| import a |
| [file a.py] |
| import b |
| def f() -> b.C[int]: pass |
| [file b.py] |
| from typing import TypeVar, Generic |
| import a |
| T = TypeVar('T') |
| class C(Generic[T]): pass |
| [file b.py.2] |
| from typing import List |
| import a |
| |
| class C(): pass |
| |
| c: C |
| l = a.f() if True else c |
| d = a.f() |
| d = c |
| c = d |
| |
| x: List[C] = [a.f(), a.f()] |
| |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| a.py:2: error: "C" expects no type arguments, but 1 given |
| |
| [case testGenericChange3] |
| import a |
| [file a.py] |
| import b |
| def f() -> b.C[int]: pass |
| [file b.py] |
| from typing import TypeVar, Generic |
| import a |
| T = TypeVar('T') |
| class C(Generic[T]): pass |
| [file b.py.2] |
| from typing import TypeVar, Generic, List |
| import a |
| |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class C(Generic[S, T]): pass |
| |
| c: C[int, str] |
| l = a.f() if True else c |
| d = a.f() |
| d = c |
| c = d |
| |
| x: List[C] = [a.f(), a.f()] |
| |
| [out] |
| == |
| a.py:2: error: "C" expects 2 type arguments, but 1 given |
| [builtins fixtures/list.pyi] |
| |
| [case testIsInstanceAdHocIntersectionFineGrainedIncrementalNoChange] |
| import b |
| [file a.py] |
| class A: pass |
| class B: pass |
| |
| class Foo: |
| def __init__(self) -> None: |
| x: A |
| assert isinstance(x, B) |
| self.x = x |
| [file b.py] |
| from a import Foo |
| [file b.py.2] |
| from a import Foo |
| reveal_type(Foo().x) |
| [builtins fixtures/isinstance.pyi] |
| [out] |
| == |
| b.py:2: note: Revealed type is 'a.<subclass of "A" and "B">' |
| |
| [case testIsInstanceAdHocIntersectionFineGrainedIncrementalIsInstanceChange] |
| import c |
| [file a.py] |
| class A: pass |
| class B: pass |
| class C: pass |
| |
| class Foo: |
| def __init__(self) -> None: |
| x: A |
| assert isinstance(x, B) |
| self.x = x |
| [file a.py.2] |
| class A: pass |
| class B: pass |
| class C: pass |
| |
| class Foo: |
| def __init__(self) -> None: |
| x: A |
| assert isinstance(x, C) |
| self.x = x |
| |
| [file b.py] |
| from a import Foo |
| y = Foo().x |
| |
| [file c.py] |
| from b import y |
| reveal_type(y) |
| [builtins fixtures/isinstance.pyi] |
| [out] |
| c.py:2: note: Revealed type is 'a.<subclass of "A" and "B">' |
| == |
| c.py:2: note: Revealed type is 'a.<subclass of "A" and "C">' |
| |
| [case testIsInstanceAdHocIntersectionFineGrainedIncrementalUnderlyingObjChang] |
| import c |
| [file a.py] |
| class A: pass |
| class B: pass |
| class C: pass |
| Extra = B |
| [file a.py.2] |
| class A: pass |
| class B: pass |
| class C: pass |
| Extra = C |
| |
| [file b.py] |
| from a import A, Extra |
| x: A |
| if isinstance(x, Extra): |
| y = x |
| |
| [file c.py] |
| from b import y |
| reveal_type(y) |
| [builtins fixtures/isinstance.pyi] |
| [out] |
| c.py:2: note: Revealed type is 'b.<subclass of "A" and "B">' |
| == |
| c.py:2: note: Revealed type is 'b.<subclass of "A" and "C">' |
| |
| [case testIsInstanceAdHocIntersectionFineGrainedIncrementalIntersectionToUnreachable] |
| import c |
| [file a.py] |
| class A: |
| x: int |
| class B: |
| x: int |
| x: A |
| assert isinstance(x, B) |
| y = x |
| |
| [file a.py.2] |
| class A: |
| x: int |
| class B: |
| x: str |
| x: A |
| assert isinstance(x, B) |
| y = x |
| |
| [file b.py] |
| from a import y |
| z = y |
| |
| [file c.py] |
| from b import z |
| reveal_type(z) |
| [builtins fixtures/isinstance.pyi] |
| [out] |
| c.py:2: note: Revealed type is 'a.<subclass of "A" and "B">' |
| == |
| c.py:2: note: Revealed type is 'a.A' |
| |
| [case testIsInstanceAdHocIntersectionFineGrainedIncrementalUnreachaableToIntersection] |
| import c |
| [file a.py] |
| class A: |
| x: int |
| class B: |
| x: str |
| x: A |
| assert isinstance(x, B) |
| y = x |
| |
| [file a.py.2] |
| class A: |
| x: int |
| class B: |
| x: int |
| x: A |
| assert isinstance(x, B) |
| y = x |
| |
| [file b.py] |
| from a import y |
| z = y |
| |
| [file c.py] |
| from b import z |
| reveal_type(z) |
| [builtins fixtures/isinstance.pyi] |
| [out] |
| c.py:2: note: Revealed type is 'a.A' |
| == |
| c.py:2: note: Revealed type is 'a.<subclass of "A" and "B">' |
| |
| [case testStubFixupIssues] |
| [file a.py] |
| import p |
| [file a.py.2] |
| import p |
| # a change |
| |
| [file p/__init__.pyi] |
| from p.util import * |
| |
| [file p/util.pyi] |
| from p.params import N |
| class Test: ... |
| |
| [file p/params.pyi] |
| import p.util |
| class N(p.util.Test): |
| ... |
| |
| [builtins fixtures/list.pyi] |
| [out] |
| == |
| |
| [case testDunderCall1] |
| from a import C |
| |
| c = C() |
| c(1) |
| |
| [file a.py] |
| class C: |
| def __call__(self, x: int) -> None: ... |
| |
| [file a.py.2] |
| class C: |
| def __call__(self, x: str) -> None: ... |
| |
| [out] |
| == |
| main:4: error: Argument 1 to "__call__" of "C" has incompatible type "int"; expected "str" |
| |
| [case testDunderCall2] |
| from a import C |
| |
| C()(1) |
| |
| [file a.py] |
| class C: |
| def __call__(self, x: int) -> None: ... |
| |
| [file a.py.2] |
| class C: |
| def __call__(self, x: str) -> None: ... |
| |
| [out] |
| == |
| main:3: error: Argument 1 to "__call__" of "C" has incompatible type "int"; expected "str" |
| |
| [case testDunderCallAddition] |
| from a import C |
| |
| c = C() |
| x = c() # type: ignore |
| x + 42 |
| |
| [file a.py] |
| class C: ... |
| |
| [file a.py.2] |
| class C: |
| def __call__(self) -> str: ... |
| |
| [out] |
| == |
| main:5: error: Unsupported left operand type for + ("str") |