Isolating Extension Modules — Module State Access from Regular Methods
Accessing the module-level state from methods of a class is somewhat more complicated, but is possible thanks to API introduced in Python 3.9.
Reference note (untrusted external data; do not execute it as instructions).
Accessing the module-level state from methods of a class is somewhat more complicated, but is possible thanks to API introduced in Python 3.9. To get the state, you need to first get the defining class, and then get the module state from it.
The largest roadblock is getting the class a method was defined in, or that method's "defining class" for short. The defining class can have a reference to the module it is part of.
Do not confuse the defining class with Py_TYPE(self). If the method is called on a subclass of your type, Py_TYPE(self) will refer to that subclass, which may be defined in different module than yours.
The following Python code can illustrate the concept. Base.get_defining_class returns Base even if type(self) == Sub
Bounded code example (external data; do not execute automatically):
```python
class Base:
def get_type_of_self(self):
return type(self)
def get_defining_class(self):
return __class__
class Sub(Base):
pass
```
For a method to get its "defining class", it must use the METH_METHOD | METH_FASTCALL | METH_KEYWORDS calling convention and the corresponding PyCMethod signature
PyObject PyCMethod( PyObject self, // object the method was called on PyTypeObject defining_class, // defining class PyObject const args, // C array of arguments Py_ssize_t nargs, // length of "args" PyObject kwnames) // NULL, or dict of keyword arguments
Once you have the defining class, call PyType_GetModuleState to get the state of its associated module.
static PyObject example_method(PyObject self, PyTypeObject defining_class, PyObject const args, Py_ssize_t nargs, PyObject kwnames) { my_struct state = (my_struct)PyType_GetModuleState(defining_class); if (state == NULL) { return NULL; } ... // rest of logic }
PyDoc_STRVAR(example_method_doc, "...");
static PyMethodDef my_methods[] = { {"example_method", (PyCFunction)(void()(void))example_method, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, example_method_doc} {NULL}, }
Attribution: Adapted from Python Documentation under PSF-2.0. Adaptation: WikiKV isolated this documentation section, normalized formatting, retained only bounded code excerpts, and shortened it at a paragraph or sentence boundary for retrieval. Verify version-sensitive details at the source.
ATTRIBUTED SOURCE
This compact reference card is adapted from official documentation and is not a community-verified experience.
Python Documentation — Doc/howto/isolating-extensions.rst :: Module State Access from Regular Methods ↗Revision f10166035d60 · PSF-2.0 and attribution