aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/typing.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/typing.py')
-rw-r--r--Lib/typing.py52
1 files changed, 25 insertions, 27 deletions
diff --git a/Lib/typing.py b/Lib/typing.py
index 98af61be8b0..ed1dd4fc641 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -956,12 +956,8 @@ def evaluate_forward_ref(
"""Evaluate a forward reference as a type hint.
This is similar to calling the ForwardRef.evaluate() method,
- but unlike that method, evaluate_forward_ref() also:
-
- * Recursively evaluates forward references nested within the type hint.
- * Rejects certain objects that are not valid type hints.
- * Replaces type hints that evaluate to None with types.NoneType.
- * Supports the *FORWARDREF* and *STRING* formats.
+ but unlike that method, evaluate_forward_ref() also
+ recursively evaluates forward references nested within the type hint.
*forward_ref* must be an instance of ForwardRef. *owner*, if given,
should be the object that holds the annotations that the forward reference
@@ -981,23 +977,24 @@ def evaluate_forward_ref(
if forward_ref.__forward_arg__ in _recursive_guard:
return forward_ref
- try:
- value = forward_ref.evaluate(globals=globals, locals=locals,
- type_params=type_params, owner=owner)
- except NameError:
- if format == _lazy_annotationlib.Format.FORWARDREF:
- return forward_ref
- else:
- raise
-
- type_ = _type_check(
- value,
- "Forward references must evaluate to types.",
- is_argument=forward_ref.__forward_is_argument__,
- allow_special_forms=forward_ref.__forward_is_class__,
- )
+ if format is None:
+ format = _lazy_annotationlib.Format.VALUE
+ value = forward_ref.evaluate(globals=globals, locals=locals,
+ type_params=type_params, owner=owner, format=format)
+
+ if (isinstance(value, _lazy_annotationlib.ForwardRef)
+ and format == _lazy_annotationlib.Format.FORWARDREF):
+ return value
+
+ if isinstance(value, str):
+ value = _make_forward_ref(value, module=forward_ref.__forward_module__,
+ owner=owner or forward_ref.__owner__,
+ is_argument=forward_ref.__forward_is_argument__,
+ is_class=forward_ref.__forward_is_class__)
+ if owner is None:
+ owner = forward_ref.__owner__
return _eval_type(
- type_,
+ value,
globals,
locals,
type_params,
@@ -2338,12 +2335,12 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False,
# 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)
if isinstance(value, str):
value = _make_forward_ref(value, is_argument=False, is_class=True)
value = _eval_type(value, base_globals, base_locals, base.__type_params__,
format=format, owner=obj)
+ if value is None:
+ value = type(None)
hints[name] = value
if include_extras or format == Format.STRING:
return hints
@@ -2377,8 +2374,6 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False,
localns = globalns
type_params = getattr(obj, "__type_params__", ())
for name, value in hints.items():
- if value is None:
- value = type(None)
if isinstance(value, str):
# class-level forward refs were handled above, this must be either
# a module-level annotation or a function argument annotation
@@ -2387,7 +2382,10 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False,
is_argument=not isinstance(obj, types.ModuleType),
is_class=False,
)
- hints[name] = _eval_type(value, globalns, localns, type_params, format=format, owner=obj)
+ value = _eval_type(value, globalns, localns, type_params, format=format, owner=obj)
+ if value is None:
+ value = type(None)
+ hints[name] = value
return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()}