Showing content from http://mail.python.org/pipermail/python-dev/attachments/20180426/d065a6dd/attachment-0001.html below:
<div dir="ltr"><div><br></div>Thanks for working on this, Marcel (and Petr). This looks like an ambitious intern project :) Couple of questions and comments in-line.<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 23, 2018 at 12:36 PM, Marcel Plch <span dir="ltr"><<a href="mailto:gmarcel.plch@gmail.com" target="_blank">gmarcel.plch@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
I am an intern at Red Hat mentored by Petr Viktorin. As a part of my<br>
internship, I learned the CPython internals and how to contribute<br>
to the CPython interpreter.<br>
<br>
As a result, I have prepared PEP 573, which solves some problems<br>
that PEP 489 (Multi-phase extension module initialization) has left open.<br>
Specifically, this PEP proposes a way to access per-module state from methods of<br>
built-in and extension types.<br>
Like PEP 489, it aims to make subinterpreter-friendly built-in/extension modules<br>
easier to create.<br>
<br>
A big problem found when converting many modules to PEP 489 multi-phase<br>
initialization is subinterpreter-friendly access to exception<br>
types defined in built-in/extension modules.<br>
This PEP solves this by introducing "immutable exception types".<br>
The current implementation requires one new type flag and two new<br>
pointers in the heap type structure.<br>
It should be possible to remove eiher the flag or one of the two pointers,<br>
if we agree on the other mechanics in the PEP .<br>
<br>
<br>
===================<br>
<br>
PEP: 573<br>
Title: Module State Access from C Extension Methods<br>
Version: $Revision$<br>
Last-Modified: $Date$<br>
Author: Petr Viktorin <<a href="mailto:encukou@gmail.com">encukou@gmail.com</a>>,<br>
    Nick Coghlan <<a href="mailto:ncoghlan@gmail.com">ncoghlan@gmail.com</a>>,<br>
    Eric Snow <<a href="mailto:ericsnowcurrently@gmail.com">ericsnowcurrently@gmail.com</a>>,<br>
    Marcel Plch <<a href="mailto:gmarcel.plch@gmail.com">gmarcel.plch@gmail.com</a>><br>
Discussions-To: <a href="mailto:import-sig@python.org">import-sig@python.org</a><br>
Status: Active<br>
Type: Process<br>
Content-Type: text/x-rst<br>
Created: 02-Jun-2016<br>
Python-Version: 3.8<br>
Post-History:<br>
<br>
<br>
Abstract<br>
========<br>
<br>
This PEP proposes to add a way for CPython extension methods to access<br>
context such as<br>
the state of the modules they are defined in.<br>
<br>
This will allow extension methods to use direct pointer dereferences<br>
rather than PyState_FindModule for looking up module state, reducing<br>
or eliminating the<br>
performance cost of using module-scoped state over process global state.<br>
<br>
This fixes one of the remaining roadblocks for adoption of PEP 3121 (Extension<br>
module initialization and finalization) and PEP 489<br>
(Multi-phase extension module initialization).<br>
<br>
Additionaly, support for easier creation of immutable exception<br>
classes is added.<br></blockquote><div><br></div><div>I'm not a fan of using 'immutable' here, or in the API function name. I understand the types are to some extent immutable (apart from their refcount, I assume), but I think it's going to be too easy to confuse it with types whose *instances* are immutable. (We do occasionally say things like "tuples are an immutable type".) Since the point is that they behave like statically defined ones, perhaps 'Static' would be a reasonable replacement.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This removes the need for keeping per-module state if it would only be used<br>
for exception classes.<br>
<br>
While this PEP takes an additional step towards fully solving the<br>
problems that PEP 3121 and PEP 489 started<br>
tackling, it does not attempt to resolve *all* remaining concerns. In<br>
particular, accessing the module state from slot methods (``nb_add``,<br>
etc) remains slower than accessing that state from other extension<br>
methods.<br>
<br>
<br>
Terminology<br>
===========<br>
<br>
Process-Global State<br>
--------------------<br>
<br>
C-level static variables. Since this is very low-level<br>
memory storage, it must be managed carefully.<br>
<br>
Per-module State<br>
----------------<br>
<br>
State local to a module object, allocated dynamically as part of a<br>
module object's initialization. This isolates the state from other<br>
instances of the module (including those in other subinterpreters).<br>
<br>
Accessed by ``PyModule_GetState()``.<br>
<br>
<br>
Static Type<br>
-----------<br>
<br>
A type object defined as a C-level static variable, i.e. a compiled-in<br>
type object.<br>
<br>
A static type needs to be shared between module instances and has no<br>
information of what module it belongs to.<br>
Static types do not have ``__dict__`` (although their instances might).<br>
<br>
Heap Type<br>
---------<br>
<br>
A type object created at run time.<br>
<br>
<br>
Rationale<br>
=========<br>
<br>
PEP 489 introduced a new way to initialize extension modules, which brings<br>
several advantages to extensions that implement it:<br>
<br>
  * The extension modules behave more like their Python counterparts.<br>
  * The extension modules can easily support loading into pre-existing<br>
   module objects, which paves the way for extension module support for<br>
   ``runpy`` or for systems that enable extension module reloading.<br>
  * Loading multiple modules from the same extension is possible, which<br>
   makes testing module isolation (a key feature for proper sub-interpreter<br>
   support) possible from a single interpreter.<br>
<br>
The biggest hurdle for adoption of PEP 489 is allowing access to module state<br>
from methods of extension types.<br>
Currently, the way to access this state from extension methods is by<br>
looking up the module via<br>
``PyState_FindModule`` (in contrast to module level functions in<br>
extension modules, which<br>
receive a module reference as an argument).<br>
However, ``PyState_FindModule`` queries the thread-local state, making<br>
it relatively<br>
costly compared to C level process global access and consequently<br>
deterring module authors from using it.<br>
<br>
Also, ``PyState_FindModule`` relies on the assumption that in each<br>
subinterpreter, there is at most one module corresponding to<br>
a given ``PyModuleDef``. This does not align well with Python's import<br>
machinery. Since PEP 489 aimed to fix that, the assumption does<br>
not hold for modules that use multi-phase initialization, so<br>
``PyState_FindModule`` is unavailable for these modules.<br>
<br>
A faster, safer way of accessing module-level state from extension methods<br>
is needed.<br>
<br>
<br>
Immutable Exception Types<br>
-------------------------<br>
<br>
For isolated modules to work, any class whose methods touch module state<br>
must be a heap type, so that each instance of a module can have its own<br>
type object. With the changes proposed in this PEP, heap type instances will<br>
have access to module state without global registration. But, to create<br>
instances of heap types, one will need the module state in order to<br>
get the type object corresponding to the appropriate module.<br>
In short, heap types are "viral" â anything that âtouchesâ them must itself be<br>
a heap type.<br>
<br>
Curently, most exception types, apart from the ones in ``builtins``, are<br>
heap types. This is likely simply because there is a convenient way<br>
to create them: ``PyErr_NewException``.<br>
Heap types generally have a mutable ``__dict__``.<br>
In most cases, this mutability is harmful. For example, exception types<br>
from the ``sqlite`` module are mutable and shared across subinterpreters.<br>
This allows "smuggling" values to other subinterpreters via attributes of<br>
``sqlite3.Error``.<br>
<br>
Moreover, since raising exceptions is a common operation, and heap types<br>
will be "viral", ``PyErr_NewException`` will tend to "infect" the module<br>
with "heap type-ness" â at least if the module decides play well with<br>
subinterpreters/isolation.<br>
Many modules could go without module state<br>
entirely if the exception classes were immutable.<br>
<br>
To solve this problem, a new function for creating immutable exception types<br>
is proposed.<br>
<br>
<br>
Background<br>
===========<br>
<br>
The implementation of a Python method may need access to one or more of<br>
the following pieces of information:<br>
<br>
  * The instance it is called on (``self``)<br>
  * The underlying function<br>
  * The class the method was defined in<br>
  * The corresponding module<br>
  * The module state<br>
<br>
In Python code, the Python-level equivalents may be retrieved as::<br>
<br>
  import sys<br>
<br>
    def meth(self):<br>
      instance = self<br>
      module_globals = globals()<br>
      module_object = sys.modules[__name__] # (1)<br>
      underlying_function = Foo.meth     # (1)<br>
      defining_class = Foo          # (1)<br>
      defining_class = __class__       # (2)<br>
<br>
.. note::<br>
<br>
  The defining class is not ``type(self)``, since ``type(self)`` might<br>
  be a subclass of ``Foo``.<br>
<br>
The statements marked (1) implicitly rely on name-based lookup via the<br>
function's ``__globals__``:<br>
either the ``Foo`` attribute to access the defining class and Python<br>
function object, or ``__name__`` to find the module object in<br>
``sys.modules``.<br>
In Python code, this is feasible, as ``__globals__`` is set<br>
appropriately when the function definition is executed, and<br>
even if the namespace has been manipulated to return a different<br>
object, at worst an exception will be raised.<br>
<br>
The ``__class__`` closure, (2), is a safer way to get the defining<br>
class, but it still relies on ``__closure__`` being set appropriately.<br>
<br>
By contrast, extension methods are typically implemented as normal C functions.<br>
This means that they only have access to their arguments and C level<br>
thread-local<br>
and process-global states. Traditionally, many extension modules have stored<br>
their shared state in C-level process globals, causing problems when:<br>
<br>
  * running multiple initialize/finalize cycles in the same process<br>
  * reloading modules (e.g. to test conditional imports)<br>
  * loading extension modules in subinterpreters<br>
<br>
PEP 3121 attempted to resolve this by offering the<br>
``PyState_FindModule`` API, but this still has significant problems<br>
when it comes to extension methods (rather than module level<br>
functions):<br>
<br>
  * it is markedly slower than directly accessing C-level process-global state<br>
  * there is still some inherent reliance on process global state<br>
that means it still doesn't reliably handle module reloading<br>
<br>
It's also the case that when looking up a C-level struct such as<br>
module state, supplying<br>
an unexpected object layout can crash the interpreter, so it's<br>
significantly more important to ensure that extension<br>
methods receive the kind of object they expect.<br>
<br>
Proposal<br>
========<br>
<br>
Currently, a bound extension method (``PyCFunction`` or<br>
``PyCFunctionWithKeywords``) receives only<br>
``self``, and (if applicable) the supplied positional and keyword arguments.<br>
<br>
While module-level extension functions already receive access to the<br>
defining module object via their<br>
``self`` argument, methods of extension types don't have that luxury:<br>
they receive the bound instance<br>
via ``self``, and hence have no direct access to the defining class or<br>
the module level state.<br>
<br>
The additional module level context described above can be made<br>
available with two changes.<br>
Both additions are optional; extension authors need to opt in to start<br>
using them:<br>
<br>
  * Add a pointer to the module to heap type objects.<br>
<br>
  * Pass the defining class to the underlying C function.<br>
<br>
   The defining class is readily available at the time built-in<br>
   method object (``PyCFunctionObject``) is created, so it can be stored<br>
   in a new struct that extends ``PyCFunctionObject``.<br>
<br>
The module state can then be retrieved from the module object via<br>
``PyModule_GetState``.<br>
<br>
Note that this proposal implies that any type whose method needs to access<br>
per-module state must be a heap type, rather than a static type.<br>
<br>
This is necessary to support loading multiple module objects from a single<br>
extension: a static type, as a C-level global, has no information about<br>
which module it belongs to.<br>
<br>
<br>
Slot methods<br>
------------<br>
<br>
The above changes don't cover slot methods, such as ``tp_iter`` or ``nb_add``.<br>
<br>
The problem with slot methods is that their C API is fixed, so we can't<br>
simply add a new argument to pass in the defining class.<br>
Two possible solutions have been proposed to this problem:<br>
<br>
  * Look up the class through walking the MRO.<br>
   This is potentially expensive, but will be useful if performance is not<br>
   a problem (such as when raising a module-level exception).<br>
  * Storing a pointer to the defining class of each slot in a separate table,<br>
   ``__typeslots__`` [#typeslots-mail]_. This is technically<br>
feasible and fast,<br>
   but quite invasive.<br>
<br>
Due to the invasiveness of the latter approach, this PEP proposes<br>
adding an MRO walking<br>
helper for use in slot method implementations, deferring the more<br>
complex alternative<br>
as a potential future optimisation. Modules affected by this concern<br>
also have the<br>
option of using thread-local state or PEP 567 context variables, or<br>
else defining their<br>
own reload-friendly lookup caching scheme.<br></blockquote><div><br></div><div>I do not believe walking the MRO is going to work without reworking the implementation of types, specifically how typeobject.c deals with slots of subclasses: in some cases copies the slots from the base class (see inherit_slots() and from where it's called). I believe this would cause problems if, for example, you define type X in module A, subclass it from type Y in module B without overriding the slot, and try to find the module object for A from the slot implementation. I don't think copying slots is a requirement for the desired semantics, but it's going to be fairly involved to rewrite it to do something else. There's also backward-compatibility to consider: third-party libraries can be inheriting from builtin types (e.g. numpy does this extensively) using the same copying-slot mechanism, which means those builtin types can't use the MRO walking to find their module without breaking compatibility with those third-party libraries.</div><div>Â </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
Immutable Exception Types<br>
-------------------------<br>
<br>
To faciliate creating static exception classes, a new function is proposed:<br>
``PyErr_<wbr>PrepareImmutableException``. It will work similarly to<br>
``PyErr_NewExceptionWithDoc``<br>
but will take a ``PyTypeObject **`` pointer, which points to a<br>
``PyTypeObject *`` that is<br>
either ``NULL`` or an initialized ``PyTypeObject``.<br>
This pointer may be declared in process-global state. The function will then<br>
allocate the object and will keep in mind that already existing exception<br>
should not be overwritten.<br>
<br>
The extra indirection makes it possible to make<br>
``PyErr_<wbr>PrepareImmutableException``<br>
part of the stable ABI by having the Python interpreter, rather than<br>
extension code,<br>
allocate the ``PyTypeObject``.<br>
<br>
<br>
Specification<br>
=============<br>
<br>
Adding module references to heap types<br>
------------------------------<wbr>--------<br>
<br>
The ``PyHeapTypeObject`` struct will get a new member, ``PyObject *ht_module``,<br>
that can store a pointer to the module object for which the type was defined.<br>
It will be ``NULL`` by default, and should not be modified after the type<br>
object is created.<br>
<br>
A new factory method will be added for creating modules::<br>
<br>
  PyObject* PyType_FromModuleAndSpec(<wbr>PyObject *module,<br>
                    PyType_Spec *spec,<br>
                    PyObject *bases)<br>
<br>
This acts the same as ``PyType_FromSpecWithBases``, and additionally sets<br>
``ht_module`` to the provided module object.<br>
<br>
Additionally, an accessor, ``PyObject * PyType_GetModule(PyTypeObject *)``<br>
will be provided.<br>
It will return the ``ht_module`` if a heap type with module pointer set<br>
is passed in, otherwise it will set a SystemError and return NULL.<br>
<br>
Usually, creating a class with ``ht_module`` set will create a reference<br>
cycle involving the class and the module.<br>
This is not a problem, as tearing down modules is not a performance-sensitive<br>
operation (and module-level functions typically also create reference cycles).<br>
The existing "set all module globals to None" code that breaks function cycles<br>
through ``f_globals`` will also break the new cycles through ``ht_module``.<br>
<br>
<br>
Passing the defining class to extension methods<br>
------------------------------<wbr>-----------------<br>
<br>
A new style of C-level functions will be added to the current selection of<br>
``PyCFunction`` and ``PyCFunctionWithKeywords``::<br>
<br>
  PyObject *PyCMethod(PyObject *self,<br>
            PyTypeObject *defining_class,<br>
            PyObject *args, PyObject *kwargs)<br>
<br>
A new method object flag, ``METH_METHOD``, will be added to signal that<br>
the underlying C function is ``PyCMethod``.<br>
<br>
To hold the extra information, a new structure extending ``PyCFunctionObject``<br>
will be added::<br>
<br>
  typedef struct {<br>
    PyCFunctionObject func;<br>
    PyTypeObject *mm_class; /* Passed as 'defining_class' arg to<br>
the C func */<br>
  } PyCMethodObject;<br>
<br>
To allow passing the defining class to the underlying C function, a change<br>
to private API is required, now ``_PyMethodDef_<wbr>RawFastCallDict`` and<br>
``_PyMethodDef_<wbr>RawFastCallKeywords`` will receive ``PyTypeObject *cls``<br>
as one of their arguments.<br>
<br>
A new macro ``PyCFunction_GET_CLASS(cls)`` will be added for easier<br>
access to mm_class.<br>
<br>
Method construction and calling code and will be updated to honor<br>
``METH_METHOD``.<br>
<br>
<br>
Argument Clinic<br>
---------------<br>
<br>
To support passing the defining class to methods using Argument Clinic,<br>
a new converter will be added to clinic.py: ``defining_class``.<br>
<br>
Each method may only have one argument using this converter, and it must<br>
appear after ``self``, or, if ``self`` is not used, as the first argument.<br>
The argument will be of type ``PyTypeObject *``.<br>
<br>
When used, Argument Clinic will select ``METH_METHOD`` as the calling<br>
convention.<br>
The argument will not appear in ``__text_signature__``.<br>
<br>
This will be compatible with ``__init__`` and ``__new__`` methods, where an<br>
MRO walker will be used to pass the defining class from clinic generated<br>
code to the user's function.<br>
<br>
<br>
Slot methods<br>
------------<br>
<br>
To allow access to per-module state from slot methods, an MRO walker<br>
will be implemented::<br>
<br>
  PyTypeObject *PyType_<wbr>DefiningTypeFromSlotFunc(<wbr>PyTypeObject *type,<br>
                         int slot, void *func)<br>
<br>
The walker will go through bases of heap-allocated ``type``<br>
and search for class that defines ``func`` at its ``slot``.<br>
<br>
The ``func`` needs not to be inherited by ``type``, only requirement<br>
for the walker to find the defining class is that the defining class<br>
must be heap-allocated.<br>
<br>
On failure, exception is set and NULL is returned.<br>
<br>
<br>
Static exceptions<br>
-----------------<br>
<br>
A new function will be added::<br>
<br>
  int PyErr_<wbr>PrepareImmutableException(<wbr>PyTypeObject **exc,<br>
                   const char *name,<br>
                   const char *doc,<br>
                   PyObject *base)<br>
<br>
Creates an immutable exception type which can be shared<br>
across multiple module objects.<br></blockquote><div><br></div><div>How is this going to deal with type.__subclasses__()? Is re-using the static type object between reloads and sub-interpreters important enough to warrant the different behaviour? What if sub-interpreters end up wanting to disallow sharing objects between them?</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If the type already exists (determined by a process-global pointer,<br>
``*exc``), skip the initialization and only ``INCREF`` it.<br>
<br>
If ``*exc`` is NULL, the function will<br>
allocate a new exception type and initialize it using given parameters<br>
the same way ``PyType_FromSpecAndBases`` would.<br>
The ``doc`` and ``base`` arguments may be ``NULL``, defaulting to a<br>
missing docstring and ``PyExc_Exception`` base class, respectively.<br>
The exception type's ``tp_flags`` will be set to values common to<br>
built-in exceptions and the ``Py_TPFLAGS_HEAP_IMMUTABLE`` flag (see below)<br>
will be set.<br>
On failure, ``PyErr_<wbr>PrepareImmutableException`` will set an exception<br>
and return -1.<br>
<br>
If called with an initialized exception type (``*exc``<br>
is non-NULL), the function will do nothing but incref ``*exc``.<br>
<br>
A new flag, ``Py_TPFLAGS_HEAP_IMMUTABLE``, will be added to prevent<br>
mutation of the type object. This makes it possible to<br>
share the object safely between multiple interpreters.<br>
This flag is checked in ``type_setattro`` and blocks<br>
setting of attributes when set, similar to built-in types.<br>
<br>
A new pointer, ``ht_moduleptr``, will be added to heap types to store ``exc``.<br>
<br>
On deinitialization of the exception type, ``*exc`` will be set to ``NULL``.<br>
This makes it safe for ``PyErr_<wbr>PrepareImmutableException`` to check if<br>
the exception was already initialized.<br>
<br>
PyType_offsets<br>
--------------<br>
<br>
Some extension types are using instances with ``__dict__`` or ``__weakref__``<br>
allocated. Currently, there is no way of passing offsets of these through<br>
``PyType_Spec``. To allow this, a new structure and a spec slot are proposed.<br>
<br>
A new structure, ``PyType_offsets``, will have two members containing the<br>
offsets of ``__dict__`` and ``__weakref__``::<br>
<br>
  typedef struct {<br>
    Py_ssize_t dict;<br>
    Py_ssize_t weaklist;<br>
  } PyType_offsets;<br>
<br>
The new slot, ``Py_offsets``, will be used to pass a ``PyType_offsets *``<br>
structure containing the mentioned data.<br>
<br>
<br>
Helpers<br>
-------<br>
<br>
Getting to per-module state from a heap type is a very common task. To make this<br>
easier, a helper will be added::<br>
<br>
  void *PyType_GetModuleState(<wbr>PyObject *type)<br>
<br>
This function takes a heap type and on success, it returns pointer to<br>
state of the<br>
module that the heap type belongs to.<br>
<br>
On failure, two scenarios may occure. When a type without a module is passed in,<br>
``SystemError`` is set and ``NULL`` returned. If the module is found, pointer<br>
to the state, which may be ``NULL``, is returned without setting any exception.<br>
<br>
<br>
Modules Converted in the Initial Implementation<br>
------------------------------<wbr>-----------------<br>
<br>
To validate the approach, several modules will be modified during<br>
the initial implementation:<br>
<br>
The ``zipimport``, ``_io``, ``_elementtree``, and ``_csv`` modules<br>
will be ported to PEP 489 multiphase initialization.<br></blockquote><div><br></div><div>zipimport currently caches things in C globals. Changing it to use PEP 489 multi-phase initialisation is very likely going to change semantics in subtle ways... Is it really worth the risk?</div><div>Â </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
Summary of API Changes and Additions<br>
==============================<wbr>======<br>
<br>
New functions:<br>
<br>
* PyType_GetModule<br>
* PyType_<wbr>DefiningTypeFromSlotFunc<br>
* PyType_GetModuleState<br>
* PyErr_<wbr>PrepareImmutableException<br>
<br>
New macros:<br>
<br>
* PyCFunction_GET_CLASS<br>
<br>
New types:<br>
<br>
* PyCMethodObject<br>
<br>
New structures:<br>
<br>
* PyType_offsets<br>
<br>
Modified functions:<br>
<br>
* _PyMethodDef_RawFastCallDict now receives ``PyTypeObject *cls``.<br>
* _PyMethodDef_<wbr>RawFastCallKeywords now receives ``PyTypeObject *cls``.<br>
<br>
Modified structures:<br>
<br>
* _heaptypeobject - added ht_module and ht_moduleptr<br>
<br>
Other changes:<br>
<br>
* METH_METHOD call flag<br>
* defining_class converter in clinic<br>
* Py_TPFLAGS_HEAP_IMMUTABLE flag<br>
* Py_offsets type spec slot<br>
<br>
<br>
Backwards Compatibility<br>
=======================<br>
<br>
Two new pointers are added to all heap types.<br>
All other changes are adding new functions, structures and a type flag.<br>
<br>
The new ``PyErr_<wbr>PrepareImmutableException`` function changes encourages<br>
modules to switch from using heap type Exception classes to immutable ones,<br>
and a number of modules will be switched in the initial implementation.<br>
This change will prevent adding class attributes to such types.<br>
For example, the following will raise AttributeError::<br>
<br>
  sqlite.OperationalError.foo = None<br>
<br>
Instances and subclasses of such exceptions will not be affected.<br>
<br>
Implementation<br>
==============<br>
<br>
An initial implementation is available in a Github repository [#gh-repo]_;<br>
a patchset is at [#gh-patch]_.<br>
<br>
<br>
Possible Future Extensions<br>
==========================<br>
<br>
Easy creation of types with module references<br>
------------------------------<wbr>---------------<br>
<br>
It would be possible to add a PEP 489 execution slot type to make<br>
creating heap types significantly easier than calling<br>
``PyType_FromModuleAndSpec``.<br>
This is left to a future PEP.<br>
<br>
<br>
Optimization<br>
------------<br>
<br>
CPython optimizes calls to methods that have restricted signatures,<br>
such as not allowing keyword arguments.<br>
<br>
As proposed here, methods defined with the ``METH_METHOD`` flag do not support<br>
these optimizations.<br>
<br>
Optimized calls still have the option of accessing per-module state<br>
the same way slot methods do.<br>
<br>
<br>
References<br>
==========<br>
<br>
.. [#typeslots-mail] [Import-SIG] On singleton modules, heap types,<br>
and subinterpreters<br>
  (<a href="https://mail.python.org/pipermail/import-sig/2015-July/001035.html" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>pipermail/import-sig/2015-<wbr>July/001035.html</a>)<br>
<br>
.. [#gh-repo]<br>
  <a href="https://github.com/Traceur759/cpython/commits/pep-c" rel="noreferrer" target="_blank">https://github.com/Traceur759/<wbr>cpython/commits/pep-c</a><br>
<br>
.. [#gh-patch]<br>
  <a href="https://github.com/Traceur759/cpython/compare/master...Traceur759:pep-c.patch" rel="noreferrer" target="_blank">https://github.com/Traceur759/<wbr>cpython/compare/master...<wbr>Traceur759:pep-c.patch</a><br>
<br>
<br>
Copyright<br>
=========<br>
<br>
This document has been placed in the public domain.<br>
______________________________<wbr>_________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/thomas%40python.org" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/options/python-dev/<wbr>thomas%40python.org</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Thomas Wouters <<a href="mailto:thomas@python.org" target="_blank">thomas@python.org</a>><br><br>Hi! I'm an email virus! Think twice before sending your email to help me spread!</div>
</div></div>
RetroSearch is an open source project built by @garambo
| Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4