Skip to content

Commit 68657d2

Browse files
authored
Interpret bare ClassVar as inferred, not Any (#19573)
Fixes #5587 Apparently, it is part of _the spec_ now.
1 parent 9d3a052 commit 68657d2

File tree

4 files changed

+29
-2
lines changed

4 files changed

+29
-2
lines changed

mypy/semanal.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5094,6 +5094,7 @@ def check_classvar(self, s: AssignmentStmt) -> None:
50945094
return
50955095
if not s.type or not self.is_classvar(s.type):
50965096
return
5097+
assert isinstance(s.type, UnboundType)
50975098
if self.is_class_scope() and isinstance(lvalue, NameExpr):
50985099
node = lvalue.node
50995100
if isinstance(node, Var):
@@ -5110,6 +5111,12 @@ def check_classvar(self, s: AssignmentStmt) -> None:
51105111
# In case of member access, report error only when assigning to self
51115112
# Other kinds of member assignments should be already reported
51125113
self.fail_invalid_classvar(lvalue)
5114+
if not s.type.args:
5115+
if isinstance(s.rvalue, TempNode) and s.rvalue.no_rhs:
5116+
if self.options.disallow_any_generics:
5117+
self.fail("ClassVar without type argument becomes Any", s, code=codes.TYPE_ARG)
5118+
return
5119+
s.type = None
51135120

51145121
def is_classvar(self, typ: Type) -> bool:
51155122
if not isinstance(typ, UnboundType):

test-data/unit/check-classvar.test

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,3 +360,23 @@ reveal_type(C.x) # E: Access to generic instance variables via class is ambiguo
360360
# N: Revealed type is "Any"
361361
reveal_type(C.y) # E: Access to generic class variables is ambiguous \
362362
# N: Revealed type is "Any"
363+
364+
[case testClassVarBareAnnotation]
365+
from typing import ClassVar
366+
367+
class C:
368+
x: ClassVar = 1
369+
y: ClassVar
370+
371+
reveal_type(C.x) # N: Revealed type is "builtins.int"
372+
reveal_type(C().x) # N: Revealed type is "builtins.int"
373+
reveal_type(C.y) # N: Revealed type is "Any"
374+
reveal_type(C().y) # N: Revealed type is "Any"
375+
376+
[case testClassVarBareAnnotationDisabled]
377+
# flags: --disallow-any-generics
378+
from typing import ClassVar
379+
380+
class C:
381+
x: ClassVar = 1
382+
y: ClassVar # E: ClassVar without type argument becomes Any

test-data/unit/check-incremental.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2051,7 +2051,7 @@ warn_no_return = True
20512051
[case testIncrementalClassVar]
20522052
from typing import ClassVar
20532053
class A:
2054-
x = None # type: ClassVar
2054+
x: ClassVar
20552055
A().x = 0
20562056
[out1]
20572057
main:4: error: Cannot assign to class variable "x" via instance

test-data/unit/semanal-classvar.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ MypyFile:1(
5252
AssignmentStmt:3(
5353
NameExpr(x [m])
5454
IntExpr(1)
55-
Any)))
55+
builtins.int)))
5656

5757
[case testClassVarWithTypeVar]
5858

0 commit comments

Comments
 (0)