Fix list formatting in PEP 573. (GH-1158)
This commit is contained in:
parent
6e4bb61652
commit
016d55f852
56
pep-0573.rst
56
pep-0573.rst
|
@ -78,13 +78,13 @@ Rationale
|
|||
PEP 489 introduced a new way to initialize extension modules, which brings
|
||||
several advantages to extensions that implement it:
|
||||
|
||||
* The extension modules behave more like their Python counterparts.
|
||||
* The extension modules can easily support loading into pre-existing
|
||||
module objects, which paves the way for extension module support for
|
||||
``runpy`` or for systems that enable extension module reloading.
|
||||
* Loading multiple modules from the same extension is possible, which
|
||||
makes testing module isolation (a key feature for proper sub-interpreter
|
||||
support) possible from a single interpreter.
|
||||
* The extension modules behave more like their Python counterparts.
|
||||
* The extension modules can easily support loading into pre-existing
|
||||
module objects, which paves the way for extension module support for
|
||||
``runpy`` or for systems that enable extension module reloading.
|
||||
* Loading multiple modules from the same extension is possible, which
|
||||
makes testing module isolation (a key feature for proper sub-interpreter
|
||||
support) possible from a single interpreter.
|
||||
|
||||
The biggest hurdle for adoption of PEP 489 is allowing access to module state
|
||||
from methods of extension types.
|
||||
|
@ -143,11 +143,11 @@ Background
|
|||
The implementation of a Python method may need access to one or more of
|
||||
the following pieces of information:
|
||||
|
||||
* The instance it is called on (``self``)
|
||||
* The underlying function
|
||||
* The class the method was defined in
|
||||
* The corresponding module
|
||||
* The module state
|
||||
* The instance it is called on (``self``)
|
||||
* The underlying function
|
||||
* The class the method was defined in
|
||||
* The corresponding module
|
||||
* The module state
|
||||
|
||||
In Python code, the Python-level equivalents may be retrieved as::
|
||||
|
||||
|
@ -178,14 +178,14 @@ This means that they only have access to their arguments and C level thread-loca
|
|||
and process-global states. Traditionally, many extension modules have stored
|
||||
their shared state in C-level process globals, causing problems when:
|
||||
|
||||
* running multiple initialize/finalize cycles in the same process
|
||||
* reloading modules (e.g. to test conditional imports)
|
||||
* loading extension modules in subinterpreters
|
||||
* running multiple initialize/finalize cycles in the same process
|
||||
* reloading modules (e.g. to test conditional imports)
|
||||
* loading extension modules in subinterpreters
|
||||
|
||||
PEP 3121 attempted to resolve this by offering the ``PyState_FindModule`` API, but this still has significant problems when it comes to extension methods (rather than module level functions):
|
||||
|
||||
* it is markedly slower than directly accessing C-level process-global state
|
||||
* there is still some inherent reliance on process global state that means it still doesn't reliably handle module reloading
|
||||
* it is markedly slower than directly accessing C-level process-global state
|
||||
* there is still some inherent reliance on process global state that means it still doesn't reliably handle module reloading
|
||||
|
||||
It's also the case that when looking up a C-level struct such as module state, supplying
|
||||
an unexpected object layout can crash the interpreter, so it's significantly more important to ensure that extension
|
||||
|
@ -205,13 +205,13 @@ The additional module level context described above can be made available with t
|
|||
Both additions are optional; extension authors need to opt in to start
|
||||
using them:
|
||||
|
||||
* Add a pointer to the module to heap type objects.
|
||||
* Add a pointer to the module to heap type objects.
|
||||
|
||||
* Pass the defining class to the underlying C function.
|
||||
* Pass the defining class to the underlying C function.
|
||||
|
||||
The defining class is readily available at the time built-in
|
||||
method object (``PyCFunctionObject``) is created, so it can be stored
|
||||
in a new struct that extends ``PyCFunctionObject``.
|
||||
The defining class is readily available at the time built-in
|
||||
method object (``PyCFunctionObject``) is created, so it can be stored
|
||||
in a new struct that extends ``PyCFunctionObject``.
|
||||
|
||||
The module state can then be retrieved from the module object via
|
||||
``PyModule_GetState``.
|
||||
|
@ -233,12 +233,12 @@ The problem with slot methods is that their C API is fixed, so we can't
|
|||
simply add a new argument to pass in the defining class.
|
||||
Two possible solutions have been proposed to this problem:
|
||||
|
||||
* Look up the class through walking the MRO.
|
||||
This is potentially expensive, but will be useful if performance is not
|
||||
a problem (such as when raising a module-level exception).
|
||||
* Storing a pointer to the defining class of each slot in a separate table,
|
||||
``__typeslots__`` [#typeslots-mail]_. This is technically feasible and fast,
|
||||
but quite invasive.
|
||||
* Look up the class through walking the MRO.
|
||||
This is potentially expensive, but will be useful if performance is not
|
||||
a problem (such as when raising a module-level exception).
|
||||
* Storing a pointer to the defining class of each slot in a separate table,
|
||||
``__typeslots__`` [#typeslots-mail]_. This is technically feasible and fast,
|
||||
but quite invasive.
|
||||
|
||||
Due to the invasiveness of the latter approach, this PEP proposes adding an MRO walking
|
||||
helper for use in slot method implementations, deferring the more complex alternative
|
||||
|
|
Loading…
Reference in New Issue