summaryrefslogtreecommitdiffstats
path: root/Lib/inspect.py
diff options
context:
space:
mode:
authorBatuhan Taskaya <batuhanosmantaskaya@gmail.com>2020-10-06 20:03:02 (GMT)
committerGitHub <noreply@github.com>2020-10-06 20:03:02 (GMT)
commit044a1048ca93d466965afc027b91a5a9eb9ce23c (patch)
tree94ef2bca072693d83448edef4009dc840c58a3e2 /Lib/inspect.py
parentbef7d299eb911086ea5a7ccf7a9da337e38a8491 (diff)
downloadcpython-044a1048ca93d466965afc027b91a5a9eb9ce23c.zip
cpython-044a1048ca93d466965afc027b91a5a9eb9ce23c.tar.gz
cpython-044a1048ca93d466965afc027b91a5a9eb9ce23c.tar.bz2
bpo-38605: Make 'from __future__ import annotations' the default (GH-20434)
The hard part was making all the tests pass; there are some subtle issues here, because apparently the future import wasn't tested very thoroughly in previous Python versions. For example, `inspect.signature()` returned type objects normally (except for forward references), but strings with the future import. We changed it to try and return type objects by calling `typing.get_type_hints()`, but fall back on returning strings if that function fails (which it may do if there are future references in the annotations that require passing in a specific namespace to resolve).
Diffstat (limited to 'Lib/inspect.py')
-rw-r--r--Lib/inspect.py19
1 files changed, 17 insertions, 2 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 887a342..ac127cb 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -45,6 +45,7 @@ import sys
import tokenize
import token
import types
+import typing
import warnings
import functools
import builtins
@@ -1877,7 +1878,10 @@ def _signature_is_functionlike(obj):
code = getattr(obj, '__code__', None)
defaults = getattr(obj, '__defaults__', _void) # Important to use _void ...
kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here
- annotations = getattr(obj, '__annotations__', None)
+ try:
+ annotations = _get_type_hints(obj)
+ except AttributeError:
+ annotations = None
return (isinstance(code, types.CodeType) and
isinstance(name, str) and
@@ -2118,6 +2122,16 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
return cls(parameters, return_annotation=cls.empty)
+def _get_type_hints(func):
+ try:
+ return typing.get_type_hints(func)
+ except Exception:
+ # First, try to use the get_type_hints to resolve
+ # annotations. But for keeping the behavior intact
+ # if there was a problem with that (like the namespace
+ # can't resolve some annotation) continue to use
+ # string annotations
+ return func.__annotations__
def _signature_from_builtin(cls, func, skip_bound_arg=True):
"""Private helper function to get signature for
@@ -2161,7 +2175,8 @@ def _signature_from_function(cls, func, skip_bound_arg=True):
positional = arg_names[:pos_count]
keyword_only_count = func_code.co_kwonlyargcount
keyword_only = arg_names[pos_count:pos_count + keyword_only_count]
- annotations = func.__annotations__
+ annotations = _get_type_hints(func)
+
defaults = func.__defaults__
kwdefaults = func.__kwdefaults__