Closed
Description
>>> import typing
>>> def f(x: typing.ClassVar[int]): pass
...
>>> typing.get_type_hints(f)
{'x': typing.ClassVar[int]}
>>> def f(x: "typing.ClassVar[int]"): pass
...
>>> typing.get_type_hints(f)
Traceback (most recent call last):
File "<python-input-4>", line 1, in <module>
typing.get_type_hints(f)
~~~~~~~~~~~~~~~~~~~~~^^^
File "/Users/jelle/py/cpython/Lib/typing.py", line 2390, in get_type_hints
hints[name] = _eval_type(value, globalns, localns, type_params, format=format, owner=obj)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jelle/py/cpython/Lib/typing.py", line 448, in _eval_type
return evaluate_forward_ref(t, globals=globalns, locals=localns,
type_params=type_params, owner=owner,
_recursive_guard=recursive_guard, format=format)
File "/Users/jelle/py/cpython/Lib/typing.py", line 993, in evaluate_forward_ref
type_ = _type_check(
value,
...<2 lines>...
allow_special_forms=forward_ref.__forward_is_class__,
)
File "/Users/jelle/py/cpython/Lib/typing.py", line 204, in _type_check
raise TypeError(f"{arg} is not valid as type argument")
TypeError: typing.ClassVar[int] is not valid as type argument
(On main but also reproduced on 3.13.)
This seems inconsistent and I don't think it's helpful for users. We should either raise in both cases or neither. I prefer to not raise in either case, because it's less disruptive for callers (they already have to deal with ClassVar
etc. potentially appearing in annotations), and provides more information.