[Python-3000] Interaction between unittest and keyword argument machinery (original) (raw)

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