The built-in int
takes two parameters:
>>> print(int.__doc__)
int(x=0) -> integer
int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments
...
However, (in CPython 3.4.0) inspect.signature
shows 0:
>>> len(inspect.signature(int).parameters)
0
in contrast with a user-defined function:
>>> def my_int(x, base=10):
... return int(x, base)
...
>>> len(inspect.signature(my_int).parameters)
2
The docs for inspect.signature
do say:
Some callables may not be introspectable in certain implementations of Python. For example, in CPython, some built-in functions defined in C provide no metadata about their arguments.
But they also say:
Raises ValueError if no signature can be provided, and TypeError if that type of object is not supported.
So I am surprised that I did not get a ValueError
and instead got what appears to be an incorrect signature.
Is there a way to reliably (and programmatically) determine when it is not possible to get the parameters for a callable with inspect
? That is, if I am given something like int
, is there a way to distinguish between "this thing does not have any parameters" and "it is not possible to determine what parameters this thing has"?
There's an open bug report for this: http://bugs.python.org/issue23934
The problem is that if the obj passed to signature()
is a 'type', and it doesn't have a user defined init or new, it just gives up and returns the signature for object
, which has 0 parameters.
If the obj is in the builtins module, and it's a 'type', but not an Exception, there's a pretty good chance it's not going to work with signature()
.
I came up with this workaround to find the problem objs... It's not particularly elegant, but it may be useful to you:
def count_params():
output = {}
for funcname in dir(builtins):
f = getattr( builtins,funcname)
if isinstance(f, type):
try:
paramcount = len(inspect.signature(f).parameters)
output[funcname] = paramcount
except:
pass
#print("%s is a %s" % (funcname, type(f)))
return output
Output:
{'__loader__': 0,
'bool': 0,
'bytes': 0,
'complex': 0,
'enumerate': 0,
'filter': 0,
'float': 0,
'frozenset': 0,
'int': 0,
'map': 0,
'memoryview': 0,
'object': 0,
'range': 0,
'reversed': 0,
'slice': 0,
'str': 0,
'tuple': 0,
'zip': 0}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With