Skip to content

parse PyCFunctions like pybind11 functions #256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

AaronOpfer
Copy link

PyCFunctions are surprisingly compatible with inspect.getfullargspec et. al., through a mechanism called __text_signature__. This means that pybind11-stubgen will not activate its docstring-parsing fallback. This is problematic for pybind11-stubgen however, because the __text_signature__ does not have any mechanism for including type hints or annotations.

This is relevant to pybind11-stubgen as I have been porting some C API functions away from pybind11 to CPython and hit a snag trying to do it piecemeal, as pybind11-stubgen won't generate stubs for functions created in the CPython way.

A test case could be as simple as:

namespace {

static PyObject* python_time_ns(PyObject* /*self*/, PyObject* /*args*/) {
    return PyLong_FromUnsignedLongLong(0);  // obviously just for the purpose of testing
}

static PyMethodDef memberdef_time_ns{.ml_name = "time_ns",
                                     .ml_meth = python_time_ns,
                                     .ml_flags = METH_NOARGS,
                                     .ml_doc = "time_ns() -> int\n"};

} // namespace

PyObject* create_time_ns_func(PyObject* modname) {
    return PyCFunction_NewEx(&memberdef_time_ns, NULL, modname);
}

And then installing this onto a pybind11 module:

    m.attr("time_ns") = create_time_ns_func(m.attr("__name__").ptr());

PyCFunctions are surprisingly compatible with `inspect.getfullargspec` et. al.,
through a mechanism called `__text_signature__`. This means that
`pybind11-stubgen` will not activate its docstring-parsing fallback.  This is
problematic for `pybind11-stubgen` however, because the `__text_signature__`
does not have any mechanism for including type hints or annotations.

This is relevant to `pybind11-stubgen` as I have been porting some C API
functions away from `pybind11` to CPython and hit a snag trying to do it
piecemeal, as `pybind11-stubgen` won't generate stubs for functions created in
the CPython way.

A test case could be as simple as:
```cpp

namespace {

static PyObject* python_time_ns(PyObject* /*self*/, PyObject* /*args*/) {
    return PyLong_FromUnsignedLongLong(0);  // obviously just for the purpose of testing
}

static PyMethodDef memberdef_time_ns{.ml_name = "time_ns",
                                     .ml_meth = python_time_ns,
                                     .ml_flags = METH_NOARGS,
                                     .ml_doc = "time_ns() -> int\n"};

} // namespace

PyObject* create_time_ns_func(PyObject* modname) {
    return PyCFunction_NewEx(&memberdef_time_ns, NULL, modname);
}
```
And then installing this onto a pybind11 module:
```cpp
    m.attr("time_ns") = create_time_ns_func(m.attr("__name__").ptr());
```
@AaronOpfer
Copy link
Author

It was not clear to me how to run/augment the tests so I'm not sure if this PR breaks anything yet. I am also open to other suggestions or consideration of whether this change is appropriate since it's pretty clearly not pybind11-related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant