-
-
Notifications
You must be signed in to change notification settings - Fork 117
[Bug] Behavior of typing_extensions.get_type_hints
differs from typing.get_type_hints
.
#597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I can't reproduce what you say on 3.10: both
|
That is because the from __future__ import annotations
import dataclasses as dcls
import inspect
import typing as typ
# import typing_extensions as typ
@dcls.dataclass
class Foo:
y: int
x: typ.ClassVar[ int ] = 1
print( 'anno', Foo.__init__.__annotations__ )
print( 'inspect', inspect.get_annotations( Foo.__init__, eval_str = True ) )
print( 'typing', typ.get_type_hints( Foo.__init__ ) )
# print( 'text', typ.get_type_hints( Foo.__init__ ) )
|
A important thing I found during debugging, it depends whether from __future__ import annotations
import dataclasses as dcls
import inspect
import typing
import typing_extensions as typ
@dcls.dataclass
class Bar:
y: int
x: typing.ClassVar[int] = 1
print("anno Bar", Bar.__init__.__annotations__)
print("inspect Bar", inspect.get_annotations(Bar.__init__, eval_str=True))
print("typing Bar", typing.get_type_hints(Bar.__init__))
print("text Bar", typ.get_type_hints(Bar.__init__))
@dcls.dataclass
class Foo:
y: int
x: typ.ClassVar[int] = 1
print("anno Foo", Foo.__init__.__annotations__)
print("inspect Foo", inspect.get_annotations(Foo.__init__, eval_str=True))
print("typing Foo", typing.get_type_hints(Foo.__init__))
print("text Foo", typ.get_type_hints(Foo.__init__)) Output:
|
Follow up. That looks like a bug dataclasses, or at least something that is not considered here. The derrived annotations of the (Pdb) Foo.__init__.__annotations__
{'y': 'int', 'x': 'typ.ClassVar[int]', 'return': None}
(Pdb) Bar.__init__.__annotations__
{'y': 'int', 'return': None} Some further insights can be found in this SO question and the
I guess that dataclasses does infer that the annotation |
Ah, good find. I hadn't tried the combination of While I agree that this points to a toxic interaction between |
Correct. I noted this in my original message and suggested that Slightly off-topic, but is it considered a good practice to silently drop annotations? What |
It doesn't drop annotations, since you're looking at annotations for |
Ooops. You're correct. I forgot that we were looking at the synthetic The remaining question is then whether the difference in |
I think that's expected behavior, |
I see. So, Thank you for your time; I will file a separate issue in the CPython repo for the |
(Possibly related to #410, but filing this separate issue to confirm and to consider documentation improvements, if so.)
The following simple reproducer will result in an error on Python 3.13.3 (latest stable CPython as of this writing) and earlier versions:
The error is:
Switching the import from
typing_extensions
totyping
causesget_type_hints
to work correctly (on both Python 3.10.12 and Python 3.13.3.):(Note the absence of the
ClassVar
annotation. This suggests that we possibly have a toxic interaction with thedataclasses.dataclass
decorator in the mix.)Likewise, removing the
from __future__ import annotations
and usingtyping_extensions.get_type_hints
also works correctly:And,
inspect.get_annotations
works correctly in all cases. But, I would prefer to useget_type_hints
as it automatically handles MRO traversal and annotation merging for classes. I have been usingtyping_extensions
rather thantyping
with the understanding thattyping_extensions
is providing a forward-compatibility layer. The forward-compatibility assumption is violated in this case.The text was updated successfully, but these errors were encountered: