Open
Description
Consider this example:
>>> def a(p, /, a, b=2, *, f): ...
...
>>> import inspect
>>> inspect.getcallargs(a, p=1, a=2, b=3, f=4)
{'p': 1, 'a': 2, 'b': 3, 'f': 4}
Compare it with the runtime:
>>> def a(p, /, a, b=2, *, f): ...
...
>>> a(p=1, a=2, b=3, f=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: a() got some positional-only arguments passed as keyword arguments: 'p'
And with inspect.signature.bind
:
>>> inspect.signature(a).bind(p=1, a=2, b=3, f=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/sobolev/Desktop/cpython/Lib/inspect.py", line 3294, in bind
return self._bind(args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/sobolev/Desktop/cpython/Lib/inspect.py", line 3186, in _bind
raise TypeError(msg) from None
TypeError: 'p' parameter is positional only, but was passed as a keyword
The issue itself is not easy to fix, because inside getcallargs
uses getfullargspec
, which does not differentiate pos-only from pos-or-keyword:
Lines 1582 to 1583 in 39ef93e
So, we cannot know that p
is pos-only.
Note that inspect.getcallargs
is deprecated in the docs.
So, I propose deprecating getcallargs
with a DeprecationWarning
in 3.13
.