From 4641f198cd9add281f1ca5a6c01ceb8a4fba8323 Mon Sep 17 00:00:00 2001 From: Aaron Opfer Date: Thu, 26 Jun 2025 09:16:17 -0500 Subject: [PATCH] parse PyCFunctions like pybind11 functions 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()); ``` --- pybind11_stubgen/parser/mixins/parse.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pybind11_stubgen/parser/mixins/parse.py b/pybind11_stubgen/parser/mixins/parse.py index 9f554f5..b4528f8 100644 --- a/pybind11_stubgen/parser/mixins/parse.py +++ b/pybind11_stubgen/parser/mixins/parse.py @@ -217,6 +217,8 @@ def handle_function(self, path: QualifiedName, func: Any) -> list[Function]: func_name = Identifier(path[-1]) try: + if type(func) is types.BuiltinFunctionType: + raise TypeError ( args, var_args,