Skip to content

Commit e0b1329

Browse files
onlinedilevkivskyi
authored andcommitted
Don't crash when partial types are used in inherited attribute (#6766)
Fixes #4552 by deferring the compatibility check.
1 parent b3420c8 commit e0b1329

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

mypy/checker.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,7 +1836,6 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
18361836
infer_lvalue_type)
18371837
else:
18381838
lvalue_type, index_lvalue, inferred = self.check_lvalue(lvalue)
1839-
18401839
# If we're assigning to __getattr__ or similar methods, check that the signature is
18411840
# valid.
18421841
if isinstance(lvalue, NameExpr) and lvalue.node:
@@ -1853,7 +1852,9 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
18531852
else:
18541853
self.check_getattr_method(signature, lvalue, name)
18551854

1856-
if isinstance(lvalue, RefExpr):
1855+
# Defer PartialType's super type checking.
1856+
if (isinstance(lvalue, RefExpr) and
1857+
not (isinstance(lvalue_type, PartialType) and lvalue_type.type is None)):
18571858
if self.check_compatibility_all_supers(lvalue, lvalue_type, rvalue):
18581859
# We hit an error on this line; don't check for any others
18591860
return
@@ -1883,6 +1884,11 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
18831884
# Try to infer a partial type. No need to check the return value, as
18841885
# an error will be reported elsewhere.
18851886
self.infer_partial_type(lvalue_type.var, lvalue, rvalue_type)
1887+
# Handle None PartialType's super type checking here, after it's resolved.
1888+
if (isinstance(lvalue, RefExpr) and
1889+
self.check_compatibility_all_supers(lvalue, lvalue_type, rvalue)):
1890+
# We hit an error on this line; don't check for any others
1891+
return
18861892
elif (is_literal_none(rvalue) and
18871893
isinstance(lvalue, NameExpr) and
18881894
isinstance(lvalue.node, Var) and

test-data/unit/check-inference.test

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,3 +2696,31 @@ reveal_type(x) # E: Revealed type is 'builtins.list[Any]'
26962696
reveal_type(y) # E: Revealed type is 'builtins.dict[Any, Any]'
26972697

26982698
[builtins fixtures/dict.pyi]
2699+
2700+
[case testInheritedAttributeNoStrictOptional]
2701+
# flags: --no-strict-optional
2702+
class A:
2703+
x: str
2704+
2705+
class B(A):
2706+
x = None
2707+
x = ''
2708+
reveal_type(x) # E: Revealed type is 'builtins.str'
2709+
2710+
[case testIncompatibleInheritedAttributeNoStrictOptional]
2711+
# flags: --no-strict-optional
2712+
class A:
2713+
x: str
2714+
2715+
class B(A):
2716+
x = None
2717+
x = 2 # E: Incompatible types in assignment (expression has type "int", base class "A" defined the type as "str")
2718+
2719+
[case testInheritedAttributeStrictOptional]
2720+
# flags: --strict-optional
2721+
class A:
2722+
x: str
2723+
2724+
class B(A):
2725+
x = None # E: Incompatible types in assignment (expression has type "None", base class "A" defined the type as "str")
2726+
x = ''

0 commit comments

Comments
 (0)