[Python-3000] Interaction between unittest and keyword argument machinery

Patrick Maupin pmaupin at gmail.com
Wed Mar 7 16:22:52 CET 2007


> > Because unittest always creates **kwargs, any code path in a C
> > function which is only executed when the *keywords parameter is NULL
> > will never be correctly tested from the standard unittest methods.
>
> This needs some context; which call from unittest to a C function are
> you talking about?

Umm, my broken ones? :)  In doing some personal doctesting, I noticed
an issue in my PEP3101 code with a null pointer, and added a test to
the unittest code to catch it in preparation for fixing it.  My
unittest code never failed, and I realized that the unittest module
was always passing down a keyword dictionary, even when no keywords
were passed to it.  I'm sure that most Python C programmers are more
experienced/careful than I am, but even so,  it seems that there are a
whole class of potential bugs in C functions that unittest cannot
check for at present, because it always passes a keywords dictionary.

>
> > doctest doesn't have this issue, but appears to be deprecated.
>
> Far from it! Doctest is alive and well. I even used it to test the
> xreload module I added to Py3k. I admit that I've not been a fan of it
> in the past, and in many cases I will prefer unittest, but there are
> definitely very good reasons to support doctest. Consider it a rare
> deviation from TOOWTDI.

The documentation for the "test" module states that "All new tests
should be written using the unittest module; using unittest is not
required but makes the tests more flexible and maintenance of the
tests easier. Some older tests are written to use doctest and a
``traditional'' testing style; these styles of tests will not be
covered."

While that language is arguably quite mild, it was enough to scare me
off of using doctest, but for a lot of what I want to test on the
string formatting, doctest is preferable, so I guess I'll build some
doctests to check in!

> > OTOH
> > unless it would be a major performance hit to never pass empty
> > *dictionary parameters (always use a NULL pointer) to C functions, it
> > would remove a whole class of untested potential execution paths to
> > change the interpreter.
>
> You guessed it, it's a major performance hit to create a whole new
> dict object (even if empty) when the majority of calls don't need it.
> So, no, this isn't going away any time soon.

That's not actually what I was suggesting.  While it still may be too
much of a performance hit, I was suggesting always passing NULL if the
dictionary is empty.  Since the C code has to support _some_ execution
path for a NULL dictionary in any case, I thought perhaps you could
remove the equivalent empty dictionary case to let the C code practice
TOOWTDI for empty or NULL dictionaries.  Obviously, some other C
function could still call a C function with an empty dictionary, but
all calls straight from Python to the C function would take the same
execution path for empty as  for NULL dictionaries, so the unittest
coverage would automatically be better.

(The naive implementation of what I am discussing would be to always pass as the
keyword parameter the expression:

    (((keyword != NULL) && (PyDict_Size(keyword) != 0)) ? keyword : NULL)


Regards,
Pat


More information about the Python-3000 mailing list