[Python-3000] Questions about PEP 3121

"Martin v. Löwis" martin at v.loewis.de
Wed Sep 5 13:00:32 CEST 2007


> First is whether the name of the function that returns the
> module-specific memory is PyModule_GetData() or PyModule_GetState()?
> The former is listed by the PEP but the latter is used by the example.

I think I like _GetState more, so I have now adjusted the PEP.

> Second is how are the exception and type to be added to the module?
> Currently one uses PyModule_AddObject() to insert an object into the
> global namespace of a module.  But the example leaves that out and I
> wanted to make sure there was not some magical new step left out
> (initializing Xxo_Type is also left out, but that does not directly
> deal with module initialization).

No, this is just an omission. I'll fix it when I revise the PEP after
the implementation.

> Lastly, what is tp_reload to be used for?  The PEP doesn't say but the
> PyModuleDef lists it.  I assume it is to be called when a module is
> reloaded, but it is not specified in the PEP.

Yes; I'm not certain whether module reloading continues to be supported
in Py3k or not. If not, it should be removed from the PEP, if yes, it
should be specified.

A few other issues that you may want to know:

I found that enhancing PyModule_New cannot really work, as Py_InitModule
does a lot of other things that shouldn't be done in PyModule_New (which
is also used to create Python modules). So I keep calling the function
Py_InitModule.

I also found that passing two constant arguments to the function is
pointless, so I moved the module name into struct PyModuleDef. I also
add PyModuleDef_HEAD, similar to types.

E.g. for array, the current diff looks like that:

+static PyModuleDef array_mod = {
+       PyModuleDef_HEAD,
+       "array",          /* name */
+       module_doc,       /* doc string */
+       a_methods,        /* methods */
+       0,                /* m_size */
+       NULL,             /* m_reload */
+       NULL,             /* m_traverse */
+       NULL,             /* m_clear */
+       NULL,             /* m_free */
+};
+
 PyMODINIT_FUNC
-initarray(void)
+PyInit_array(void)
 {
        PyObject *m;

        if (PyType_Ready(&Arraytype) < 0)
             return;
        Py_Type(&PyArrayIter_Type) = &PyType_Type;
-       m = Py_InitModule3("array", a_methods, module_doc);
+       m = Py_InitModule(&array_mod);
        if (m == NULL)
-               return;
+               return NULL;

         Py_INCREF((PyObject *)&Arraytype);
        PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
         Py_INCREF((PyObject *)&Arraytype);
        PyModule_AddObject(m, "array", (PyObject *)&Arraytype);
        /* No need to check the error here, the caller will do that */
+       return m;
 }

This doesn't include putting the type into interpreter state, and
I won't be able to fix all cases of global variables (also, some
global variables are out of scope of the PEP, including most types,
so some global variables will remain after I'm done).

Notice that I also kept the convention that the caller will check
for errors, so you can return a module object even though an
exception occurred. Making all these functions exception-safe is
fairly tedious, and I'm not attempting that for the moment.

Regards,
Martin


More information about the Python-3000 mailing list