| [case testAssignmentOnClass] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| A.x = 2 | |
| [case testAssignmentOnInstance] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| A().x = 2 | |
| [out] | |
| main:4: error: Cannot assign to class variable "x" via instance | |
| [case testAssignmentOnSubclassInstance] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| class B(A): | |
| pass | |
| B().x = 2 | |
| [out] | |
| main:6: error: Cannot assign to class variable "x" via instance | |
| [case testOverrideOnSelf] | |
| from typing import ClassVar | |
| class A: | |
| x: ClassVar[int] | |
| def __init__(self) -> None: | |
| self.x = 0 | |
| [out] | |
| main:5: error: Cannot assign to class variable "x" via instance | |
| [case testOverrideOnSelfInSubclass] | |
| from typing import ClassVar | |
| class A: | |
| x: ClassVar[int] | |
| class B(A): | |
| def __init__(self) -> None: | |
| self.x = 0 | |
| [out] | |
| main:6: error: Cannot assign to class variable "x" via instance | |
| [case testReadingFromInstance] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| A().x | |
| reveal_type(A().x) | |
| [out] | |
| main:5: note: Revealed type is "builtins.int" | |
| [case testReadingFromSelf] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| def __init__(self) -> None: | |
| reveal_type(self.x) | |
| [out] | |
| main:5: note: Revealed type is "builtins.int" | |
| [case testTypecheckSimple] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| y = A.x # type: int | |
| [case testTypecheckWithUserType] | |
| from typing import ClassVar | |
| class A: | |
| pass | |
| class B: | |
| x = A() # type: ClassVar[A] | |
| [case testTypeCheckOnAssignment] | |
| from typing import ClassVar | |
| class A: | |
| pass | |
| class B: | |
| pass | |
| class C: | |
| x: ClassVar[A] | |
| C.x = B() | |
| [out] | |
| main:8: error: Incompatible types in assignment (expression has type "B", variable has type "A") | |
| [case testTypeCheckWithOverridden] | |
| from typing import ClassVar | |
| class A: | |
| pass | |
| class B(A): | |
| pass | |
| class C: | |
| x = A() # type: ClassVar[A] | |
| C.x = B() | |
| [case testRevealType] | |
| from typing import ClassVar | |
| class A: | |
| x: ClassVar[int] | |
| reveal_type(A.x) | |
| [out] | |
| main:4: note: Revealed type is "builtins.int" | |
| [case testInfer] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| y = A.x | |
| reveal_type(y) | |
| [out] | |
| main:5: note: Revealed type is "builtins.int" | |
| [case testAssignmentOnUnion] | |
| from typing import ClassVar, Union | |
| class A: | |
| x: int | |
| class B: | |
| x: ClassVar[int] | |
| c = A() # type: Union[A, B] | |
| c.x = 1 | |
| [out] | |
| main:7: error: Cannot assign to class variable "x" via instance | |
| [case testAssignmentOnInstanceFromType] | |
| from typing import ClassVar, Type | |
| class A: | |
| x: ClassVar[int] | |
| def f(a: Type[A]) -> None: | |
| a().x = 0 | |
| [out] | |
| main:5: error: Cannot assign to class variable "x" via instance | |
| [case testAssignmentOnInstanceFromSubclassType] | |
| from typing import ClassVar, Type | |
| class A: | |
| x: ClassVar[int] | |
| class B(A): | |
| pass | |
| def f(b: Type[B]) -> None: | |
| b().x = 0 | |
| [out] | |
| main:7: error: Cannot assign to class variable "x" via instance | |
| [case testClassVarWithList] | |
| from typing import ClassVar, List | |
| class A: | |
| x: ClassVar[List[int]] | |
| A.x = ['a'] | |
| A().x.append(1) | |
| A().x.append('') | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| main:4: error: List item 0 has incompatible type "str"; expected "int" | |
| main:6: error: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" | |
| [case testClassVarWithUnion] | |
| from typing import ClassVar, Union | |
| class A: | |
| x: ClassVar[Union[int, str]] | |
| class B: | |
| pass | |
| A.x = 0 | |
| A.x = 'a' | |
| A.x = B() | |
| reveal_type(A().x) | |
| [out] | |
| main:8: error: Incompatible types in assignment (expression has type "B", variable has type "int | str") | |
| main:9: note: Revealed type is "builtins.int | builtins.str" | |
| [case testOverrideWithNarrowedUnion] | |
| from typing import ClassVar, Union | |
| class A: pass | |
| class B: pass | |
| class C: pass | |
| class D: | |
| x: ClassVar[Union[A, B, C]] | |
| class E(D): | |
| x: ClassVar[Union[A, B]] | |
| [case testOverrideWithExtendedUnion] | |
| from typing import ClassVar, Union | |
| class A: pass | |
| class B: pass | |
| class C: pass | |
| class D: | |
| x: ClassVar[Union[A, B]] | |
| class E(D): | |
| x: ClassVar[Union[A, B, C]] | |
| [out] | |
| main:8: error: Incompatible types in assignment (expression has type "A | B | C", base class "D" defined the type as "A | B") | |
| [case testAssignmentToCallableRet] | |
| from typing import ClassVar | |
| class A: | |
| x: ClassVar[int] | |
| def f() -> A: | |
| return A() | |
| f().x = 0 | |
| [out] | |
| main:6: error: Cannot assign to class variable "x" via instance | |
| [case testOverrideWithIncompatibleType] | |
| from typing import ClassVar | |
| class A: | |
| x: ClassVar[int] | |
| class B(A): | |
| x: ClassVar[str] | |
| [out] | |
| main:5: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int") | |
| [case testOverrideWithNormalAttribute] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| class B(A): | |
| x = 2 # type: int | |
| [out] | |
| main:5: error: Cannot override class variable (previously declared on base class "A") with instance variable | |
| [case testOverrideWithAttributeWithClassVar] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: int | |
| class B(A): | |
| x = 2 # type: ClassVar[int] | |
| [out] | |
| main:5: error: Cannot override instance variable (previously declared on base class "A") with class variable | |
| [case testOverrideClassVarManyBases] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| class B: | |
| x = 2 # type: int | |
| class C(A, B): | |
| x = 3 # type: ClassVar[int] | |
| [out] | |
| main:7: error: Cannot override instance variable (previously declared on base class "B") with class variable | |
| [case testOverrideClassVarWithClassVar] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| class B(A): | |
| x = 2 # type: ClassVar[int] | |
| [case testOverrideClassVarWithImplicitClassVar] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| class B(A): | |
| x = 2 | |
| [case testOverrideClassVarWithImplicitThenExplicit] | |
| from typing import ClassVar | |
| class A: | |
| x = 1 # type: ClassVar[int] | |
| class B(A): | |
| x = 2 | |
| class C(B): | |
| x = 3 # type: ClassVar[int] | |
| [case testOverrideOnABCSubclass] | |
| from abc import ABCMeta | |
| from typing import ClassVar | |
| class A(metaclass=ABCMeta): | |
| x: ClassVar[int] | |
| class B(A): | |
| x = 0 # type: ClassVar[int] | |
| [case testAcrossModules] | |
| import m | |
| reveal_type(m.A().x) | |
| m.A().x = 0 | |
| [file m.py] | |
| from typing import ClassVar | |
| class A: | |
| x: ClassVar[int] | |
| [out] | |
| main:2: note: Revealed type is "builtins.int" | |
| main:3: error: Cannot assign to class variable "x" via instance | |
| [case testClassVarWithGeneric] | |
| from typing import ClassVar, Generic, TypeVar | |
| T = TypeVar('T') | |
| class A(Generic[T]): | |
| x: ClassVar[T] # Error reported at access site | |
| @classmethod | |
| def foo(cls) -> T: | |
| return cls.x # OK | |
| A.x # E: Access to generic class variables is ambiguous | |
| A.x = 1 # E: Access to generic class variables is ambiguous | |
| A[int].x # E: Access to generic class variables is ambiguous | |
| class Bad(A[int]): | |
| pass | |
| Bad.x # E: Access to generic class variables is ambiguous | |
| class Good(A[int]): | |
| x = 42 | |
| reveal_type(Good.x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testClassVarWithNestedGeneric] | |
| from typing import ClassVar, Generic, Tuple, TypeVar, Union, Type | |
| T = TypeVar('T') | |
| U = TypeVar('U') | |
| class A(Generic[T, U]): | |
| x: ClassVar[Union[T, Tuple[U, Type[U]]]] # Error reported at access site | |
| @classmethod | |
| def foo(cls) -> Union[T, Tuple[U, Type[U]]]: | |
| return cls.x # OK | |
| A.x # E: Access to generic class variables is ambiguous | |
| A.x = 1 # E: Access to generic class variables is ambiguous | |
| A[int, str].x # E: Access to generic class variables is ambiguous | |
| class Bad(A[int, str]): | |
| pass | |
| reveal_type(Bad.x) # E: Access to generic class variables is ambiguous \ | |
| # N: Revealed type is "builtins.int | tuple[builtins.str, type[builtins.str]]" | |
| reveal_type(Bad().x) # N: Revealed type is "builtins.int | tuple[builtins.str, type[builtins.str]]" | |
| class Good(A[int, str]): | |
| x = 42 | |
| reveal_type(Good.x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testSuggestClassVarOnTooFewArgumentsMethod] | |
| from typing import Callable | |
| class C: | |
| foo: Callable[[C], int] | |
| c:C | |
| c.foo() # E: Too few arguments \ | |
| # N: "foo" is considered instance variable, to make it class variable use ClassVar[...] | |
| [case testClassVarUnionBoundOnInstance] | |
| from typing import Union, Callable, ClassVar | |
| class C: | |
| def f(self) -> int: ... | |
| g: ClassVar[Union[Callable[[C], int], int]] = f | |
| reveal_type(C().g) # N: Revealed type is "(def () -> builtins.int) | builtins.int" | |
| [case testGenericSubclassAccessNoLeak] | |
| from typing import ClassVar, Generic, TypeVar | |
| T = TypeVar("T") | |
| class B(Generic[T]): | |
| x: T | |
| y: ClassVar[T] | |
| class C(B[T]): ... | |
| reveal_type(C.x) # E: Access to generic instance variables via class is ambiguous \ | |
| # N: Revealed type is "Any" | |
| reveal_type(C.y) # E: Access to generic class variables is ambiguous \ | |
| # N: Revealed type is "Any" | |
| [case testClassVarBareAnnotation] | |
| from typing import ClassVar | |
| class C: | |
| x: ClassVar = 1 | |
| y: ClassVar | |
| reveal_type(C.x) # N: Revealed type is "builtins.int" | |
| reveal_type(C().x) # N: Revealed type is "builtins.int" | |
| reveal_type(C.y) # N: Revealed type is "Any" | |
| reveal_type(C().y) # N: Revealed type is "Any" | |
| [case testClassVarBareAnnotationDisabled] | |
| # flags: --disallow-any-generics | |
| from typing import ClassVar | |
| class C: | |
| x: ClassVar = 1 | |
| y: ClassVar # E: ClassVar without type argument becomes Any |