diff --git a/changes/3401-uriyyo.md b/changes/3401-uriyyo.md new file mode 100644 index 0000000..7b46117 --- /dev/null +++ b/changes/3401-uriyyo.md @@ -0,0 +1 @@ +Fix issue when pydantic fail to parse `typing.ClassVar` string type annotation. \ No newline at end of file diff --git a/pydantic/typing.py b/pydantic/typing.py index 156db0b..5797432 100644 --- a/pydantic/typing.py +++ b/pydantic/typing.py @@ -332,7 +332,9 @@ def resolve_annotations(raw_annotations: Dict[str, Type[Any]], module_name: Opti annotations = {} for name, value in raw_annotations.items(): if isinstance(value, str): - if sys.version_info >= (3, 7): + if (3, 10) > sys.version_info >= (3, 9, 8) or sys.version_info >= (3, 10, 1): + value = ForwardRef(value, is_argument=False, is_class=True) + elif sys.version_info >= (3, 7): value = ForwardRef(value, is_argument=False) else: value = ForwardRef(value) diff --git a/tests/test_forward_ref.py b/tests/test_forward_ref.py index 95595fc..692a33d 100644 --- a/tests/test_forward_ref.py +++ b/tests/test_forward_ref.py @@ -519,3 +519,20 @@ def test_nested_forward_ref(): NestedTuple.update_forward_refs() obj = NestedTuple.parse_obj({'x': ('1', {'x': ('2', {'x': ('3', None)})})}) assert obj.dict() == {'x': (1, {'x': (2, {'x': (3, None)})})} + + +@skip_pre_37 +def test_class_var_as_string(create_module): + module = create_module( + # language=Python + """ +from __future__ import annotations +from typing import ClassVar +from pydantic import BaseModel + +class Model(BaseModel): + a: ClassVar[int] +""" + ) + + assert module.Model.__class_vars__ == {'a'}