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:
/*[clinic input]
test.func -> int
x: object
y: object = None
*
z: object = None
Test function
[clinic start generated code]*/
This produces
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf);
if (!args) {
goto exit;
}
x = args[0];
if (!noptargs) {
goto skip_optional_pos;
}
if (args[1]) {
y = args[1];
if (!--noptargs) {
goto skip_optional_pos;
}
}
skip_optional_pos:
if (!noptargs) {
goto skip_optional_kwonly;
}
z = args[2];
skip_optional_kwonly:
_return_value = test_func_impl(module, x, y, z);
Note that all gotos to skip_optional_pos happen only when !noptargs, but skip_optional_pos first checks the exact same condition and immediately jumps to skip_optional_kwonly. We can remove this double jump and extra check and instead generate simpler code:
x = args[0];
if (!noptargs) {
goto skip_optional;
}
if (args[1]) {
y = args[1];
if (!--noptargs) {
goto skip_optional;
}
}
z = args[2];
skip_optional:
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 and skip_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 check nargs.)
CC @erlend-aasland @AlexWaygood @serhiy-storchaka
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
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_poshappen only when!noptargs, butskip_optional_posfirst 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
zis not keyword-only but a regular positional argument.In general, it does not seem to make sense to have separate
skip_optional_posandskip_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
Linked PRs