如何让mypy识别__init_subclass__中定义的ClassVar类型?
Solution
To resolve the mypy type checking warnings, you need to make the Philosopher class generic, tying its school class variable to the concrete School subclass passed during subclass creation. Here's the fixed code:
from typing import TypeVar, ClassVar, Generic, type class School: def __init__(self) -> None: self.number = 0 def test(self) -> None: self.number = 0 class Sophism(School): def test(self) -> None: self.number = 1 class Epicureanism(School): def test(self) -> None: self.number = 2 # Define a TypeVar bound to School, to represent concrete subclasses SchoolT = TypeVar("SchoolT", bound=School) class Philosopher(Generic[SchoolT]): # ClassVar uses the generic type variable to track the concrete School subclass school: ClassVar[SchoolT] def __init_subclass__(cls, /, school: type[SchoolT], **kwargs: object) -> None: super().__init_subclass__(**kwargs) cls.school = school() # Explicitly specify the generic type when creating the subclass class Sophist(Philosopher[Sophism], school=Sophism): pass s1 = Sophist() s2 = Sophist() s1.school.test() # No mypy error now assert s1.school.number == s2.school.number == Sophist.school.number # True assert s1.school == s2.school == Sophist.school # True
Key Changes:
- Generic Philosopher Class: By inheriting from
Generic[SchoolT], we makePhilosophera generic class where each subclass is tied to a specificSchooltype. This lets mypy infer the concrete type ofschoolfor each subclass. - ClassVar with Generic Type: The
schoolattribute is annotated asClassVar[SchoolT], which tells mypy it's a class-level variable whose type matches the generic parameter of the subclass. - Explicit Generic Parameter: When defining
Sophist, we specifyPhilosopher[Sophism]to bind the subclass to theSophismschool type. This ensures mypy recognizess1.schoolas an instance ofSophism, with access totest()andnumber. - Type Hint for init_subclass: The
schoolparameter in__init_subclass__is typed astype[SchoolT], confirming it's a subclass ofSchoolthat matches the generic parameter.
These changes eliminate all mypy warnings while preserving the original runtime behavior.
内容的提问来源于stack exchange,提问作者Some Guy
相关产品推荐
相关产品推荐

