Open eltoder opened 10 months ago
Two labels are needed if there are required keyword-only parameters.
/*[clinic input]
test.func -> int
x: object
y: object = None
*
z: object
t: object = None
Test function
[clinic start generated code]*/
It is not currently supported by PyArg_ParseTupleWithKeywords()
, but there are plans to support it.
If it is possible to make Argument Clinic to generate simpler code in special cases without significant complication of the generator code -- it would be good. The current code is a compromise between simplicity of the generator and efficiency of the generated code. I believe that modern C compilers are smart enough to eliminate unneeded tests and jumps, so it only affects human readability.
Two labels are needed if there are required keyword-only parameters.
Can you elaborate why is it required? If there are required keyword-only arguments, noptargs
will never reach 0 until we get to the keyword-only arguments, so all gotos before that can be omitted.
I believe that modern C compilers are smart enough to eliminate unneeded tests and jumps, so it only affects human readability.
C compilers can optimize the jumps, but there's no way for them to remove the extra check. This relies on the contract of _PyArg_UnpackKeywords() function that is not known to compilers.
Can you elaborate why is it required? If there are required keyword-only arguments,
noptargs
will never reach 0 until we get to the keyword-only arguments, so all gotos before that can be omitted.
Ah, I take it back. Yes, in this case you can make use of 2 labels.
It seems straightforward to use 2 labels when there are required keyword-only arguments and 1 label when there are only optional keyword-only arguments. The biggest issue seems to be that the former case is not actually supported yet, so there is no way to test that it works :-)
Bug report
Bug description:
Generated code for argument parsing contains redundant gotos when there are both positional and keyword-only arguments with default values. Take this example:
This produces
Note that all gotos to
skip_optional_pos
happen only when!noptargs
, butskip_optional_pos
first checks the exact same condition and immediately jumps toskip_optional_kwonly
. We can remove this double jump and extra check and instead generate simpler code:This code is generated if
z
is not keyword-only but a regular positional argument.In general, it does not seem to make sense to have separate
skip_optional_pos
andskip_optional_kwonly
, since there is no way to tell them apart. We only have the combined number of optional arguments (noptargs
), which includes both positional and keyword only. (This is unlike positional-only arguments, where we can also checknargs
.)CC @erlend-aasland @AlexWaygood @serhiy-storchaka
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux