`TypeAlias` to alias a `ClassVar` with an `Annotated` type raises an error
Closed this issue · 2 comments
Bug Report
When using a TypeAlias to alias a ClassVar with an Annotated type, mypy raises an error indicating that ClassVar is valid only within a class body. This happens even though the code is valid and works at runtime. The issue seems to stem from mypy not recognizing the use of ClassVar within a type alias.
To Reproduce
from typing import ClassVar, Annotated, TypeAlias
# Define a type alias for a ClassVar with an Annotated type
MyType: TypeAlias = ClassVar[Annotated[str, "MyType"]]
class A:
# Use the type alias in a class definition
typ: MyType
Expected Behavior
Mypy should recognize that MyType is a type alias for a ClassVar and allow its usage within the class A without errors. The typ attribute should be treated as a class variable of type Annotated[str, "MyType"].
Actual Behavior
Mypy raises the following error:
test.py:4: error: "ClassVar" is valid only in class body
This suggests that mypy does not accept the use of ClassVar within a type alias outside of a class body, even though it's valid Python code.
Your Environment
Mypy version used: 1.4.1
Mypy command-line flags: None
Mypy configuration options from mypy.ini: None
Python version used: 3.11
Additional Information
The code works as expected at runtime without any issues. Using ClassVar directly within the class body without a type alias does not produce an error. This issue may affect libraries like Pydantic that rely on such patterns for type annotations.
This issue may affect libraries like Pydantic that rely on such patterns for type annotations.
I'll note that we don't rely on such patterns. with PEP 613 type aliases, this is equivalent to a simple assignment at runtime so naturally Pydantic treats both fields as being equivalent:
MyType: TypeAlias = ClassVar[int]
class Model(BaseModel):
a: MyType
b: ClassVar[int]
However, we don't support PEP 695 aliases as the runtime behavior is different.
Mypy is working correctly here in conformance with the typing spec.
The righthand side of a type alias definition must be a valid type expression. ClassVar
is a type qualifier that is legal (under specific circumstances) within an annotation expression, but it is not allowed in a type expression. Refer to this section of the typing spec for details. Mypy should therefore reject this type alias statement because it's invalid according to the spec.
If you want to use the ClassVar
type qualifier, you must use it within the class body, as indicated by mypy's error message.