[Python-Dev] Changing PyModuleDef.m_reload to m_slots

Petr Viktorin encukou at gmail.com
Fri Apr 17 15:52:56 CEST 2015


Hello,

PEP 489, Redesigning extension module loading [0], is currently 
discussed on import-sig, but one question calls for a wider audience.

As a background, the PyModuleDef structure [1] is currently:

     struct PyModuleDef{
       PyModuleDef_Base m_base;
       const char* m_name;
       const char* m_doc;
       Py_ssize_t m_size;
       PyMethodDef *m_methods;
       inquiry m_reload;
       traverseproc m_traverse;
       inquiry m_clear;
       freefunc m_free;
     };

... where the m_reload pointer is unused, and must be NULL.
My proposal is to repurpose this pointer to hold an array of slots, in 
the style of PEP 384's PyType_Spec [2], which would allow adding 
extensions -- both those needed for PEP 489 and future ones.

The result would be:

     typedef struct {
         int slot;
         void *value;
     } PyModuleDesc_Slot;

     typedef struct PyModuleDef {
         PyModuleDef_Base m_base;
         const char* m_name;
         const char* m_doc;
         Py_ssize_t m_size;
         PyMethodDef *m_methods;
         PyModuleDesc_Slot* m_slots;  /* <-- change here */
         traverseproc m_traverse;
         inquiry m_clear;
         freefunc m_free;
     } PyModuleDef;

The alternative is defining another struct for module definitions, with 
a parallel versions of functions to operate on it, and duplication on 
the lower level (e.g. a variant of PyModule_GetDef, variants for 
PyState_FindModule &c with the supporting registry, extra storage in 
module objects, two places to look in for GC/deallocation hooks).

The downside is that, strictly speaking, this would break API/ABI, 
though in pedantic details.

The field name could conceivably be used to get the NULL or in C99-style 
designated initializers, but since NULL is the only valid value, I don't 
see a reason for that. It could also be used for zeroing the structure 
after allocating a PyModuleDef dynamically.

ABI-wise, this changes a function pointer to a data pointer. To my 
knowledge, Python doesn't support a platform where this would matter, 
but I admit my knowledge is not complete.

Please share any concerns you might have about this change.


[0] https://www.python.org/dev/peps/pep-0489/
[1] https://docs.python.org/3/c-api/module.html#c.PyModuleDef
[2] https://www.python.org/dev/peps/pep-0384/#type-objects


More information about the Python-Dev mailing list