PEP 489: Update from Petr.
This commit is contained in:
parent
cb84322924
commit
d7780468e2
62
pep-0489.txt
62
pep-0489.txt
|
@ -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.
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue