update
This commit is contained in:
238
.CondaPkg/env/Lib/inspect.py
vendored
238
.CondaPkg/env/Lib/inspect.py
vendored
@@ -160,6 +160,7 @@ import builtins
|
||||
from keyword import iskeyword
|
||||
from operator import attrgetter
|
||||
from collections import namedtuple, OrderedDict
|
||||
from weakref import ref as make_weakref
|
||||
|
||||
# Create constants for the compiler flags in Include/code.h
|
||||
# We try to get them from dis to avoid duplication
|
||||
@@ -279,7 +280,13 @@ def get_annotations(obj, *, globals=None, locals=None, eval_str=False):
|
||||
if globals is None:
|
||||
globals = obj_globals
|
||||
if locals is None:
|
||||
locals = obj_locals
|
||||
locals = obj_locals or {}
|
||||
|
||||
# "Inject" type parameters into the local namespace
|
||||
# (unless they are shadowed by assignments *in* the local namespace),
|
||||
# as a way of emulating annotation scopes when calling `eval()`
|
||||
if type_params := getattr(obj, "__type_params__", ()):
|
||||
locals = {param.__name__: param for param in type_params} | locals
|
||||
|
||||
return_value = {key:
|
||||
value if not isinstance(value, str) else eval(value, globals, locals)
|
||||
@@ -400,13 +407,13 @@ def isgeneratorfunction(obj):
|
||||
return _has_code_flag(obj, CO_GENERATOR)
|
||||
|
||||
# A marker for markcoroutinefunction and iscoroutinefunction.
|
||||
_is_coroutine_marker = object()
|
||||
_is_coroutine_mark = object()
|
||||
|
||||
def _has_coroutine_mark(f):
|
||||
while ismethod(f):
|
||||
f = f.__func__
|
||||
f = functools._unwrap_partial(f)
|
||||
return getattr(f, "_is_coroutine_marker", None) is _is_coroutine_marker
|
||||
return getattr(f, "_is_coroutine_marker", None) is _is_coroutine_mark
|
||||
|
||||
def markcoroutinefunction(func):
|
||||
"""
|
||||
@@ -414,7 +421,7 @@ def markcoroutinefunction(func):
|
||||
"""
|
||||
if hasattr(func, '__func__'):
|
||||
func = func.__func__
|
||||
func._is_coroutine_marker = _is_coroutine_marker
|
||||
func._is_coroutine_marker = _is_coroutine_mark
|
||||
return func
|
||||
|
||||
def iscoroutinefunction(obj):
|
||||
@@ -760,18 +767,14 @@ def unwrap(func, *, stop=None):
|
||||
:exc:`ValueError` is raised if a cycle is encountered.
|
||||
|
||||
"""
|
||||
if stop is None:
|
||||
def _is_wrapper(f):
|
||||
return hasattr(f, '__wrapped__')
|
||||
else:
|
||||
def _is_wrapper(f):
|
||||
return hasattr(f, '__wrapped__') and not stop(f)
|
||||
f = func # remember the original func for error reporting
|
||||
# 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):
|
||||
while not isinstance(func, type) and hasattr(func, '__wrapped__'):
|
||||
if stop is not None and stop(func):
|
||||
break
|
||||
func = func.__wrapped__
|
||||
id_func = id(func)
|
||||
if (id_func in memo) or (len(memo) >= recursion_limit):
|
||||
@@ -1802,9 +1805,16 @@ def _check_class(klass, attr):
|
||||
return entry.__dict__[attr]
|
||||
return _sentinel
|
||||
|
||||
|
||||
@functools.lru_cache()
|
||||
def _shadowed_dict_from_mro_tuple(mro):
|
||||
for entry in mro:
|
||||
def _shadowed_dict_from_weakref_mro_tuple(*weakref_mro):
|
||||
for weakref_entry in weakref_mro:
|
||||
# Normally we'd have to check whether the result of weakref_entry()
|
||||
# is None here, in case the object the weakref is pointing to has died.
|
||||
# In this specific case, however, we know that the only caller of this
|
||||
# function is `_shadowed_dict()`, and that therefore this weakref is
|
||||
# guaranteed to point to an object that is still alive.
|
||||
entry = weakref_entry()
|
||||
dunder_dict = _get_dunder_dict_of_class(entry)
|
||||
if '__dict__' in dunder_dict:
|
||||
class_dict = dunder_dict['__dict__']
|
||||
@@ -1814,8 +1824,19 @@ def _shadowed_dict_from_mro_tuple(mro):
|
||||
return class_dict
|
||||
return _sentinel
|
||||
|
||||
|
||||
def _shadowed_dict(klass):
|
||||
return _shadowed_dict_from_mro_tuple(_static_getmro(klass))
|
||||
# gh-118013: the inner function here is decorated with lru_cache for
|
||||
# performance reasons, *but* make sure not to pass strong references
|
||||
# to the items in the mro. Doing so can lead to unexpected memory
|
||||
# consumption in cases where classes are dynamically created and
|
||||
# destroyed, and the dynamically created classes happen to be the only
|
||||
# objects that hold strong references to other objects that take up a
|
||||
# significant amount of memory.
|
||||
return _shadowed_dict_from_weakref_mro_tuple(
|
||||
*[make_weakref(entry) for entry in _static_getmro(klass)]
|
||||
)
|
||||
|
||||
|
||||
def getattr_static(obj, attr, default=_sentinel):
|
||||
"""Retrieve attributes without triggering dynamic lookup via the
|
||||
@@ -2007,15 +2028,17 @@ def _signature_get_user_defined_method(cls, method_name):
|
||||
named ``method_name`` and returns it only if it is a
|
||||
pure python function.
|
||||
"""
|
||||
try:
|
||||
meth = getattr(cls, method_name)
|
||||
except AttributeError:
|
||||
return
|
||||
if method_name == '__new__':
|
||||
meth = getattr(cls, method_name, None)
|
||||
else:
|
||||
if not isinstance(meth, _NonUserDefinedCallables):
|
||||
# Once '__signature__' will be added to 'C'-level
|
||||
# callables, this check won't be necessary
|
||||
return meth
|
||||
meth = getattr_static(cls, method_name, None)
|
||||
if meth is None or isinstance(meth, _NonUserDefinedCallables):
|
||||
# Once '__signature__' will be added to 'C'-level
|
||||
# callables, this check won't be necessary
|
||||
return None
|
||||
if method_name != '__new__':
|
||||
meth = _descriptor_get(meth, cls)
|
||||
return meth
|
||||
|
||||
|
||||
def _signature_get_partial(wrapped_sig, partial, extra_args=()):
|
||||
@@ -2128,8 +2151,10 @@ def _signature_is_builtin(obj):
|
||||
ismethoddescriptor(obj) or
|
||||
isinstance(obj, _NonUserDefinedCallables) or
|
||||
# Can't test 'isinstance(type)' here, as it would
|
||||
# also be True for regular python classes
|
||||
obj in (type, object))
|
||||
# also be True for regular python classes.
|
||||
# Can't use the `in` operator here, as it would
|
||||
# invoke the custom __eq__ method.
|
||||
obj is type or obj is object)
|
||||
|
||||
|
||||
def _signature_is_functionlike(obj):
|
||||
@@ -2460,6 +2485,15 @@ def _signature_from_function(cls, func, skip_bound_arg=True,
|
||||
__validate_parameters__=is_duck_function)
|
||||
|
||||
|
||||
def _descriptor_get(descriptor, obj):
|
||||
if isclass(descriptor):
|
||||
return descriptor
|
||||
get = getattr(type(descriptor), '__get__', _sentinel)
|
||||
if get is _sentinel:
|
||||
return descriptor
|
||||
return get(descriptor, obj, type(obj))
|
||||
|
||||
|
||||
def _signature_from_callable(obj, *,
|
||||
follow_wrapper_chains=True,
|
||||
skip_bound_arg=True,
|
||||
@@ -2568,7 +2602,6 @@ def _signature_from_callable(obj, *,
|
||||
wrapped_sig = _get_signature_of(obj.func)
|
||||
return _signature_get_partial(wrapped_sig, obj)
|
||||
|
||||
sig = None
|
||||
if isinstance(obj, type):
|
||||
# obj is a class or a metaclass
|
||||
|
||||
@@ -2576,88 +2609,65 @@ def _signature_from_callable(obj, *,
|
||||
# in its metaclass
|
||||
call = _signature_get_user_defined_method(type(obj), '__call__')
|
||||
if call is not None:
|
||||
sig = _get_signature_of(call)
|
||||
else:
|
||||
factory_method = None
|
||||
new = _signature_get_user_defined_method(obj, '__new__')
|
||||
init = _signature_get_user_defined_method(obj, '__init__')
|
||||
return _get_signature_of(call)
|
||||
|
||||
# Go through the MRO and see if any class has user-defined
|
||||
# pure Python __new__ or __init__ method
|
||||
for base in obj.__mro__:
|
||||
# Now we check if the 'obj' class has an own '__new__' method
|
||||
if new is not None and '__new__' in base.__dict__:
|
||||
factory_method = new
|
||||
break
|
||||
# or an own '__init__' method
|
||||
elif init is not None and '__init__' in base.__dict__:
|
||||
factory_method = init
|
||||
break
|
||||
new = _signature_get_user_defined_method(obj, '__new__')
|
||||
init = _signature_get_user_defined_method(obj, '__init__')
|
||||
|
||||
if factory_method is not None:
|
||||
sig = _get_signature_of(factory_method)
|
||||
# Go through the MRO and see if any class has user-defined
|
||||
# pure Python __new__ or __init__ method
|
||||
for base in obj.__mro__:
|
||||
# Now we check if the 'obj' class has an own '__new__' method
|
||||
if new is not None and '__new__' in base.__dict__:
|
||||
sig = _get_signature_of(new)
|
||||
if skip_bound_arg:
|
||||
sig = _signature_bound_method(sig)
|
||||
return sig
|
||||
# or an own '__init__' method
|
||||
elif init is not None and '__init__' in base.__dict__:
|
||||
return _get_signature_of(init)
|
||||
|
||||
if sig is None:
|
||||
# At this point we know, that `obj` is a class, with no user-
|
||||
# defined '__init__', '__new__', or class-level '__call__'
|
||||
# At this point we know, that `obj` is a class, with no user-
|
||||
# defined '__init__', '__new__', or class-level '__call__'
|
||||
|
||||
for base in obj.__mro__[:-1]:
|
||||
# Since '__text_signature__' is implemented as a
|
||||
# descriptor that extracts text signature from the
|
||||
# class docstring, if 'obj' is derived from a builtin
|
||||
# class, its own '__text_signature__' may be 'None'.
|
||||
# Therefore, we go through the MRO (except the last
|
||||
# class in there, which is 'object') to find the first
|
||||
# class with non-empty text signature.
|
||||
try:
|
||||
text_sig = base.__text_signature__
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
if text_sig:
|
||||
# If 'base' class has a __text_signature__ attribute:
|
||||
# return a signature based on it
|
||||
return _signature_fromstr(sigcls, base, text_sig)
|
||||
|
||||
# No '__text_signature__' was found for the 'obj' class.
|
||||
# Last option is to check if its '__init__' is
|
||||
# object.__init__ or type.__init__.
|
||||
if type not in obj.__mro__:
|
||||
# We have a class (not metaclass), but no user-defined
|
||||
# __init__ or __new__ for it
|
||||
if (obj.__init__ is object.__init__ and
|
||||
obj.__new__ is object.__new__):
|
||||
# Return a signature of 'object' builtin.
|
||||
return sigcls.from_callable(object)
|
||||
else:
|
||||
raise ValueError(
|
||||
'no signature found for builtin type {!r}'.format(obj))
|
||||
|
||||
elif not isinstance(obj, _NonUserDefinedCallables):
|
||||
# An object with __call__
|
||||
# We also check that the 'obj' is not an instance of
|
||||
# types.WrapperDescriptorType or types.MethodWrapperType to avoid
|
||||
# infinite recursion (and even potential segfault)
|
||||
call = _signature_get_user_defined_method(type(obj), '__call__')
|
||||
if call is not None:
|
||||
for base in obj.__mro__[:-1]:
|
||||
# Since '__text_signature__' is implemented as a
|
||||
# descriptor that extracts text signature from the
|
||||
# class docstring, if 'obj' is derived from a builtin
|
||||
# class, its own '__text_signature__' may be 'None'.
|
||||
# Therefore, we go through the MRO (except the last
|
||||
# class in there, which is 'object') to find the first
|
||||
# class with non-empty text signature.
|
||||
try:
|
||||
sig = _get_signature_of(call)
|
||||
except ValueError as ex:
|
||||
msg = 'no signature found for {!r}'.format(obj)
|
||||
raise ValueError(msg) from ex
|
||||
text_sig = base.__text_signature__
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
if text_sig:
|
||||
# If 'base' class has a __text_signature__ attribute:
|
||||
# return a signature based on it
|
||||
return _signature_fromstr(sigcls, base, text_sig)
|
||||
|
||||
if sig is not None:
|
||||
# For classes and objects we skip the first parameter of their
|
||||
# __call__, __new__, or __init__ methods
|
||||
if skip_bound_arg:
|
||||
return _signature_bound_method(sig)
|
||||
else:
|
||||
return sig
|
||||
# No '__text_signature__' was found for the 'obj' class.
|
||||
# Last option is to check if its '__init__' is
|
||||
# object.__init__ or type.__init__.
|
||||
if type not in obj.__mro__:
|
||||
# We have a class (not metaclass), but no user-defined
|
||||
# __init__ or __new__ for it
|
||||
if (obj.__init__ is object.__init__ and
|
||||
obj.__new__ is object.__new__):
|
||||
# Return a signature of 'object' builtin.
|
||||
return sigcls.from_callable(object)
|
||||
else:
|
||||
raise ValueError(
|
||||
'no signature found for builtin type {!r}'.format(obj))
|
||||
|
||||
if isinstance(obj, types.BuiltinFunctionType):
|
||||
# Raise a nicer error message for builtins
|
||||
msg = 'no signature found for builtin function {!r}'.format(obj)
|
||||
raise ValueError(msg)
|
||||
else:
|
||||
# An object with __call__
|
||||
call = getattr_static(type(obj), '__call__', None)
|
||||
if call is not None:
|
||||
call = _descriptor_get(call, obj)
|
||||
return _get_signature_of(call)
|
||||
|
||||
raise ValueError('callable {!r} is not supported by signature'.format(obj))
|
||||
|
||||
@@ -3125,6 +3135,8 @@ class Signature:
|
||||
parameters_ex = ()
|
||||
arg_vals = iter(args)
|
||||
|
||||
pos_only_param_in_kwargs = []
|
||||
|
||||
while True:
|
||||
# Let's iterate through the positional arguments and corresponding
|
||||
# parameters
|
||||
@@ -3145,10 +3157,10 @@ class Signature:
|
||||
break
|
||||
elif param.name in kwargs:
|
||||
if param.kind == _POSITIONAL_ONLY:
|
||||
msg = '{arg!r} parameter is positional only, ' \
|
||||
'but was passed as a keyword'
|
||||
msg = msg.format(arg=param.name)
|
||||
raise TypeError(msg) from None
|
||||
# Raise a TypeError once we are sure there is no
|
||||
# **kwargs param later.
|
||||
pos_only_param_in_kwargs.append(param)
|
||||
continue
|
||||
parameters_ex = (param,)
|
||||
break
|
||||
elif (param.kind == _VAR_KEYWORD or
|
||||
@@ -3230,20 +3242,22 @@ class Signature:
|
||||
format(arg=param_name)) from None
|
||||
|
||||
else:
|
||||
if param.kind == _POSITIONAL_ONLY:
|
||||
# This should never happen in case of a properly built
|
||||
# Signature object (but let's have this check here
|
||||
# to ensure correct behaviour just in case)
|
||||
raise TypeError('{arg!r} parameter is positional only, '
|
||||
'but was passed as a keyword'. \
|
||||
format(arg=param.name))
|
||||
|
||||
arguments[param_name] = arg_val
|
||||
|
||||
if kwargs:
|
||||
if kwargs_param is not None:
|
||||
# Process our '**kwargs'-like parameter
|
||||
arguments[kwargs_param.name] = kwargs
|
||||
elif pos_only_param_in_kwargs:
|
||||
raise TypeError(
|
||||
'got some positional-only arguments passed as '
|
||||
'keyword arguments: {arg!r}'.format(
|
||||
arg=', '.join(
|
||||
param.name
|
||||
for param in pos_only_param_in_kwargs
|
||||
),
|
||||
),
|
||||
)
|
||||
else:
|
||||
raise TypeError(
|
||||
'got an unexpected keyword argument {arg!r}'.format(
|
||||
|
||||
Reference in New Issue
Block a user