mirror of
https://github.com/python/cpython.git
synced 2025-10-06 23:21:06 +00:00
bpo-42904: Change search order of typing.get_type_hints eval (#25632)
While surprising (searching globals before locals in one specific case), this is needed for backwards compatibility.
This commit is contained in:
parent
94549ee728
commit
1b1f9852bd
3 changed files with 17 additions and 3 deletions
|
@ -1604,7 +1604,8 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
|
|||
- If no dict arguments are passed, an attempt is made to use the
|
||||
globals from obj (or the respective module's globals for classes),
|
||||
and these are also used as the locals. If the object does not appear
|
||||
to have globals, an empty dictionary is used.
|
||||
to have globals, an empty dictionary is used. For classes, the search
|
||||
order is globals first then locals.
|
||||
|
||||
- If one dict argument is passed, it is used for both globals and
|
||||
locals.
|
||||
|
@ -1628,6 +1629,14 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
|
|||
base_globals = globalns
|
||||
ann = base.__dict__.get('__annotations__', {})
|
||||
base_locals = dict(vars(base)) if localns is None else localns
|
||||
if localns is None and globalns is None:
|
||||
# This is surprising, but required. Before Python 3.10,
|
||||
# get_type_hints only evaluated the globalns of
|
||||
# a class. To maintain backwards compatibility, we reverse
|
||||
# the globalns and localns order so that eval() looks into
|
||||
# *base_globals* first rather than *base_locals*.
|
||||
# This only affects ForwardRefs.
|
||||
base_globals, base_locals = base_locals, base_globals
|
||||
for name, value in ann.items():
|
||||
if value is None:
|
||||
value = type(None)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue