diff --git a/mypy/fixup.py b/mypy/fixup.py index 281f5fc4a0ae..947f3bbb7afc 100644 --- a/mypy/fixup.py +++ b/mypy/fixup.py @@ -236,7 +236,10 @@ def lookup_qualified_typeinfo(modules: Dict[str, MypyFile], name: str, return node else: # Looks like a missing TypeInfo in quick mode, put something there - assert quick_and_dirty, "Should never get here in normal mode" + assert quick_and_dirty, "Should never get here in normal mode," \ + " got {}:{} instead of TypeInfo".format(type(node).__name__, + node.fullname() if node + else '') return stale_info(modules) diff --git a/mypy/semanal.py b/mypy/semanal.py index 1e24dd3ea1c1..3facb72cb729 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1931,6 +1931,10 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> None: res, alias_tvars, depends_on, qualified_tvars = self.analyze_alias(rvalue) if not res: return + if (isinstance(res, Instance) and res.type.name() == lvalue.name and + res.type.module_name == self.cur_mod_id): + # Aliases like C = C is a no-op. + return s.is_alias_def = True node = self.lookup(lvalue.name, lvalue) assert node is not None diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index a902a25d5ed3..f386890280b4 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -5193,3 +5193,117 @@ def f(x: str) -> None: pass [out] [out2] tmp/main.py:2: error: Argument 1 to "f" has incompatible type "int"; expected "str" + +[case testOverrideByIdemAlias] +import a +[file a.py] +import lib +x = 1 +[file a.py.2] +import lib +x = 2 +[file lib.py] +C = C +class C: # type: ignore + pass +[out] +[out2] + +[case testOverrideByIdemAliasReversed] +import a +[file a.py] +import lib +x = 1 +[file a.py.2] +import lib +x = 2 +[file lib.py] +class C: + pass +C = C # type: ignore +x: C +[out] +[out2] + +[case testOverrideByIdemAliasGeneric] +import a +[file a.py] +import lib +x = 1 +[file a.py.2] +import lib +x = 2 +[file lib.py] +from typing import Generic, TypeVar + +T = TypeVar('T') + +class C(Generic[T]): + pass +C = C[int] # type: ignore +x: C +[out] +[out2] + +[case testOverrideByIdemAliasImported] +import a +[file a.py] +import lib +x = 1 +[file a.py.2] +import lib +x = 2 +[file lib.py] +from other import C +C = C # type: ignore +x: C +[file other.py] +class C: + pass +[out] +[out2] + +[case testOverrideByIdemAliasImportedReversed] +import a +[file a.py] +import lib +x = 1 +[file a.py.2] +import lib +x = 2 +[file lib.py] +C = C # type: ignore +from other import C +[file other.py] +class C: + pass +[out] +[out2] + +[case testConditionalExceptionAliasOverride] +import a +[file a.py] +import lib +try: + x = 1 +except lib.Exception as e: + pass +[file a.py.2] +import lib +try: + x = 2 +except lib.Exception as e: + pass +[file lib.py] +try: + Exception = Exception +except BaseException: + class Exception(BaseException): pass # type: ignore + +try: + pass +except Exception as e: + pass +[builtins fixtures/exception.pyi] +[out] +[out2] diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 44377d584cd8..b8ebe8105213 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -518,3 +518,42 @@ def foo(x: Bogus[int]) -> None: reveal_type(x) # E: Revealed type is 'builtins.int' [builtins fixtures/dict.pyi] + +[case testOverrideByIdemAliasCorrectType] +C = C +class C: # type: ignore + pass +x: C +reveal_type(x) # E: Revealed type is '__main__.C' +[out] + +[case testOverrideByIdemAliasCorrectTypeReversed] +class C: + pass +C = C # type: ignore +x: C +reveal_type(x) # E: Revealed type is '__main__.C' +[out] + +[case testOverrideByIdemAliasCorrectTypeImported] +from other import C as B +C = B +x: C +reveal_type(x) # E: Revealed type is 'other.C' +[file other.py] +class C: + pass +[out] + +[case testConditionalExceptionAlias] +try: + E = E +except BaseException: + class E(BaseException): pass # type: ignore + +try: + pass +except E as e: + reveal_type(e) # E: Revealed type is '__main__.E' +[builtins fixtures/exception.pyi] +[out] diff --git a/test-data/unit/fixtures/exception.pyi b/test-data/unit/fixtures/exception.pyi index b6810d41fd1f..f9bda1b2a042 100644 --- a/test-data/unit/fixtures/exception.pyi +++ b/test-data/unit/fixtures/exception.pyi @@ -14,3 +14,4 @@ class bool: pass class ellipsis: pass class BaseException: pass +class Exception(BaseException): pass