GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — gh-108494: Argument Clinic: inline parsing code for positional-only parameters in the limited C API by serhiy-storchaka · Pull Request #108622 · python/cpython Conversation
|
| pl = '' if min_pos == 1 else 's' | ||
| parser_code.append(normalize_snippet(f""" | ||
| if ({nargs} != {min_pos}) {{{{ | ||
| PyErr_Format(PyExc_TypeError, "{{name}} expected {min_pos} argument{pl}, got %zd", {nargs}); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This generate many static C strings for similar error messages. Would it make sense to pass name and min_pos (and "s" for plural) as argument to PyErr_Format(), and have a unique format string? It would be faster but make the Python binary smaller and use less memory.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
_PyArg_BadArgument() is has 4 parameters, but it is not generic enough yet. It formats an error message in the style of some error messages formatted in PyArg_ParseTuple() and PyArg_ParseTupleAndKeywords(), but even these functions has cases which cannot be covered by _PyArg_BadArgument() ("must be %d-item sequence", "must be sequence of length %d"), and there are many other forms of error messages for wrong type of argument in the rest of code. If _PyArg_BadArgument() be general enough and used in many other places outside of Argument Clinic generated code, it will bi worth to add it to the public API.
On other hand, PyErr_Format() is extremely general and flexible variant of _PyArg_BadArgument().
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| indent=4)) | ||
| else: | ||
| parser_code = [normalize_snippet(f""" | ||
| if (!_PyArg_CheckPositional("{{name}}", {nargs}, {min_pos}, {max_args})) {{{{ |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
What about moving _PyArg_CheckPositional() to the limited C API?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Yes, it can be done, together with _PyArg_NoKeywords(), _PyArg_NoPositional() and _PyArg_NoKwnames().
But the main problem is handling keyword arguments, so I want to add new API only when we see the whole image.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| elif (not requires_defining_class and pos_only == len(parameters) and | ||
| not pseudo_args and limited_capi): | ||
| # positional-only for the limited C API |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
It is no longer needed, because there is other PyArg_ParseTuple() below which is used if inlining the parsing code failed. PyArg_UnpackTuple() no longer used, because inlining is always successful in this simple case.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| nargs = f"Py_MIN(nargs, {max_pos})" if max_pos else "0" | ||
|
|
||
| if limited_capi: | ||
| # positional-or-keyword arguments |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
It was moved down, to a fallback code used if inlining failed. For now, it always failed for limited_capi, because there is no public variant of _PyArg_UnpackKeywords.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanatory review comments.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
I don't have the bandwith to review the generated C param parsing code. I guess Victor does a better job of reviewing that, than me. If Alex is fine with the clinic.py changes, you are good to go. BTW, I really like the introduction of the |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ditto to what Erlend said: I can't really review the generated C code, but I approve of the concept and the clinic.py changes look good to me
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
LGTM. The overall change LGTM. clinic.py coding style makes reviews really complicated :-( I prefer testing fastcall than new_or_init, that's a nice improvment.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
nice work! if there are bugs lurking in here (it is hard to visually spot everything in this kind of large clinic.py change) i'm sure they'll show themselves in generated code behaviors that can be fixed up later.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
There's a new commit after the PR has been approved. @gpshead, @vstinner, @erlend-aasland, @AlexWaygood: please review the changes made to this pull request. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.