Open Steffenju95 opened 2 months ago
Running your copy-pasted code in current 3.11.9, 3.12.3, and 3.13.0a6 on Windows, print(ba.args, ba.kwargs)
returns ('bla', 'bli') {'bat': 'blub'}
. Note that args
is a tuple, not a dict, as one should expect. There must have been a fix since the 3.12 you have.
Running your copy-pasted code in current 3.11.9, 3.12.3, and 3.13.0a6 on Windows,
print(ba.args, ba.kwargs)
returns('bla', 'bli') {'bat': 'blub'}
. Note thatargs
is a tuple, not a dict, as one should expect. There must have been a fix since the 3.12 you have.
Thank you for you fast reply. You are absolutely right, It's behaves like you said. I should next time check more carefully and copy paste my tested code.
But one point stays. I still think baz='bli'
should be returned as kwargs
, because otherwise there is a lost of information. I regarding to that I corrected my initial post.
I'm just not sure if it's still a bug report or more a feature request. I guess it's depends on, if the actual behavior is intended as it is.
See also #102551
See also #102551
Okay, so it's definitely intended as it is. (I missed that in the PEP 362)
~~I agree with this comment and think it would be good to change the actual behavior: https://github.com/python/cpython/issues/102551#issuecomment-1475438832~~
I also don't see so far an argument against it, beside the PEP defines it different and backward compatibility.
~~For the implementation there is not even a new variable needed as proposed before.
You could just pass the args
and kwargs
argument in addition to argument
and let the property methods assess it instead of extracting it from attributes
and signature
. So nothing would change, beside two more arguments in __init__
and to private attributes _args
and _kwargs
that replaced the code to extract it from attributes
and signature
.~~
But if there are good arguments against it, I think it would be a good idea to address this unintuitive behaviour beside the one sentence in the PEP also in the code doc and here: https://docs.python.org/3/library/inspect.html#inspect.BoundArguments.args
Edit:
I realized in the meantime that beside the feature to reduce the args
and kwargs
to the minimum (See my original Post https://github.com/python/cpython/issues/118577#issue-2279113456), you can change the arguments
dict of BoundArguments
and it will calculate you the correct args
and kwargs
for the new binding. So changing this behaviour as suggested could cause problems. So I root for a better documentation of the unintuitive behaviour.
Please suggest specific doc changes in a comment.
args A tuple of positional arguments values. Dynamically computed by applying the arguments attribute to the corresponding signature. Includes ambiguous arguments (See Note).
kwargs A dict of keyword arguments values. Dynamically computed by applying the arguments attribute to the corresponding signature. Excludes ambiguous arguments (See Note).
Note: The allocation in args and kwargs may not match the inserted args and kwargs in Signature.bind() or Signature.bind_partial(). This concerns argument of the kind POSITIONAL_OR_KEYWORD in cases where they can be passed ambiguous as args or kwargs. In cases of ambiguity the dynamically computation of args and kwargs always simplifies the given arguments as much as possible, by dropping keywords and saving them positional in args. For example:
def test(a=1, b=2, c=3):
pass
sig = signature(test)
ba = sig.bind(a=10, c=13)
>>> ba.args
(10,)
>>> ba.kwargs:
{'c': 13}
Feature Request
Feature description:
In this case the argument
baz
get returned withba.args
, which returns('bla', 'bli')
I expected it inba.kwargs
, but that returns only{bat: 'blub'}
.Binding
baz
positional (bind('bla', 'bli', bat='blub')
) works as expected. Hereba.args
returns('bla', 'bli')
again andba.kwargs
{bat: 'blub'}
.Is this behavior wanted like this? In my perspective it makes more sense when the
BoundArguments
class returnsPOSITIONAL_OR_KEYWORD
arguments as it got it (positional asargs
and keyword askwargs
) and not always asargs
. I think there happens a lost of Information .Edit: At least it not cause errors, because in constellations, where it is necessary to be a keyword it is. So it also could argued against the information lost, that it is a build in feature of simplification of unnecessary keywords.
See the following example:
ba.args
=>('bla',)
ba.kwargs
=>{'baz': 'bli', 'bat': 'blub'}
CPython versions tested on:
3.12
Operating systems tested on:
Windows
Linked PRs