Consider this example:
>>>defa(p, /, a, b=2, *, f): ...
... >>>importinspect>>>inspect.getcallargs(a, p=1, a=2, b=3, f=4)
{'p': 1, 'a': 2, 'b': 3, 'f': 4}Compare it with the runtime:
>>>defa(p, /, a, b=2, *, f): ...
... >>>a(p=1, a=2, b=3, f=4)
Traceback (mostrecentcalllast):
File"<stdin>", line1, in<module>TypeError: a() gotsomepositional-onlyargumentspassedaskeywordarguments: 'p'
And with inspect.signature.bind:
>>>inspect.signature(a).bind(p=1, a=2, b=3, f=4)
Traceback (mostrecentcalllast):
File"<stdin>", line1, in<module>File"/Users/sobolev/Desktop/cpython/Lib/inspect.py", line3294, inbindreturnself._bind(args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^File"/Users/sobolev/Desktop/cpython/Lib/inspect.py", line3186, in_bindraiseTypeError(msg) fromNoneTypeError: 'p'parameterispositionalonly, butwaspassedasakeyword
The issue itself is not easy to fix, because inside getcallargs uses getfullargspec, which does not differentiate pos-only from pos-or-keyword:
| spec=getfullargspec(func) |
| args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann=spec |
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.
Linked PRs
Consider this example:
Compare it with the runtime:
And with
inspect.signature.bind:The issue itself is not easy to fix, because inside
getcallargsusesgetfullargspec, which does not differentiate pos-only from pos-or-keyword:cpython/Lib/inspect.py
Lines 1582 to 1583 in 39ef93e
So, we cannot know that
pis pos-only.Note that
inspect.getcallargsis deprecated in the docs.So, I propose deprecating
getcallargswith aDeprecationWarningin3.13.Linked PRs