summaryrefslogtreecommitdiff
path: root/Lib/inspect.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/inspect.py')
-rw-r--r--Lib/inspect.py32
1 files changed, 27 insertions, 5 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py
index d6bd8cdb62..781a5320a0 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -1419,9 +1419,11 @@ def getgeneratorlocals(generator):
_WrapperDescriptor = type(type.__call__)
_MethodWrapper = type(all.__call__)
+_ClassMethodWrapper = type(int.__dict__['from_bytes'])
_NonUserDefinedCallables = (_WrapperDescriptor,
_MethodWrapper,
+ _ClassMethodWrapper,
types.BuiltinFunctionType)
@@ -1443,6 +1445,13 @@ def signature(obj):
if not callable(obj):
raise TypeError('{!r} is not a callable object'.format(obj))
+ if (isinstance(obj, _NonUserDefinedCallables) or
+ ismethoddescriptor(obj) or
+ isinstance(obj, type)):
+ sig = Signature.from_builtin(obj)
+ if sig:
+ return sig
+
if isinstance(obj, types.MethodType):
# In this case we skip the first parameter of the underlying
# function (usually `self` or `cls`).
@@ -1460,13 +1469,9 @@ def signature(obj):
if sig is not None:
return sig
-
if isinstance(obj, types.FunctionType):
return Signature.from_function(obj)
- if isinstance(obj, types.BuiltinFunctionType):
- return Signature.from_builtin(obj)
-
if isinstance(obj, functools.partial):
sig = signature(obj.func)
@@ -2033,7 +2038,7 @@ class Signature:
name = parse_name(name_node)
if name is invalid:
return None
- if default_node:
+ if default_node and default_node is not _empty:
try:
default_node = RewriteSymbolics().visit(default_node)
o = ast.literal_eval(default_node)
@@ -2066,6 +2071,23 @@ class Signature:
kind = Parameter.VAR_KEYWORD
p(f.args.kwarg, empty)
+ if parameters and (hasattr(func, '__self__') or
+ isinstance(func, _WrapperDescriptor,) or
+ ismethoddescriptor(func)
+ ):
+ name = parameters[0].name
+ if name not in ('self', 'module', 'type'):
+ pass
+ elif getattr(func, '__self__', None):
+ # strip off self (it's already been bound)
+ p = parameters.pop(0)
+ if not p.name in ('self', 'module', 'type'):
+ raise ValueError('Unexpected name ' + repr(p.name) + ', expected self/module/cls/type')
+ else:
+ # for builtins, self parameter is always positional-only!
+ p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY)
+ parameters[0] = p
+
return cls(parameters, return_annotation=cls.empty)