From d7780468e2c583a377a9aa8ef5b86be04efdf239 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Fri, 17 Apr 2015 21:05:59 +0300 Subject: [PATCH] PEP 489: Update from Petr. --- pep-0489.txt | 62 ++++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/pep-0489.txt b/pep-0489.txt index 695fed6c9..ab51807e2 100644 --- a/pep-0489.txt +++ b/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_" 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.