GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing docs.python.org — Using the C API: Assorted topics Using the C API: Assorted topics¶The tutorial walked you through creating a C API extension module, but left many areas unexplained. This document looks at several concepts that you’ll need to learn in order to write more complex extensions. Errors and Exceptions¶An important convention throughout the Python interpreter is the following: when
a function fails, it should set an exception condition and return an error value
(usually The Python API defines a number of functions to set various types of exceptions. The most common one is Another useful function is You can test non-destructively whether an exception has been set with
When a function f that calls another function g detects that the latter
fails, f should itself return an error value (usually (There are situations where a module can actually give a more detailed error
message by calling another To ignore an exception set by a function call that failed, the exception
condition must be cleared explicitly by calling Every failing Also note that, with the important exception of Finally, be careful to clean up garbage (by making The choice of which exception to raise is entirely yours. There are predeclared
C objects corresponding to all built-in Python exceptions, such as
You can also define a new exception that is unique to your module. The simplest way to do this is to declare a static global object variable at the beginning of the file: static PyObject *SpamError = NULL; and initialize it by calling SpamError = PyErr_NewException("spam.error", NULL, NULL); Since For now, let’s avoid the issue: we will block repeated initialization by raising an
static PyObject *SpamError = NULL; static int spam_module_exec(PyObject *m) { if (SpamError != NULL) { PyErr_SetString(PyExc_ImportError, "cannot initialize spam module more than once"); return -1; } SpamError = PyErr_NewException("spam.error", NULL, NULL); if (PyModule_AddObjectRef(m, "SpamError", SpamError) < 0) { return -1; } return 0; } static PyModuleDef_Slot spam_module_slots[] = { {Py_mod_exec, spam_module_exec}, {0, NULL} }; static struct PyModuleDef spam_module = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "spam", .m_size = 0, // non-negative .m_slots = spam_module_slots, }; PyMODINIT_FUNC PyInit_spam(void) { return PyModuleDef_Init(&spam_module); } Note that the Python name for the exception object is Note also that the For now, the We discuss the use of The static PyObject * spam_system(PyObject *self, PyObject *args) { const char *command; int sts; if (!PyArg_ParseTuple(args, "s", &command)) return NULL; sts = system(command); if (sts < 0) { PyErr_SetString(SpamError, "System command failed"); return NULL; } return PyLong_FromLong(sts); } Embedding an extension¶If you want to make your module a permanent
part of the Python interpreter, you will have to change the configuration setup
and rebuild the interpreter. On Unix, place
your file ( spam spammodule.o
and rebuild the interpreter by running make in the toplevel
directory. You can also run make in the If your module requires additional libraries to link with, these can be listed on the line in the configuration file as well, for instance: spam spammodule.o -lX11 Calling Python Functions from C¶The tutorial concentrated on making C functions callable from Python. The reverse is also useful: calling Python functions from C. This is especially the case for libraries that support so-called “callback” functions. If a C interface makes use of callbacks, the equivalent Python often needs to provide a callback mechanism to the Python programmer; the implementation will require calling the Python callback functions from a C callback. Other uses are also imaginable. Fortunately, the Python interpreter is easily called recursively, and there is a standard interface to call a Python function. (If you’re interested in how to call the Python parser with a particular string as input, see The Very High Level Layer.) Calling a Python function is easy. First, the Python program must somehow pass
you the Python function object. You should provide a function (or some other
interface) to do this. When this function is called, save a pointer to the
Python function object (be careful to static PyObject *my_callback = NULL; static PyObject * my_set_callback(PyObject *dummy, PyObject *args) { PyObject *result = NULL; PyObject *temp; if (PyArg_ParseTuple(args, "O:set_callback", &temp)) { if (!PyCallable_Check(temp)) { PyErr_SetString(PyExc_TypeError, "parameter must be callable"); return NULL; } Py_XINCREF(temp); /* Add a reference to new callback */ Py_XDECREF(my_callback); /* Dispose of previous callback */ my_callback = temp; /* Remember new callback */ /* Boilerplate to return "None" */ Py_INCREF(Py_None); result = Py_None; } return result; } This function must be registered with the interpreter using the
The macros Later, when it is time to call the function, you call the C function
int arg; PyObject *arglist; PyObject *result; ... arg = 123; ... /* Time to call the callback */ arglist = Py_BuildValue("(i)", arg); result = PyObject_CallObject(my_callback, arglist); Py_DECREF(arglist);
The return value of Before you do this, however, it is important to check that the return value
isn’t if (result == NULL) return NULL; /* Pass error back */ ...use result... Py_DECREF(result); Depending on the desired interface to the Python callback function, you may also
have to provide an argument list to PyObject *arglist; ... arglist = Py_BuildValue("(l)", eventcode); if (arglist == NULL) return NULL; result = PyObject_CallObject(my_callback, arglist); Py_DECREF(arglist); if (result == NULL) return NULL; /* Pass error back */ /* Here maybe use the result */ Py_DECREF(result); Note the placement of You may also call a function with keyword arguments by using
PyObject *arglist, *dict; ... arglist = PyTuple_New(0); if (arglist == NULL) return NULL; dict = Py_BuildValue("{s:i}", "name", val); if (dict == NULL) { Py_DECREF(arglist); return NULL; } result = PyObject_Call(my_callback, arglist, dict); Py_DECREF(arglist); Py_DECREF(dict); if (result == NULL) return NULL; /* Pass error back */ /* Here maybe use the result */ Py_DECREF(result); Extracting Parameters in Extension Functions¶The tutorial uses a “ For unpacking the tuple, CPython provides the int PyArg_ParseTuple(PyObject *arg, const char *format, ...); The arg argument must be a tuple object containing an argument list passed from Python to a C function. The format argument must be a format string, whose syntax is explained in Parsing arguments and building values in the Python/C API Reference Manual. The remaining arguments must be addresses of variables whose type is determined by the format string. For example, to receive a single Python const char *command; if (!PyArg_ParseTuple(args, "s", &command)) { return NULL; } If an error is detected in the argument list, Note that while Note that any Python object references which are provided to the caller are borrowed references; do not decrement their reference count! Some example calls: #include <Python.h> int ok; int i, j; long k, l; const char *s; Py_ssize_t size; ok = PyArg_ParseTuple(args, ""); /* No arguments */ /* Python call: f() */ ok = PyArg_ParseTuple(args, "s", &s); /* A string */ /* Possible Python call: f('whoops!') */ ok = PyArg_ParseTuple(args, "lls", &k, &l, &s); /* Two longs and a string */ /* Possible Python call: f(1, 2, 'three') */ ok = PyArg_ParseTuple(args, "(ii)s#", &i, &j, &s, &size); /* A pair of ints and a string, whose size is also returned */ /* Possible Python call: f((1, 2), 'three') */ { const char *file; const char *mode = "r"; int bufsize = 0; ok = PyArg_ParseTuple(args, "s|si", &file, &mode, &bufsize); /* A string, and optionally another string and an integer */ /* Possible Python calls: f('spam') f('spam', 'w') f('spam', 'wb', 100000) */ } { int left, top, right, bottom, h, v; ok = PyArg_ParseTuple(args, "((ii)(ii))(ii)", &left, &top, &right, &bottom, &h, &v); /* A rectangle and a point */ /* Possible Python call: f(((0, 0), (400, 300)), (10, 10)) */ } { Py_complex c; ok = PyArg_ParseTuple(args, "D:myfunction", &c); /* a complex, also providing a function name for errors */ /* Possible Python call: myfunction(1+2j) */ } Keyword Parameters for Extension Functions¶If you also want your function to accept
keyword arguments, use the In this case, the C function should accept a third The int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict, const char *format, char * const *kwlist, ...); The arg and format parameters are identical to those of the
Note Nested tuples cannot be parsed when using keyword arguments! Keyword parameters
passed in which are not present in the kwlist will cause Here is an example module which uses keywords, based on an example by Geoff Philbrick (philbrick@hks.com): #define PY_SSIZE_T_CLEAN #include <Python.h> static PyObject * keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds) { int voltage; const char *state = "a stiff"; const char *action = "voom"; const char *type = "Norwegian Blue"; static char *kwlist[] = {"voltage", "state", "action", "type", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sss", kwlist, &voltage, &state, &action, &type)) return NULL; printf("-- This parrot wouldn't %s if you put %i Volts through it.\n", action, voltage); printf("-- Lovely plumage, the %s -- It's %s!\n", type, state); Py_RETURN_NONE; } static PyMethodDef keywdarg_methods[] = { /* The cast of the function is necessary since PyCFunction values * only take two PyObject* parameters, and keywdarg_parrot() takes * three. */ {"parrot", (PyCFunction)(void(*)(void))keywdarg_parrot, METH_VARARGS | METH_KEYWORDS, "Print a lovely skit to standard output."}, {NULL, NULL, 0, NULL} /* sentinel */ }; Building Arbitrary Values¶This function is the counterpart to PyObject *Py_BuildValue(const char *format, ...); It recognizes a set of format units similar to the ones recognized by
One difference with Examples (to the left the call, to the right the resulting Python value): Py_BuildValue("") None
Py_BuildValue("i", 123) 123
Py_BuildValue("iii", 123, 456, 789) (123, 456, 789)
Py_BuildValue("s", "hello") 'hello'
Py_BuildValue("y", "hello") b'hello'
Py_BuildValue("ss", "hello", "world") ('hello', 'world')
Py_BuildValue("s#", "hello", 4) 'hell'
Py_BuildValue("y#", "hello", 4) b'hell'
Py_BuildValue("()") ()
Py_BuildValue("(i)", 123) (123,)
Py_BuildValue("(ii)", 123, 456) (123, 456)
Py_BuildValue("(i,i)", 123, 456) (123, 456)
Py_BuildValue("[i,i]", 123, 456) [123, 456]
Py_BuildValue("{s:i,s:i}",
"abc", 123, "def", 456) {'abc': 123, 'def': 456}
Py_BuildValue("((ii)(ii)) (ii)",
1, 2, 3, 4, 5, 6) (((1, 2), (3, 4)), (5, 6))
Reference Counts¶In languages like C or C++, the programmer is responsible for dynamic allocation
and deallocation of memory on the heap. In C, this is done using the functions
Every block of memory allocated with Common causes of memory leaks are unusual paths through the code. For instance, a function may allocate a block of memory, do some calculation, and then free the block again. Now a change in the requirements for the function may add a test to the calculation that detects an error condition and can return prematurely from the function. It’s easy to forget to free the allocated memory block when taking this premature exit, especially when it is added later to the code. Such leaks, once introduced, often go undetected for a long time: the error exit is taken only in a small fraction of all calls, and most modern machines have plenty of virtual memory, so the leak only becomes apparent in a long-running process that uses the leaking function frequently. Therefore, it’s important to prevent leaks from happening by having a coding convention or strategy that minimizes this kind of errors. Since Python makes heavy use of An alternative strategy is called automatic garbage collection.
(Sometimes, reference counting is also referred to as a garbage collection
strategy, hence the use of “automatic” to distinguish the two.) The big
advantage of automatic garbage collection is that the user doesn’t need to call
While Python uses the traditional reference counting implementation, it also offers a cycle detector that works to detect reference cycles. This allows applications to not worry about creating direct or indirect circular references; these are the weakness of garbage collection implemented using only reference counting. Reference cycles consist of objects which contain (possibly indirect) references to themselves, so that each object in the cycle has a reference count which is non-zero. Typical reference counting implementations are not able to reclaim the memory belonging to any objects in a reference cycle, or referenced from the objects in the cycle, even though there are no further references to the cycle itself. The cycle detector is able to detect garbage cycles and can reclaim them.
The Reference Counting in Python¶There are two macros, The big question now remains: when to use It is also possible to borrow [1] a reference to an object. The
borrower of a reference should not call The advantage of borrowing over owning a reference is that you don’t need to take care of disposing of the reference on all possible paths through the code — in other words, with a borrowed reference you don’t run the risk of leaking when a premature exit is taken. The disadvantage of borrowing over owning is that there are some subtle situations where in seemingly correct code a borrowed reference can be used after the owner from which it was borrowed has in fact disposed of it. A borrowed reference can be changed into an owned reference by calling
Ownership Rules¶Whenever an object reference is passed into or out of a function, it is part of the function’s interface specification whether ownership is transferred with the reference or not. Most functions that return a reference to an object pass on ownership with the
reference. In particular, all functions whose function it is to create a new
object, such as Many functions that extract objects from other objects also transfer ownership
with the reference, for instance The function When you pass an object reference into another function, in general, the
function borrows the reference from you — if it needs to store it, it will use
When a C function is called from Python, it borrows references to its arguments
from the caller. The caller owns a reference to the object, so the borrowed
reference’s lifetime is guaranteed until the function returns. Only when such a
borrowed reference must be stored or passed on, it must be turned into an owned
reference by calling The object reference returned from a C function that is called from Python must be an owned reference — ownership is transferred from the function to its caller. Thin Ice¶There are a few situations where seemingly harmless use of a borrowed reference can lead to problems. These all have to do with implicit invocations of the interpreter, which can cause the owner of a reference to dispose of it. The first and most important case to know about is using void bug(PyObject *list) { PyObject *item = PyList_GetItem(list, 0); PyList_SetItem(list, 1, PyLong_FromLong(0L)); PyObject_Print(item, stdout, 0); /* BUG! */ } This function first borrows a reference to Let’s follow the control flow into Since it is written in Python, the The solution, once you know the source of the problem, is easy: temporarily increment the reference count. The correct version of the function reads: void no_bug(PyObject *list) { PyObject *item = PyList_GetItem(list, 0); Py_INCREF(item); PyList_SetItem(list, 1, PyLong_FromLong(0L)); PyObject_Print(item, stdout, 0); Py_DECREF(item); } This is a true story. An older version of Python contained variants of this bug
and someone spent a considerable amount of time in a C debugger to figure out
why his The second case of problems with a borrowed reference is a variant involving
threads. Normally, multiple threads in the Python interpreter can’t get in each
other’s way, because there is a global lock
protecting Python’s entire object space.
However, it is possible to temporarily release this lock using the macro
void bug(PyObject *list) { PyObject *item = PyList_GetItem(list, 0); Py_BEGIN_ALLOW_THREADS ...some blocking I/O call... Py_END_ALLOW_THREADS PyObject_Print(item, stdout, 0); /* BUG! */ } NULL Pointers¶In general, functions that take object references as arguments do not expect you
to pass them It is better to test for The macros The macros for checking for a particular object type ( The C function calling mechanism guarantees that the argument list passed to C
functions ( It is a severe error to ever let a Writing Extensions in C++¶It is possible to write extension modules in C++. Some restrictions apply. If
the main program (the Python interpreter) is compiled and linked by the C
compiler, global or static objects with constructors cannot be used. This is
not a problem if the main program is linked by the C++ compiler. Functions that
will be called by the Python interpreter (in particular, module initialization
functions) have to be declared using Providing a C API for an Extension Module¶Many extension modules just provide new functions and types to be used from Python, but sometimes the code in an extension module can be useful for other extension modules. For example, an extension module could implement a type “collection” which works like lists without order. Just like the standard Python list type has a C API which permits extension modules to create and manipulate lists, this new collection type should have a set of C functions for direct manipulation from other extension modules. At first sight this seems easy: just write the functions (without declaring them
Portability therefore requires not to make any assumptions about symbol
visibility. This means that all symbols in extension modules should be declared
Python provides a special mechanism to pass C-level information (pointers) from one extension module to another one: Capsules. A Capsule is a Python data type which stores a pointer (void*). Capsules can only be created and accessed via their C API, but they can be passed around like any other Python object. In particular, they can be assigned to a name in an extension module’s namespace. Other extension modules can then import this module, retrieve the value of this name, and then retrieve the pointer from the Capsule. There are many ways in which Capsules can be used to export the C API of an extension module. Each function could get its own Capsule, or all C API pointers could be stored in an array whose address is published in a Capsule. And the various tasks of storing and retrieving the pointers can be distributed in different ways between the module providing the code and the client modules. Whichever method you choose, it’s important to name your Capsules properly.
The function In particular, Capsules used to expose C APIs should be given a name following this convention: modulename.attributename The convenience function The following example demonstrates an approach that puts most of the burden on the writer of the exporting module, which is appropriate for commonly used library modules. It stores all C API pointers (just one in the example!) in an array of void pointers which becomes the value of a Capsule. The header file corresponding to the module provides a macro that takes care of importing the module and retrieving its C API pointers; client modules only have to call this macro before accessing the C API. The exporting module is a modification of the The function static int PySpam_System(const char *command) { return system(command); } The function static PyObject * spam_system(PyObject *self, PyObject *args) { const char *command; int sts; if (!PyArg_ParseTuple(args, "s", &command)) return NULL; sts = PySpam_System(command); return PyLong_FromLong(sts); } In the beginning of the module, right after the line #include <Python.h> two more lines must be added: #define SPAM_MODULE #include "spammodule.h" The static int spam_module_exec(PyObject *m) { static void *PySpam_API[PySpam_API_pointers]; PyObject *c_api_object; /* Initialize the C API pointer array */ PySpam_API[PySpam_System_NUM] = (void *)PySpam_System; /* Create a Capsule containing the API pointer array's address */ c_api_object = PyCapsule_New((void *)PySpam_API, "spam._C_API", NULL); if (PyModule_Add(m, "_C_API", c_api_object) < 0) { return -1; } return 0; } Note that The bulk of the work is in the header file #ifndef Py_SPAMMODULE_H #define Py_SPAMMODULE_H #ifdef __cplusplus extern "C" { #endif /* Header file for spammodule */ /* C API functions */ #define PySpam_System_NUM 0 #define PySpam_System_RETURN int #define PySpam_System_PROTO (const char *command) /* Total number of C API pointers */ #define PySpam_API_pointers 1 #ifdef SPAM_MODULE /* This section is used when compiling spammodule.c */ static PySpam_System_RETURN PySpam_System PySpam_System_PROTO; #else /* This section is used in modules that use spammodule's API */ static void **PySpam_API; #define PySpam_System \ (*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM]) /* Return -1 on error, 0 on success. * PyCapsule_Import will set an exception if there's an error. */ static int import_spam(void) { PySpam_API = (void **)PyCapsule_Import("spam._C_API", 0); return (PySpam_API != NULL) ? 0 : -1; } #endif #ifdef __cplusplus } #endif #endif /* !defined(Py_SPAMMODULE_H) */ All that a client module must do in order to have access to the function
static int client_module_exec(PyObject *m) { if (import_spam() < 0) { return -1; } /* additional initialization can happen here */ return 0; } The main disadvantage of this approach is that the file Finally it should be mentioned that Capsules offer additional functionality,
which is especially useful for memory allocation and deallocation of the pointer
stored in a Capsule. The details are described in the Python/C API Reference
Manual in the section Capsules and in the implementation of Capsules (files
Footnotes
© Copyright 2001 Python Software Foundation.
This page is licensed under the Python Software Foundation License Version 2. Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License. See History and License for more information. The Python Software Foundation is a non-profit corporation. Please donate. Last updated on Nov 12, 2026 (11:13 UTC). Found a bug? Created using Sphinx 9.1.1. |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |