\chapter{Further Details\label{further-details}} This chapter contains details that you don't stricly \emph{need} to know to get your extension written, but might help. One a first reading, it's probably safe and even wise to just skim the first paragraph of each section to know where to find the details when you want them. \section{Other Calling Conventions\label{other-calling-conventions}} Earlier, I mentioned that \code{METH_VARARGS} was the default but not only choice for the \code{ml_flags} field in a \code{PyMethodDef} structure. The other choices allow keyword arguments to be supplied or certain common cases to be handled more efficiently. \begin{tableii}{cl}{code}{flag}{meaning} \lineii{METH_OLDARGS} {Obsolete; do not use this.} \lineii{METH_KEYWORDS} {Means the function accepts keyword arguments.} \lineii{METH_O} {Means the function takes a single argument.} \lineii{METH_NOARGS} {Means the function takes no arguments.} \end{tableii} (in addition one of the flags \code{METH_STATIC} or \code{METH_CLASS} can be bitwise or-ed with one of the above values to implement static or class methods -- this is described in chapter \ref{defining-new-types}, ``Defining New Types''. Python 2.4 adds another flag -- \code{METH_COEXIST} -- but this covers a very specialized sitation and can \emph{certainly} be ignored at first). Here's an example module that demonstrates the use of each of the conventions (except for the obsolete \code{METH_OLDARGS}): \verbatiminput{callingconventions.c} (this uses a C API function \code{PyString_FromFormat} that hasn't been mentioned yet; this function is rather like the C function \code{sprintf} except the result is a Python, not C, string. And there's no risk of buffer overflow). As you can see from the code above, there's a qualitative difference between the \code{METH_O} and \code{METH_NOARGS} conventions and the \code{METH_KEYWORD} convention: the former two are specializations of METH_VARARGS that allow less code and more efficiency in common cases, whereas \code{METH_KEYWORD} allows more functionality (passing keyword arguments) at the cost of slightly more code. Let's see the various conventions in use: \begin{verbatim} >>> from callingconventions import varargs, o, noargs, keywords >>> varargs() 'received 0 arguments' >>> varargs(1) 'received 1 arguments' >>> varargs('a', 'b', None) 'received 3 arguments' >>> varargs(a=1) Traceback (most recent call last): File "", line 1, in ? TypeError: varargs() takes no keyword arguments >>> o() Traceback (most recent call last): File "", line 1, in ? TypeError: o() takes exactly one argument (0 given) >>> o(1) 'received 1 arguments of type int' >>> o('1') 'received 1 arguments of type str' >>> o(1,2) Traceback (most recent call last): File "", line 1, in ? TypeError: o() takes exactly one argument (2 given) >>> noargs() 'received no arguments, noarg is 0x0' >>> noargs(1) Traceback (most recent call last): File "", line 1, in ? TypeError: noargs() takes no arguments (1 given) >>> keywords(1) >>> keywords(arg=1) >>> keywords(1,2) Traceback (most recent call last): File "", line 1, in ? TypeError: keywords() takes exactly 1 argument (2 given) >>> keywords(1,arg=2) Traceback (most recent call last): File "", line 1, in ? TypeError: keyword parameter 'arg' was given by position and by name >>> keywords(blarg=2) Traceback (most recent call last): File "", line 1, in ? TypeError: keywords() takes exactly 1 argument (0 given) \end{verbatim} (XXX the last error message is surely a bug that should be fixed? in fact vgetargskeywords looks due for a rewrite on many levels). So which convention should you use? If \code{METH_NOARGS} applies to your situation, it's a no-brainer. In the case of one argument, it's probably more transparent (and even more likely to be more efficient) to do whatever checking you'd be getting \code{PyArg_ParseTuple} to do by hand. For longer argument lists, whether to put the effort in to support keyword arguments isn't something that can be decided absolutely. Bear in mind that keyword arguments are most useful when you have a large-ish number of optional arguments which can be supplied indpendently (or are even mutually exclusive, but that's a slightly dubious design choice). \section{Calling Python Callables from C\label{calling-python-from-c}} So far we have concentrated on making C functions callable from Python. The reverse is also useful: calling Python functions from C. In fact, as in Python, as far as the C API is concerned Python functions are just a particular case of a callable type: you don't have to care whether it's a Python function, bound method, builtin function, type object, instance of a user-defined type that has a \code{__call__} method or whatever else. In some sense, the primitive API function for all this -- the function that all the other functions that will be described in this section end up calling -- is \code{PyObject_Call}. This function takes three arguments: \begin{enumerate} \item \var{func}: the object you wish to call. \item \var{args}: a tuple of positional arguments. \item \var{kw}: a dictionary containing keyword arguments, or \code{NULL} if none are to be passed. \end{enumerate} So a call ``\code{PyObject_Call(func, t, kw)}'' is essentially the same as ``\code{func(*t, **kw)}'' in Python -- except the former does no error checking on \var{t} or \var{kw}. Get it wrong and a segfault or access violation is likely to be the result. For this reason it is often preferable to use the API function ``\code{PyEval_CallObjectWithKeywords}'' which has the same signature as \code{PyObject_Call} but \emph{does} do error checking on its arguments. As with essentially all API functions, both \code{PyObject_Call} and \code{PyEval_CallObjectWithKeywords} return \code{NULL} on failure with an exception set. If they succeed they transfer ownership of the resulting reference back to the caller (as the result is fairly likely to be a new object, there's not really anything else that could be the case). It's fairly rare that you will want to supply keyword arguments, so there is a convenience macro: \begin{verbatim} #define PyEval_CallObject(func,arg) \ PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL) \end{verbatim} If you do not happen to have a tuple of arguments lying around, you can use \code{PyEval_CallFunction}: \begin{verbatim} PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *obj, char *format, ...); \end{verbatim} The string \var{format} and the following arguments are as for \code{Py_BuildValue} (XXX so i really should have described that by now!). A call such as \begin{verbatim} PyEval_CallFunction(obj, "iii", a, b, c); \end{verbatim} is equivalent to \begin{verbatim} PyEval_CallObject(obj, Py_BuildValue("iii", a, b, c)); \end{verbatim} but with error checking and not leaking the tuple of arguments... Another convenience function is \code{PyEval_CallMethod}. Again, a call \begin{verbatim} PyEval_CallMethod(obj, "insert", "iO", i, item); \end{verbatim} is, modulo error checking and getting the reference count details right, the same as \begin{verbatim} PyEval_CallObject(PyObject_GetAttrString(obj, "insert"), Py_BuildValue("iO", i, item)); \end{verbatim} XXX examples! \section{Providing a C API for your module\label{providing-a-c-api}} \section{Writing Extensions in Other Languages\label{other-languages}} While C is in some sense the most natural language to write Python extensions in -- Python is implemeted in C, after all -- it's not the only choice. The next most likely choices are C++ or Pyrex (also, scientific users fairly frequently wrap libraries written in Fortran). Extensions written in other languages will be using the C interfaces on some level, so knowing about them doesn't do you any harm. C++ is an obvious choice if you are writing a wrapper to a library written in C++, or if you just plain prefer C++ to C. The most commonly used library is boost.python (or Boost::Python?), but there are a variety of alternatives. XXX links, details, perhaps a toy example. Pyrex is a relatively new Python-like lanuage designed specifically for writing Python extensions. XXX links, details, toy example. Something about f2py?? SWIG??