Message411677
Interesting! Representing the entire type hint as a string is something I haven't thought about, but it makes sense that it works.
It is my understanding that `get_type_hint()` already walks through the entire type hint recursively. If it weren't, it would not resolve `List['N']` to `List[__main__.N]` in the example below.
>>> from typing import get_type_hints, Mapping, List
>>>
>>> class N:
... a: Mapping['str', list[List['N']]]
...
>>> get_type_hints(N)
{'a': typing.Mapping[str, list[typing.List[__main__.N]]]}
Upon closer inspection of the `typing` code, I can see that `_eval_type()` is doing that recursion. Applying the change your proposed in your previous message to that function seems to work at least in a trivial test case.
diff --git a/Lib/typing.py b/Lib/typing.py
index e3e098b1fc..ac56b545b4 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -331,6 +331,12 @@ def _eval_type(t, globalns, localns, recursive_guard=frozenset()):
if isinstance(t, ForwardRef):
return t._evaluate(globalns, localns, recursive_guard)
if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)):
+ if isinstance(t, GenericAlias):
+ args = tuple(
+ ForwardRef(arg) if isinstance(arg, str) else arg
+ for arg in t.__args__
+ )
+ t = t.__origin__[(*args,)]
ev_args = tuple(_eval_type(a, globalns, localns, recursive_guard) for a in t.__args__)
if ev_args == t.__args__:
return t
Testcase:
>>> from typing import get_type_hints, Mapping, List
>>> class N:
... a: Mapping['str', List[list['N']]]
...
>>> get_type_hints(N)
{'a': typing.Mapping[str, typing.List[list[__main__.N]]]}
I believe that this would be enough, but then again I haven't yet had enough time to crack at other implications this might have.
> How will it interact with from __future__ import annotations?
I've never used this future, but from my current, possibly limited, understanding it should have no side effects on how `get_type_hints()` will evaluate fully stringified annotations (as you have already shown, a fully stringified type hint actually works fine with PEP 585 generics).
> And can we sell this as a bugfix for 3.10, or will this be a new feature in 3.11?
I will throw in my personal opinion that this could be a bugfix, but I'm obviously biased as being on the "experiencing end" of this behaviour we're trying to change. |
|
Date |
User |
Action |
Args |
2022-01-25 22:07:42 | n_rosenstein | set | recipients:
+ n_rosenstein, gvanrossum, eric.smith, lukasz.langa, levkivskyi, JelleZijlstra, miss-islington, BTaskaya, sobolevn, joperez, kj, AlexWaygood |
2022-01-25 22:07:42 | n_rosenstein | set | messageid: <1643148462.16.0.723370086753.issue41370@roundup.psfhosted.org> |
2022-01-25 22:07:42 | n_rosenstein | link | issue41370 messages |
2022-01-25 22:07:42 | n_rosenstein | create | |
|