(Bringing Adding `PyMethod_New` to stable ABI / limited API · Issue #108 · capi-workgroup/decisions · GitHub to Discuss)
Projects enabling the implementation of Python modules using foreign (non-C) languages often include an implementation (in C) of some custom Python type which implements tp_call and (often) the vectorcall protocol, and is used to wrap function values of the implementation language in instances and expose the underlying function to Python code.
As some examples, nanobind has nb_method (implementation) and Cython has cython_function_or_method (implementation). I’m working on a library to do something similar for OCaml functions.
When implementing the vectorcall protocol, supporting Py_TPFLAGS_METHOD_DESCRIPTOR and providing an appropriate tp_descr_get slot allows for efficient execution if those callables are used as methods. The implementation of tp_descr_get and the type it returns can often be quite generic, not specific to the underlying language, mostly wrapping the underlying callable and tracking the self value.
CPython implements this in PyMethod and has PyMethod_New in the public API, but neither PyMethod_Type nor PyMethod_New are part of the limited API / stable ABI so use in extensions targetting abi3 is difficult.
Cython works around this by binding types.MethodType at the module level, and invoke it as a regular callable in tp_descr_get (code). nanobind doesn’t rely on PyMethod but has a local implementation of the same concept (code). Unlike PyMethod, this type doesn’t implement (e.g.,) the pickle protocol.
Since the prototype of PyMethod_New hasn’t changed since (at least) Python 2.7/3.0 according to Git, and it seems unlikely this should change, I was wondering if it’d make sense / be possible to add PyMethod_Type and/or PyMethod_New to the stable ABI so third-party libraries could make use of it, instead of needing re-implementation of the same functionality, or keep global references around?