upgrade inspect to CPython 3.8.2

This commit is contained in:
CPython dev authored and Jeong YunWon committed 2020-03-15 11:00:23 +09:00
1 parent 5e56b778a2
commit 7ea90f1463
1 file changed
+210 -119
+210 -119
View File
@@ -18,7 +18,7 @@ Here are some of the useful functions provided by this module:
getargvalues(), getcallargs() - get info about function arguments
getfullargspec() - same, with support for Python 3 features
formatargspec(), formatargvalues() - format an argument spec
formatargvalues() - format an argument spec
getouterframes(), getinnerframes() - get info about frames
currentframe() - get the current stack frame
stack(), trace() - get info about frames on the stack or in a traceback
@@ -31,7 +31,7 @@ Here are some of the useful functions provided by this module:
__author__ = ('Ka-Ping Yee <ping@lfw.org>',
'Yury Selivanov <yselivanov@sprymix.com>')
import ast
import abc
import dis
import collections.abc
import enum
@@ -110,7 +110,7 @@ def ismethoddescriptor(object):
def isdatadescriptor(object):
"""Return true if the object is a data descriptor.
Data descriptors have both a __get__ and a __set__ attribute. Examples are
Data descriptors have a __set__ or a __delete__ attribute. Examples are
properties (defined in Python) and getsets and members (defined in C).
Typically, data descriptors will also have __name__ and __doc__ attributes
(properties, getsets, and members have both of these attributes), but this
@@ -119,7 +119,7 @@ def isdatadescriptor(object):
# mutual exclusion
return False
tp = type(object)
return hasattr(tp, "__set__") and hasattr(tp, "__get__")
return hasattr(tp, "__set__") or hasattr(tp, "__delete__")
if hasattr(types, 'MemberDescriptorType'):
# CPython and equivalent
@@ -168,30 +168,38 @@ def isfunction(object):
__kwdefaults__ dict of keyword only parameters with defaults"""
return isinstance(object, types.FunctionType)
def isgeneratorfunction(object):
def _has_code_flag(f, flag):
"""Return true if ``f`` is a function (or a method or functools.partial
wrapper wrapping a function) whose code object has the given ``flag``
set in its flags."""
while ismethod(f):
f = f.__func__
f = functools._unwrap_partial(f)
if not isfunction(f):
return False
return bool(f.__code__.co_flags & flag)
def isgeneratorfunction(obj):
"""Return true if the object is a user-defined generator function.
Generator function objects provide the same attributes as functions.
See help(isfunction) for a list of attributes."""
return bool((isfunction(object) or ismethod(object)) and
object.__code__.co_flags & CO_GENERATOR)
return _has_code_flag(obj, CO_GENERATOR)
def iscoroutinefunction(object):
def iscoroutinefunction(obj):
"""Return true if the object is a coroutine function.
Coroutine functions are defined with "async def" syntax.
"""
return bool((isfunction(object) or ismethod(object)) and
object.__code__.co_flags & CO_COROUTINE)
return _has_code_flag(obj, CO_COROUTINE)
def isasyncgenfunction(object):
def isasyncgenfunction(obj):
"""Return true if the object is an asynchronous generator function.
Asynchronous generator functions are defined with "async def"
syntax and have "yield" expressions in their body.
"""
return bool((isfunction(object) or ismethod(object)) and
object.__code__.co_flags & CO_ASYNC_GENERATOR)
return _has_code_flag(obj, CO_ASYNC_GENERATOR)
def isasyncgen(object):
"""Return true if the object is an asynchronous generator."""
@@ -253,18 +261,25 @@ def iscode(object):
"""Return true if the object is a code object.
Code objects provide these attributes:
co_argcount number of arguments (not including * or ** args)
co_code string of raw compiled bytecode
co_consts tuple of constants used in the bytecode
co_filename name of file in which this code object was created
co_firstlineno number of first line in Python source code
co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
co_lnotab encoded mapping of line numbers to bytecode indices
co_name name with which this code object was defined
co_names tuple of names of local variables
co_nlocals number of local variables
co_stacksize virtual machine stack space required
co_varnames tuple of names of arguments and local variables"""
co_argcount number of arguments (not including *, ** args
or keyword only arguments)
co_code string of raw compiled bytecode
co_cellvars tuple of names of cell variables
co_consts tuple of constants used in the bytecode
co_filename name of file in which this code object was created
co_firstlineno number of first line in Python source code
co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
| 16=nested | 32=generator | 64=nofree | 128=coroutine
| 256=iterable_coroutine | 512=async_generator
co_freevars tuple of names of free variables
co_posonlyargcount number of positional only arguments
co_kwonlyargcount number of keyword only arguments (not including ** arg)
co_lnotab encoded mapping of line numbers to bytecode indices
co_name name with which this code object was defined
co_names tuple of names of local variables
co_nlocals number of local variables
co_stacksize virtual machine stack space required
co_varnames tuple of names of arguments and local variables"""
return isinstance(object, types.CodeType)
def isbuiltin(object):
@@ -285,7 +300,27 @@ def isroutine(object):
def isabstract(object):
"""Return true if the object is an abstract base class (ABC)."""
return bool(isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT)
if not isinstance(object, type):
return False
if object.__flags__ & TPFLAGS_IS_ABSTRACT:
return True
if not issubclass(type(object), abc.ABCMeta):
return False
if hasattr(object, '__abstractmethods__'):
# It looks like ABCMeta.__new__ has finished running;
# TPFLAGS_IS_ABSTRACT should have been accurate.
return False
# It looks like ABCMeta.__new__ has not finished running yet; we're
# probably in __init_subclass__. We'll look for abstractmethods manually.
for name, value in object.__dict__.items():
if getattr(value, "__isabstractmethod__", False):
return True
for base in object.__bases__:
for name in getattr(base, "__abstractmethods__", ()):
value = getattr(object, name, None)
if getattr(value, "__isabstractmethod__", False):
return True
return False
def getmembers(object, predicate=None):
"""Return all members of an object as (name, value) pairs sorted by name.
@@ -362,7 +397,7 @@ def classify_class_attrs(cls):
mro = getmro(cls)
metamro = getmro(type(cls)) # for attributes stored in the metaclass
metamro = tuple([cls for cls in metamro if cls not in (type, object)])
metamro = tuple(cls for cls in metamro if cls not in (type, object))
class_bases = (cls,) + mro
all_bases = class_bases + metamro
names = dir(cls)
@@ -430,10 +465,10 @@ def classify_class_attrs(cls):
continue
obj = get_obj if get_obj is not None else dict_obj
# Classify the object or its descriptor.
if isinstance(dict_obj, staticmethod):
if isinstance(dict_obj, (staticmethod, types.BuiltinMethodType)):
kind = "static method"
obj = dict_obj
elif isinstance(dict_obj, classmethod):
elif isinstance(dict_obj, (classmethod, types.ClassMethodDescriptorType)):
kind = "class method"
obj = dict_obj
elif isinstance(dict_obj, property):
@@ -478,13 +513,16 @@ def unwrap(func, *, stop=None):
def _is_wrapper(f):
return hasattr(f, '__wrapped__') and not stop(f)
f = func # remember the original func for error reporting
memo = {id(f)} # Memoise by id to tolerate non-hashable objects
# Memoise by id to tolerate non-hashable objects, but store objects to
# ensure they aren't destroyed, which would allow their IDs to be reused.
memo = {id(f): f}
recursion_limit = sys.getrecursionlimit()
while _is_wrapper(func):
func = func.__wrapped__
id_func = id(func)
if id_func in memo:
if (id_func in memo) or (len(memo) >= recursion_limit):
raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
memo.add(id_func)
memo[id_func] = func
return func
# -------------------------------------------------- source code extraction
@@ -550,9 +588,12 @@ def _finddoc(obj):
cls = obj.__objclass__
if getattr(cls, name) is not obj:
return None
if ismemberdescriptor(obj):
slots = getattr(cls, '__slots__', None)
if isinstance(slots, dict) and name in slots:
return slots[name]
else:
return None
for base in cls.__mro__:
try:
doc = getattr(base, name).__doc__
@@ -613,14 +654,14 @@ def cleandoc(doc):
def getfile(object):
"""Work out which source or compiled file an object was defined in."""
if ismodule(object):
if hasattr(object, '__file__'):
if getattr(object, '__file__', None):
return object.__file__
raise TypeError('{!r} is a built-in module'.format(object))
if isclass(object):
if hasattr(object, '__module__'):
object = sys.modules.get(object.__module__)
if hasattr(object, '__file__'):
return object.__file__
module = sys.modules.get(object.__module__)
if getattr(module, '__file__', None):
return module.__file__
raise TypeError('{!r} is a built-in class'.format(object))
if ismethod(object):
object = object.__func__
@@ -632,8 +673,9 @@ def getfile(object):
object = object.f_code
if iscode(object):
return object.co_filename
raise TypeError('{!r} is not a module, class, method, '
'function, traceback, frame, or code object'.format(object))
raise TypeError('module, class, method, function, traceback, frame, or '
'code object was expected, got {}'.format(
type(object).__name__))
def getmodulename(path):
"""Return the module name for a given file, or None."""
@@ -924,7 +966,12 @@ def getsourcelines(object):
object = unwrap(object)
lines, lnum = findsource(object)
if ismodule(object):
if istraceback(object):
object = object.tb_frame
# for module or frame that corresponds to module, return all source lines
if (ismodule(object) or
(isframe(object) and object.f_code.co_name == "<module>")):
return lines, 0
else:
return getblock(lines[lnum:]), lnum + 1
@@ -963,7 +1010,7 @@ def getclasstree(classes, unique=False):
for c in classes:
if c.__bases__:
for parent in c.__bases__:
if not parent in children:
if parent not in children:
children[parent] = []
if c not in children[parent]:
children[parent].append(c)
@@ -985,21 +1032,11 @@ def getargs(co):
'args' is the list of argument names. Keyword-only arguments are
appended. 'varargs' and 'varkw' are the names of the * and **
arguments or None."""
args, varargs, kwonlyargs, varkw = _getfullargs(co)
return Arguments(args + kwonlyargs, varargs, varkw)
def _getfullargs(co):
"""Get information about the arguments accepted by a code object.
Four things are returned: (args, varargs, kwonlyargs, varkw), where
'args' and 'kwonlyargs' are lists of argument names, and 'varargs'
and 'varkw' are the names of the * and ** arguments or None."""
if not iscode(co):
raise TypeError('{!r} is not a code object'.format(co))
nargs = co.co_argcount
names = co.co_varnames
nargs = co.co_argcount
nkwargs = co.co_kwonlyargcount
args = list(names[:nargs])
kwonlyargs = list(names[nargs:nargs+nkwargs])
@@ -1013,8 +1050,7 @@ def _getfullargs(co):
varkw = None
if co.co_flags & CO_VARKEYWORDS:
varkw = co.co_varnames[nargs]
return args, varargs, kwonlyargs, varkw
return Arguments(args + kwonlyargs, varargs, varkw)
ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
@@ -1035,15 +1071,17 @@ def getargspec(func):
Alternatively, use getfullargspec() for an API with a similar namedtuple
based interface, but full support for annotations and keyword-only
parameters.
Deprecated since Python 3.5, use `inspect.getfullargspec()`.
"""
warnings.warn("inspect.getargspec() is deprecated, "
warnings.warn("inspect.getargspec() is deprecated since Python 3.0, "
"use inspect.signature() or inspect.getfullargspec()",
DeprecationWarning, stacklevel=2)
args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
getfullargspec(func)
if kwonlyargs or ann:
raise ValueError("Function has keyword-only parameters or annotations"
", use getfullargspec() API which can support them")
", use inspect.signature() API which can support them")
return ArgSpec(args, varargs, varkw, defaults)
FullArgSpec = namedtuple('FullArgSpec',
@@ -1065,7 +1103,6 @@ def getfullargspec(func):
- the "self" parameter is always reported, even for bound methods
- wrapper chains defined by __wrapped__ *not* unwrapped automatically
"""
try:
# Re: `skip_bound_arg=False`
#
@@ -1097,6 +1134,7 @@ def getfullargspec(func):
args = []
varargs = None
varkw = None
posonlyargs = []
kwonlyargs = []
defaults = ()
annotations = {}
@@ -1111,7 +1149,9 @@ def getfullargspec(func):
name = param.name
if kind is _POSITIONAL_ONLY:
args.append(name)
posonlyargs.append(name)
if param.default is not param.empty:
defaults += (param.default,)
elif kind is _POSITIONAL_OR_KEYWORD:
args.append(name)
if param.default is not param.empty:
@@ -1136,7 +1176,7 @@ def getfullargspec(func):
# compatibility with 'func.__defaults__'
defaults = None
return FullArgSpec(args, varargs, varkw, defaults,
return FullArgSpec(posonlyargs + args, varargs, varkw, defaults,
kwonlyargs, kwdefaults, annotations)
@@ -1181,7 +1221,19 @@ def formatargspec(args, varargs=None, varkw=None, defaults=None,
kwonlyargs, kwonlydefaults, annotations). The other five arguments
are the corresponding optional formatting functions that are called to
turn names and values into strings. The last argument is an optional
function to format the sequence of arguments."""
function to format the sequence of arguments.
Deprecated since Python 3.5: use the `signature` function and `Signature`
objects.
"""
from warnings import warn
warn("`formatargspec` is deprecated since Python 3.5. Use `signature` and "
"the `Signature` object directly",
DeprecationWarning,
stacklevel=2)
def formatargandannotation(arg):
result = formatarg(arg)
if arg in annotations:
@@ -1273,14 +1325,12 @@ def _too_many(f_name, args, kwonly, varargs, defcount, given, values):
(f_name, sig, "s" if plural else "", given, kwonly_sig,
"was" if given == 1 and not kwonly_given else "were"))
def getcallargs(*func_and_positional, **named):
def getcallargs(func, /, *positional, **named):
"""Get the mapping of arguments to values.
A dict is returned, with keys the function argument names (including the
names of the * and ** arguments, if any), and values the respective bound
values from 'positional' and 'named'."""
func = func_and_positional[0]
positional = func_and_positional[1:]
spec = getfullargspec(func)
args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec
f_name = func.__name__
@@ -1350,7 +1400,7 @@ def getclosurevars(func):
func = func.__func__
if not isfunction(func):
raise TypeError("'{!r}' is not a Python function".format(func))
raise TypeError("{!r} is not a Python function".format(func))
code = func.__code__
# Nonlocal references are named in co_freevars and resolved
@@ -1416,7 +1466,6 @@ def getframeinfo(frame, context=1):
except OSError:
lines = index = None
else:
start = max(start, 1)
start = max(0, min(start, len(lines) - context))
lines = lines[start:start+context]
index = lineno - 1 - start
@@ -1594,7 +1643,7 @@ def getgeneratorlocals(generator):
bound values."""
if not isgenerator(generator):
raise TypeError("'{!r}' is not a Python generator".format(generator))
raise TypeError("{!r} is not a Python generator".format(generator))
frame = getattr(generator, "gi_frame", None)
if frame is not None:
@@ -1910,6 +1959,9 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
"""Private helper to parse content of '__text_signature__'
and return a Signature based on it.
"""
# Lazy import ast because it's relatively heavy and
# it's not used for other than this function.
import ast
Parameter = cls._parameter_cls
@@ -1939,11 +1991,11 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
module = sys.modules.get(module_name, None)
if module:
module_dict = module.__dict__
sys_module_dict = sys.modules
sys_module_dict = sys.modules.copy()
def parse_name(node):
assert isinstance(node, ast.arg)
if node.annotation != None:
if node.annotation is not None:
raise ValueError("Annotations are not currently supported")
return node.arg
@@ -1956,14 +2008,8 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
except NameError:
raise RuntimeError()
if isinstance(value, str):
return ast.Str(value)
if isinstance(value, (int, float)):
return ast.Num(value)
if isinstance(value, bytes):
return ast.Bytes(value)
if value in (True, False, None):
return ast.NameConstant(value)
if isinstance(value, (str, int, float, bytes, bool, type(None))):
return ast.Constant(value)
raise RuntimeError()
class RewriteSymbolics(ast.NodeTransformer):
@@ -2063,7 +2109,7 @@ def _signature_from_builtin(cls, func, skip_bound_arg=True):
return _signature_fromstr(cls, func, s, skip_bound_arg)
def _signature_from_function(cls, func):
def _signature_from_function(cls, func, skip_bound_arg=True):
"""Private helper: constructs Signature for the given python function."""
is_duck_function = False
@@ -2075,15 +2121,20 @@ def _signature_from_function(cls, func):
# of pure function:
raise TypeError('{!r} is not a Python function'.format(func))
s = getattr(func, "__text_signature__", None)
if s:
return _signature_fromstr(cls, func, s, skip_bound_arg)
Parameter = cls._parameter_cls
# Parameter information.
func_code = func.__code__
pos_count = func_code.co_argcount
arg_names = func_code.co_varnames
positional = tuple(arg_names[:pos_count])
posonly_count = func_code.co_posonlyargcount
positional = arg_names[:pos_count]
keyword_only_count = func_code.co_kwonlyargcount
keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
keyword_only = arg_names[pos_count:pos_count + keyword_only_count]
annotations = func.__annotations__
defaults = func.__defaults__
kwdefaults = func.__kwdefaults__
@@ -2095,19 +2146,27 @@ def _signature_from_function(cls, func):
parameters = []
# Non-keyword-only parameters w/o defaults.
non_default_count = pos_count - pos_default_count
posonly_left = posonly_count
# Non-keyword-only parameters w/o defaults.
for name in positional[:non_default_count]:
kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD
annotation = annotations.get(name, _empty)
parameters.append(Parameter(name, annotation=annotation,
kind=_POSITIONAL_OR_KEYWORD))
kind=kind))
if posonly_left:
posonly_left -= 1
# ... w/ defaults.
for offset, name in enumerate(positional[non_default_count:]):
kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD
annotation = annotations.get(name, _empty)
parameters.append(Parameter(name, annotation=annotation,
kind=_POSITIONAL_OR_KEYWORD,
kind=kind,
default=defaults[offset]))
if posonly_left:
posonly_left -= 1
# *args
if func_code.co_flags & CO_VARARGS:
@@ -2215,16 +2274,23 @@ def _signature_from_callable(obj, *,
sigcls=sigcls)
sig = _signature_get_partial(wrapped_sig, partialmethod, (None,))
first_wrapped_param = tuple(wrapped_sig.parameters.values())[0]
new_params = (first_wrapped_param,) + tuple(sig.parameters.values())
return sig.replace(parameters=new_params)
if first_wrapped_param.kind is Parameter.VAR_POSITIONAL:
# First argument of the wrapped callable is `*args`, as in
# `partialmethod(lambda *args)`.
return sig
else:
sig_params = tuple(sig.parameters.values())
assert (not sig_params or
first_wrapped_param is not sig_params[0])
new_params = (first_wrapped_param,) + sig_params
return sig.replace(parameters=new_params)
if isfunction(obj) or _signature_is_functionlike(obj):
# If it's a pure Python function, or an object that is duck type
# of a Python function (Cython functions, for instance), then:
return _signature_from_function(sigcls, obj)
return _signature_from_function(sigcls, obj,
skip_bound_arg=skip_bound_arg)
if _signature_is_builtin(obj):
return _signature_from_builtin(sigcls, obj,
@@ -2301,7 +2367,7 @@ def _signature_from_callable(obj, *,
if (obj.__init__ is object.__init__ and
obj.__new__ is object.__new__):
# Return a signature of 'object' builtin.
return signature(object)
return sigcls.from_callable(object)
else:
raise ValueError(
'no signature found for builtin type {!r}'.format(obj))
@@ -2357,6 +2423,9 @@ class _ParameterKind(enum.IntEnum):
def __str__(self):
return self._name_
@property
def description(self):
return _PARAM_NAME_MAPPING[self]
_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY
_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD
@@ -2364,6 +2433,14 @@ _VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL
_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY
_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD
_PARAM_NAME_MAPPING = {
_POSITIONAL_ONLY: 'positional-only',
_POSITIONAL_OR_KEYWORD: 'positional or keyword',
_VAR_POSITIONAL: 'variadic positional',
_KEYWORD_ONLY: 'keyword-only',
_VAR_KEYWORD: 'variadic keyword'
}
class Parameter:
"""Represents a parameter in a function signature.
@@ -2398,15 +2475,14 @@ class Parameter:
empty = _empty
def __init__(self, name, kind, *, default=_empty, annotation=_empty):
if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
_VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
raise ValueError("invalid value for 'Parameter.kind' attribute")
self._kind = kind
try:
self._kind = _ParameterKind(kind)
except ValueError:
raise ValueError(f'value {kind!r} is not a valid Parameter.kind')
if default is not _empty:
if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
msg = '{} parameters cannot have default values'.format(kind)
if self._kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
msg = '{} parameters cannot have default values'
msg = msg.format(self._kind.description)
raise ValueError(msg)
self._default = default
self._annotation = annotation
@@ -2415,19 +2491,21 @@ class Parameter:
raise ValueError('name is a required attribute for Parameter')
if not isinstance(name, str):
raise TypeError("name must be a str, not a {!r}".format(name))
msg = 'name must be a str, not a {}'.format(type(name).__name__)
raise TypeError(msg)
if name[0] == '.' and name[1:].isdigit():
# These are implicit arguments generated by comprehensions. In
# order to provide a friendlier interface to users, we recast
# their name as "implicitN" and treat them as positional-only.
# See issue 19611.
if kind != _POSITIONAL_OR_KEYWORD:
raise ValueError(
'implicit arguments must be passed in as {}'.format(
_POSITIONAL_OR_KEYWORD
)
if self._kind != _POSITIONAL_OR_KEYWORD:
msg = (
'implicit arguments must be passed as '
'positional or keyword arguments, not {}'
)
msg = msg.format(self._kind.description)
raise ValueError(msg)
self._kind = _POSITIONAL_ONLY
name = 'implicit{}'.format(name[1:])
@@ -2486,11 +2564,14 @@ class Parameter:
# Add annotation and default value
if self._annotation is not _empty:
formatted = '{}:{}'.format(formatted,
formatted = '{}: {}'.format(formatted,
formatannotation(self._annotation))
if self._default is not _empty:
formatted = '{}={}'.format(formatted, repr(self._default))
if self._annotation is not _empty:
formatted = '{} = {}'.format(formatted, repr(self._default))
else:
formatted = '{}={}'.format(formatted, repr(self._default))
if kind == _VAR_POSITIONAL:
formatted = '*' + formatted
@@ -2695,8 +2776,12 @@ class Signature:
name = param.name
if kind < top_kind:
msg = 'wrong parameter order: {!r} before {!r}'
msg = msg.format(top_kind, kind)
msg = (
'wrong parameter order: {} parameter before {} '
'parameter'
)
msg = msg.format(top_kind.description,
kind.description)
raise ValueError(msg)
elif kind > top_kind:
kind_defaults = False
@@ -2729,19 +2814,25 @@ class Signature:
@classmethod
def from_function(cls, func):
"""Constructs Signature for the given python function."""
"""Constructs Signature for the given python function.
warnings.warn("inspect.Signature.from_function() is deprecated, "
"use Signature.from_callable()",
Deprecated since Python 3.5, use `Signature.from_callable()`.
"""
warnings.warn("inspect.Signature.from_function() is deprecated since "
"Python 3.5, use Signature.from_callable()",
DeprecationWarning, stacklevel=2)
return _signature_from_function(cls, func)
@classmethod
def from_builtin(cls, func):
"""Constructs Signature for the given builtin function."""
"""Constructs Signature for the given builtin function.
warnings.warn("inspect.Signature.from_builtin() is deprecated, "
"use Signature.from_callable()",
Deprecated since Python 3.5, use `Signature.from_callable()`.
"""
warnings.warn("inspect.Signature.from_builtin() is deprecated since "
"Python 3.5, use Signature.from_callable()",
DeprecationWarning, stacklevel=2)
return _signature_from_builtin(cls, func)
@@ -2869,7 +2960,7 @@ class Signature:
arguments[param.name] = tuple(values)
break
if param.name in kwargs:
if param.name in kwargs and param.kind != _POSITIONAL_ONLY:
raise TypeError(
'multiple values for argument {arg!r}'.format(
arg=param.name)) from None
@@ -2926,19 +3017,19 @@ class Signature:
return self._bound_arguments_cls(self, arguments)
def bind(*args, **kwargs):
def bind(self, /, *args, **kwargs):
"""Get a BoundArguments object, that maps the passed `args`
and `kwargs` to the function's signature. Raises `TypeError`
if the passed arguments can not be bound.
"""
return args[0]._bind(args[1:], kwargs)
return self._bind(args, kwargs)
def bind_partial(*args, **kwargs):
def bind_partial(self, /, *args, **kwargs):
"""Get a BoundArguments object, that partially maps the
passed `args` and `kwargs` to the function's signature.
Raises `TypeError` if the passed arguments can not be bound.
"""
return args[0]._bind(args[1:], kwargs, partial=True)
return self._bind(args, kwargs, partial=True)
def __reduce__(self):
return (type(self),
@@ -3027,7 +3118,7 @@ def _main():
type(exc).__name__,
exc)
print(msg, file=sys.stderr)
exit(2)
sys.exit(2)
if has_attrs:
parts = attrs.split(".")
@@ -3037,7 +3128,7 @@ def _main():
if module.__name__ in sys.builtin_module_names:
print("Can't get info for builtin modules.", file=sys.stderr)
exit(1)
sys.exit(1)
if args.details:
print('Target: {}'.format(target))