PEP 489: Update from Petr.

This commit is contained in:
Berker Peksag 2015-04-17 21:05:59 +03:00
parent cb84322924
commit d7780468e2
1 changed files with 33 additions and 29 deletions

View File

@ -128,13 +128,13 @@ PEP 384's PyType_Spec for types. The structure is defined as::
typedef struct {
int slot;
void *value;
} PyModuleDesc_Slot;
} PyModuleExport_Slot;
typedef struct {
const char* doc;
int flags;
PyModuleDesc_Slot *slots;
} PyModuleDesc;
PyModuleExport_Slot *slots;
} PyModuleExport;
The *doc* member specifies the module's docstring.
@ -142,7 +142,7 @@ The *flags* may currently be either 0 or ``PyModule_EXPORT_SINGLETON``, describe
in "Singleton Modules" below.
Other flag values may be added in the future.
The *slots* points to an array of PyModuleDesc_Slot structures, terminated
The *slots* points to an array of PyModuleExport_Slot structures, terminated
by a slot with id set to 0 (i.e. ``{0, NULL}``).
To specify a slot, a unique slot ID must be provided.
@ -164,7 +164,7 @@ Unknown slot IDs will cause the import to fail with ImportError.
.. note::
An alternate proposal is to use PyModuleDef instead of PyModuleDesc,
An alternate proposal is to use PyModuleDef instead of PyModuleExport,
re-purposing the m_reload pointer to hold the slots::
typedef struct PyModuleDef {
@ -173,7 +173,7 @@ Unknown slot IDs will cause the import to fail with ImportError.
const char* m_doc;
Py_ssize_t m_size;
PyMethodDef *m_methods;
PyModuleDesc_Slot* m_slots; /* changed from `inquiry m_reload;` */
PyModuleExport_Slot* m_slots; /* changed from `inquiry m_reload;` */
traverseproc m_traverse;
inquiry m_clear;
freefunc m_free;
@ -197,10 +197,10 @@ Py_mod_create
The Py_mod_create slot is used to support custom module subclasses.
The value pointer must point to a function with the following signature::
PyObject* (*PyModuleCreateFunction)(PyObject *spec, PyModuleDesc *desc)
PyObject* (*PyModuleCreateFunction)(PyObject *spec, PyModuleExport *exp)
The function receives a ModuleSpec instance, as defined in PEP 451,
and the PyModuleDesc structure.
and the PyModuleExport structure.
It should return a new module object, or set an error
and return NULL.
@ -213,12 +213,12 @@ types.ModuleType. Any type can be used, as long as it supports setting and
getting attributes, including at least the import-related attributes.
If a module instance is returned from Py_mod_create, the import machinery will
store a pointer to PyModuleDesc in the module object so that it may be
retrieved by PyModule_GetDesc (described later).
store a pointer to PyModuleExport in the module object so that it may be
retrieved by PyModule_GetExport (described later).
.. note::
If PyModuleDef is used instead of PyModuleDesc, the def is stored
If PyModuleDef is used instead of PyModuleExport, the def is stored
instead, to be retrieved by PyModule_GetDef.
Note that when this function is called, the module's entry in sys.modules
@ -230,6 +230,9 @@ to not call user code from it.
Multiple Py_mod_create slots may not be specified. If they are, import
will fail with ImportError.
If Py_mod_create is not specified, the import machinery will create a normal
module object, as if by calling PyModule_Create.
Py_mod_statedef
...............
@ -290,7 +293,7 @@ The specified methods are added to the module, like with PyModuleDef.m_methods.
Py_mod_exec
...........
The function in this slot must have the signature::
The entry in this slot must point to a function with the following signature::
int (*PyModuleExecFunction)(PyObject* module)
@ -298,7 +301,7 @@ It will be called to initialize a module. Usually, this amounts to
setting the module's initial attributes.
The "module" argument receives the module object to initialize. This will
always be the module object created from the corresponding PyModuleDesc.
always be the module object created from the corresponding PyModuleExport.
When this function is called, import-related attributes (such as ``__spec__``)
will have been set, and the module has already been added to sys.modules.
@ -317,20 +320,21 @@ Legacy Init
-----------
If the PyModuleExport function is not defined, the import machinery will try to
initialize the module using the PyInit hook, as described in PEP 3121.
initialize the module using the "PyInit_<modulename>" hook,
as described in PEP 3121.
If PyModuleExport is defined, PyModuleInit will be ignored.
If the PyModuleExport function is defined, the PyInit function will be ignored.
Modules requiring compatibility with previous versions of CPython may implement
PyModuleInit in addition to the new hook.
the PyInit function in addition to the new hook.
Modules using the legacy init API will be initialized entirely in the
Loader.create_module step; Loader.exec_module will be a no-op.
.. XXX: Give example code for a backwards-compatible Init based on slots
.. XXX: Give example code for a backwards-compatible PyInit based on slots
.. note::
If PyModuleDef is reused, implementing the PyInit hook becomes easy:
If PyModuleDef is reused, implementing the PyInit function becomes easy:
* call PyModule_Create with the PyModuleDef (m_reload was ignored in
previous Python versions, so the slots array will be ignored).
@ -354,16 +358,16 @@ A simple rule of thumb is: Do not define any static data, except built-in types
with no mutable or user-settable class attributes.
PyModule_GetDesc
----------------
PyModule_GetExport
------------------
To retrieve the PyModuleDesc structure used to create a module,
To retrieve the PyModuleExport structure used to create a module,
a new function will be added::
PyModuleDesc* PyModule_GetDesc(PyObject *module)
PyModuleExport* PyModule_GetExport(PyObject *module)
The function returns NULL if the parameter is not a module object, or was not
created using PyModuleDesc.
created using PyModuleExport.
.. note::
@ -389,7 +393,7 @@ a reference to the module object, either directly or indirectly.
However, there are some modules that really need to be only loaded once:
typically ones that wrap a C library with global state.
These modules should set the PyModule_EXPORT_SINGLETON flag
in PyModuleDesc.flags. When this flag is set, loading an additional
in PyModuleExport.flags. When this flag is set, loading an additional
copy of the module after it has been loaded once will return the previously
loaded object.
This will be done on a low level, using _PyImport_FixupExtensionObject.
@ -401,21 +405,21 @@ the interpreter state using three new functions, which parallel their
PyModuleDef counterparts, PyState_FindModule, PyState_AddModule,
and PyState_RemoveModule::
PyObject* PyState_FindSingletonModule(PyModuleDesc *desc)
int PyState_AddSingletonModule(PyObject *module, PyModuleDesc *desc)
int PyState_RemoveSingletonModule(PyModuleDesc *desc)
PyObject* PyState_FindSingletonModule(PyModuleExport *exp)
int PyState_AddSingletonModule(PyObject *module, PyModuleExport *exp)
int PyState_RemoveSingletonModule(PyModuleExport *exp)
.. note::
If PyModuleDef is used instead of PyModuleDesc, the flag would be specified
If PyModuleDef is used instead of PyModuleExport, the flag would be specified
as a slot with NULL value, i.e. ``{Py_mod_flag_singleton, NULL}``.
In this case, PyState_FindModule, PyState_AddModule and
PyState_RemoveModule can be used instead of the new functions.
.. note::
Another possibility is to use PyModuleDef_Base in PyModuleDesc, and
Another possibility is to use PyModuleDef_Base in PyModuleExport, and
have PyState_FindModule and friends work with either of the two structures.