mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
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).
This commit is contained in:
parent
bef7d299eb
commit
044a1048ca
27 changed files with 403 additions and 299 deletions
|
@ -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__
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue