'ClassVar inside generic class with same name as the parametrizing variable
I have a generic class definition which declares a ClassVar that happens to have the same name as the parametrizing TypeVar. I'd like to keep them the same name. However, mypy complains about this for reasons that are not obvious to me; it seems to replace the TypeVar with the newly declared ClassVar. This seems to contradict the following statement in PEP 484:
Type variables follow normal name resolution rules. However, there are some special cases in the static typechecking context: [...]
It is not mentioned as part of the "special cases" following the above paragraph.
The following is an example that reproduces the problem:
from __future__ import annotations
from typing import Any, ClassVar, Generic, Type, TypeVar
T = TypeVar('T')
class Base(Generic[T]):
T: ClassVar[Type] # This happens to have the same name as the TypeVar.
def from_text(self, x: str) -> T:
raise NotImplementedError
class Foo(Base[list]):
T: ClassVar[Type] = list
def from_text(self, x: str) -> list:
return list(x)
def do_stuff(obj: Base[T], val: Any) -> T:
if isinstance(val, obj.T):
return val
elif isinstance(val, str):
return obj.from_text(val)
else:
raise TypeError(type(val))
x = do_stuff(Foo(), [1, 2, 3])
y = do_stuff(Foo(), '123')
I get the following error from mypy:
test.py:12: error: Variable "test.Base.T" is not valid as a type
test.py:12: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
Found 1 error in 1 file (checked 1 source file)
If I replace the name of the ClassVar with something else then no error is reported.
Python and mypy version:
$ python --version
Python 3.7.9
$ mypy --version
mypy 0.931
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
