-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
Description
Feature or enhancement
Some builtin functions accept None as a special value in addition to values that should have the specified type. For example start
and stop
indices in index()
, size
in read()
, dir_fd
in many os
functions, and numerous string parameters, e.g. encoding
and errors
.
There are special format units in PyArg_Parse*
functions for "string or None": z
, z*
, z#
. There is half-public converter _PyEval_SliceIndex
for indices, and several more private converters. But while NULL can non-ambiguously represent None in C, there is no single integer value for None. In many cases it is -1, but it is 0 and Py_SIZE(self)
for indices, AT_FDCWD
for dir_fd
parameter, etc. This is why _PyEval_SliceIndex
keeps the value of the C variable unchanged when the argument is None.
I propose to generalize it to all types. Add the ?
modifier. If it occurs after the format unit, and the argument is None, it keeps the initial value of the C variable, like if the argument was optional and missed. For example:
int dir_fd = AT_FDCWD;
Py_ssize_t size = PY_SSIZE_T_MAX;
double speed = 0.0;
int sep = EOF;
int flag = -1;
if (!PyArg_ParseTuple(args, "i?n?d?C?p?", &dir_fd, &size, &speed, &sep, &flag)) {
return NULL;
}
The code accepts two integers, a float, a character, and an arbitrary object (as boolean), but any of 5 arguments can also be None
, in which case the corresponding variable keeps its initial value.
There was a similar proposition for Argument Clinic: #64540. But this proposition works not only with Argument Clinic, therefore it can be used in third-party code. It works not only with integers, but with all types, including custom converters. It is more convenient, because do not need to use a special structure. I believe that it covers most of use cases, and in few remaining cases you still can handle it manually, as before.
After implementing this for PyArg_Parse*
I will add support in Argument Clinic.
Linked PRs
- gh-112068: C API: Add support of nullable arguments in PyArg_Parse (prefix) #121187
- gh-112068: C API: Add support of nullable arguments in PyArg_Parse (suffix) #121303
- Revert "gh-112068: C API: Add support of nullable arguments in PyArg_Parse (GH-121303)" #136991
- [3.14] Revert "gh-112068: C API: Add support of nullable arguments in PyArg_Parse (GH-121303)" (GH-136991) #137006