How does unit test handle error handling for Python / C APIs such as PyType_Ready and PyObject_New?

This is a fairly simple (if tedious) extension module written in C, including errors for many Python / C APIs such as PyArg_ParseTuple. For example, the idiomatic way to run a C function that implements a Python function or method is as follows:

if (!PyArg_ParseTuple(args, "someformat:function_name")) { return NULL; } 

The success case of this can be verified by the module by calling a function with the correct number and type of arguments. Failures can also be tested by calling a function with the first incorrect number of arguments and then the correct number of arguments, but passing values โ€‹โ€‹of the wrong type. This leads to full coverage of C code branch testing.

However, it is unclear how to use negative paths for other Python / C APIs. The idiomatic way to start module initialization in extension C is as follows:

  if (PyType_Ready(&Some_Extension_Structure) < 0) { return 0; } 

How can PyType_Ready fail? Similarly, the C function often uses an API to assign a new instance of an extension type, such as PyObject_New :

  self = PyObject_New(Some_Structure, &Some_Extension_Structure); if (self == NULL) { return NULL; } 

How does one unit test this negative case (especially considering PyObject_New is probably used many times during the execution of one unit test method)?

It seems possible to create a common solution based on dynamic linker tricks, such as LD_PRELOAD , to provide fakes for these C APIs, which can be aimed at unsuccessful attempts in the right ways at the right time. The cost of building such a system seems a bit out of reach. Has anyone else done this and made the result available?

Are there any Python / C tricks that could facilitate this testing?

Should I think of other lines entirely?

+6
source share
1 answer

This is a clear example for test doubles (e.g. mockery). Since the Python C API does not offer any ability to falsify state from memory, you will have to do it yourself.

Create your own layer that provides PyType_Ready and PyObject_New . Ask them to move on to the C API functions if any control, possibly an environment variable, does not give them directions. They can cause any chaos you desire and test your code reaction.

+2
source

Source: https://habr.com/ru/post/908350/


All Articles