views:

93

answers:

1

Hello SO :)

I am writing C extensions, and I'd like to specify for my users the signature of my methods. Let's throw in some code :)

static PyObject* foo(PyObject *self, PyObject *args) {

    /* blabla [...] */

}

PyDoc_STRVAR(
    foo_doc,
    "Great example function\n"
    "Arguments: (timeout, flags=None)\n"
    "Doc blahblah doc doc doc.");

static PyMethodDef methods[] = {
    {"foo", foo, METH_VARARGS, foo_doc},
    {NULL},
};

PyMODINIT_FUNC init_myexample(void) {
    (void) Py_InitModule3("_myexample", methods, "a simple example module");
}

Now if (after building it...) I load the module and look at its help:

>>> import _myexample
>>> help(_myexample)

I will get:

Help on module _myexample:

NAME
    _myexample - a simple example module

FILE
    /path/to/module/_myexample.so

FUNCTIONS
    foo(...)
        Great example function
        Arguments: (timeout, flags=None)
        Doc blahblah doc doc doc.

I would like to be even more specific and be able to replace foo(...) by foo(timeout, flags=None)

Can I do this? How? :)

Thanks!

+2  A: 

My usual approach to finding out about things like this is: "use the source".

Basically, I would presume that the standard modules of python would use such a feature when available. Looking at the source (for example here) should help, but in fact even the standard modules add the prototype after the automatic output. Like this:

torsten@pulsar:~$ python2.6
>>> import fcntl
>>> help(fcntl.flock)
flock(...)
    flock(fd, operation)

    Perform the lock operation op on file descriptor fd.  See the Unix [...]

So as upstream is not using such a feature, I would assume it is not there. :-)

Okay, I just checked current python3k sources and this is still the case. That signature is generated in pydoc.py in the python sources here: pydoc.py. Relevant excerpt starting in line 1260:

        if inspect.isfunction(object):
            args, varargs, varkw, defaults = inspect.getargspec(object)
            ...
        else:
            argspec = '(...)'

inspect.isfunction checks if the object the documentation is requested for is a Python function. But C implemented functions are considered builtins, therefore you will always get name(...) as the output.

Bluehorn