Skip to content

Commit

Permalink
Don't crash when partial types are used in inherited attribute (#6766)
Browse files Browse the repository at this point in the history
Fixes #4552 by deferring the compatibility check.
  • Loading branch information
onlined authored and ilevkivskyi committed May 13, 2019
1 parent b3420c8 commit e0b1329
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
10 changes: 8 additions & 2 deletions mypy/checker.py
Expand Up @@ -1836,7 +1836,6 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
infer_lvalue_type)
else:
lvalue_type, index_lvalue, inferred = self.check_lvalue(lvalue)

# If we're assigning to __getattr__ or similar methods, check that the signature is
# valid.
if isinstance(lvalue, NameExpr) and lvalue.node:
Expand All @@ -1853,7 +1852,9 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
else:
self.check_getattr_method(signature, lvalue, name)

if isinstance(lvalue, RefExpr):
# Defer PartialType's super type checking.
if (isinstance(lvalue, RefExpr) and
not (isinstance(lvalue_type, PartialType) and lvalue_type.type is None)):
if self.check_compatibility_all_supers(lvalue, lvalue_type, rvalue):
# We hit an error on this line; don't check for any others
return
Expand Down Expand Up @@ -1883,6 +1884,11 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
# Try to infer a partial type. No need to check the return value, as
# an error will be reported elsewhere.
self.infer_partial_type(lvalue_type.var, lvalue, rvalue_type)
# Handle None PartialType's super type checking here, after it's resolved.
if (isinstance(lvalue, RefExpr) and
self.check_compatibility_all_supers(lvalue, lvalue_type, rvalue)):
# We hit an error on this line; don't check for any others
return
elif (is_literal_none(rvalue) and
isinstance(lvalue, NameExpr) and
isinstance(lvalue.node, Var) and
Expand Down
28 changes: 28 additions & 0 deletions test-data/unit/check-inference.test
Expand Up @@ -2696,3 +2696,31 @@ reveal_type(x) # E: Revealed type is 'builtins.list[Any]'
reveal_type(y) # E: Revealed type is 'builtins.dict[Any, Any]'

[builtins fixtures/dict.pyi]

[case testInheritedAttributeNoStrictOptional]
# flags: --no-strict-optional
class A:
x: str

class B(A):
x = None
x = ''
reveal_type(x) # E: Revealed type is 'builtins.str'

[case testIncompatibleInheritedAttributeNoStrictOptional]
# flags: --no-strict-optional
class A:
x: str

class B(A):
x = None
x = 2 # E: Incompatible types in assignment (expression has type "int", base class "A" defined the type as "str")

[case testInheritedAttributeStrictOptional]
# flags: --strict-optional
class A:
x: str

class B(A):
x = None # E: Incompatible types in assignment (expression has type "None", base class "A" defined the type as "str")
x = ''

0 comments on commit e0b1329

Please sign in to comment.