8000 Don't crash on aliases like C = C by ilevkivskyi · Pull Request #5632 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Don't crash on aliases like C = C #5632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion mypy/fixup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down
4 changes: 4 additions & 0 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
114 changes: 114 additions & 0 deletions test-data/unit/check-incremental.test
Original file line number Diff line number Diff line change
Expand Up @@ -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]
39 changes: 39 additions & 0 deletions test-data/unit/check-type-aliases.test
Original file line number Diff line number Diff line change
Expand Up @@ -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]
1 change: 1 addition & 0 deletions test-data/unit/fixtures/exception.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ class bool: pass
class ellipsis: pass

class BaseException: pass
class Exception(BaseException): pass
0