[Python-Dev] AC Derby and accepting None for optional positional arguments

Guido van Rossum guido at python.org
Thu Jan 16 07:05:00 CET 2014

On Wed, Jan 15, 2014 at 9:55 PM, Larry Hastings <larry at hastings.org> wrote:
> On 01/15/2014 09:37 PM, Guido van Rossum wrote:
> Well, I think these are mostly artifacts from old times, and usually passing
> None *should* be the same as omitting the argument. But check each case!
> Vajrasky Kok's recent posting to python-dev discusses the same problem.  His
> example is itertools.repeat's second parameter, which is slightly nastier.
> Consider the implementation:
> static PyObject *
> repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
> {
>     repeatobject *ro;
>     PyObject *element;
>     Py_ssize_t cnt = -1;
>     static char *kwargs[] = {"object", "times", NULL};
>     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs,
>                                      &element, &cnt))
>         return NULL;
>     if (PyTuple_Size(args) == 2 && cnt < 0)
>         cnt = 0;
> I draw your attention to the last two lines.  And remember, Argument Clinic
> doesn't provide the "args" and "kwargs" parameters to the "impl" function.
> That means two things:
> itertools.repeat deliberately makes it impossible to provide an argument for
> "times" that behaves the same as not providing the "times" argument, and
> there is currently no way to implement this behavior using Argument Clinic.
> (I'd have to add a hack where impl functions also get args and kwargs.)
> Passing in "None" here is inconvenient as it's an integer argument.  -1
> actually seems like a pretty sane default to mean "repeat forever", but the
> author has gone to some effort to prevent this.  I therefore assume they had
> a very good reason.  So again we seem stuck.
> Are you suggesting that, when converting builtins to Argument Clinic with
> unrepresentable default values, we're permitted to tweak the defaults to
> something representable?

In this specific case it's clear to me that the special-casing of
negative count is intentional -- presumably it emulates sequence
repetition, where e.g. 'a'*-1 == ''.

But not accepting None is laziness -- accepting either a number or
None requires much more effort, if you need to have the number as a C
integer. I'm not sure how AC could make this any easier, unless you
want to special-case maxint or -maxint-1.

In the sha1 example, however, accepting None and converting it to NULL
(without a reference leak, please :-) seems fine though.

--Guido van Rossum (python.org/~guido)

More information about the Python-Dev mailing list