[Import-SIG] PEP 489: Redesigning extension module loading
Petr Viktorin
encukou at gmail.com
Thu Mar 26 11:01:49 CET 2015
On 03/26/2015 05:25 AM, Nick Coghlan wrote:
> On 25 March 2015 at 23:36, Petr Viktorin <encukou at gmail.com> wrote:
>> On 03/25/2015 01:11 PM, Nick Coghlan wrote:
>>>
>>> On 25 March 2015 at 02:34, Petr Viktorin <encukou at gmail.com> wrote:
>>>>
>>>> I'll share my notes on an API with PEP 384-style slots, before attempting
>>>> to
>>>> write it out in PEP language.
>>>>
>>>> I struggled to find a good name for the "PyType_Spec" equivalent, since
>>>> ModuleDef and ModuleSpec are both taken, but then I realized that, if the
>>>> docstring is put in a slot, I just need an array of slots...
>>>
>>>
>>> Because we're looking for an exported symbol, I think there's value in
>>> having a more clearly defined top level structure rather than just an
>>> array.
>>
>>
>> OK.
>> I'm not sure on cross-platform support of data rather than functions
>> exported from shared libraries, so kept the hook as a function.
>> Perhaps I'm being too paranoid here?
>
> Given that http://bugs.python.org/issue23743 came across my inbox this
> morning, I'm going to go with "No, you're not being too paranoid once
> we take C++ compilers and linkers into account".
Yeah. I'm usually against boilerplate but here the extra function will
probably save headaches later.
> Perhaps we could make it use a new PyExport prefix though and drop the
> integer IDs in favour of exporting additional symbols? That is, have
> the hook be "PyExport_spam" with a separate "PyExport_spam_methods"?
>
> That opens the door to potentially having *other* export APIs in the
> future, like "PyExport_spam_codecs", "PyExport_spam_types",
> "PyExport_spam_constants_str".
I'm not convinced. I think the dynamic loading machinery is too
sensitive to weird platform-specific compiler/linker details to add bits
like this whenever they're needed. Having everything packaged up as a
module, which registers whatever it wants when it's loaded, seems better
to me.
Also, I believe all these extension APIs should preferably include
module names. The PyCapsule_Import naming convention is a good idea.
Makes it easier to know where things come from.
[...]
> Pulling this idea for your full extension example:
>
> static PyExportDef_Method spam_methods[] = {
> {"demo", (PyCFunction)spam_demo, ...},
> {NULL, NULL}
> };
>
> static PyExportDef_ModuleState spam_statedef = {
> sizeof(spam_state_t),
> spam_state_traverse,
> spam_state_clear,
> spam_state_free
> /* any of those three can be NULL if not needed */
> }
>
> static PyExportDef_Module spam_module = {
> PyDoc_STR("A spammy module"),
> spam_exec,
> spam_statedef
> }
>
> PyExportDef_Module *PyExport_spam {
> return spam_module;
> }
>
> PyExportDef_Method *PyExport_spam_methods {
> return spam_methods;
> }
>
> Using slots instead, the last part (from spam_module down) would
> revert to being closer to your example:
>
> static PyExportDef_ModuleSlot spam_slots[] = {
> {Py_m_doc, PyDoc_STR("A spammy module")},
> {Py_m_methods, spam_methods},
> {Py_m_statedef, spam_statedef},
> {Py_m_exec, spam_exec},
> {0, NULL}
> }
>
> PyExportDef_ModuleSlot *PyExport_spam {
> return spam_slots;
> }
>
> So actually writing that down suggests numeric slots may still be a
> better idea.
Yes, I think so as well. Also consider:
- Python can fail hard on unknown slot numbers. Checking for unknown
exports would require enumerating exported symbols, which is definitely
not something I can code for every platform (if that's even possible).
- Additional exported functions are not actually more type-safe – the
exported symbols would be void*, Python would still need to cast to an
appropriate function type.
> I like the "PyExport" and "PyExportDef" prefixes though.
As above, I think modules are the only thing that should be exported,
and with that, "PyModuleExport" sounds better.
More information about the Import-SIG
mailing list