Clarify PEP 523 with the settled C API for co_extra (#97)
This commit is contained in:
parent
5426603a2b
commit
81572832aa
52
pep-0523.txt
52
pep-0523.txt
|
@ -84,39 +84,35 @@ One field is to be added to the ``PyCodeObject`` struct
|
|||
|
||||
typedef struct {
|
||||
...
|
||||
PyObject *co_extra; /* "Scratch space" for the code object. */
|
||||
_PyCodeObjectExtra co_extra; /* "Scratch space" for the code object. */
|
||||
} PyCodeObject;
|
||||
|
||||
The ``co_extra`` will be ``NULL`` by default and will not be used by
|
||||
CPython itself. Third-party code is free to use the field as desired.
|
||||
Values stored in the field are expected to not be required in order
|
||||
for the code object to function, allowing the loss of the data of the
|
||||
field to be acceptable. The field will be freed like all other fields
|
||||
on ``PyCodeObject`` during deallocation using ``Py_XDECREF()``.
|
||||
The ``co_extra`` will be ``NULL`` by default and it is not planned to
|
||||
be used by CPython itself. Third-party code is free to use the field
|
||||
as desired. Values stored in the field are expected to not be required
|
||||
in order for the code object to function, allowing the loss of the
|
||||
data of the field to be acceptable.
|
||||
|
||||
Code using the field is expected to always store a tuple in the field.
|
||||
This allows for multiple users of the field to not trample over each
|
||||
other while being as performant as possible. Typical usage of the
|
||||
field is expected to roughly follow the following pseudo-code::
|
||||
A private API has been introduced to work with the field::
|
||||
|
||||
if co_extra is None:
|
||||
data = DataClass()
|
||||
co_extra = (data,)
|
||||
else:
|
||||
assert isinstance(co_extra, tuple)
|
||||
for x in co_extra:
|
||||
if isinstance(x, DataClass):
|
||||
data = x
|
||||
break
|
||||
else:
|
||||
data = DataClass()
|
||||
co_extra += (data,)
|
||||
PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
|
||||
PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index,
|
||||
void **extra);
|
||||
PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index,
|
||||
void *extra);
|
||||
|
||||
Using a list was considered but was found to be less performant, and
|
||||
with a key use-case being JIT usage the performance consideration it
|
||||
was deemed more important to use a tuple than a list. A tuple also
|
||||
makes more sense semantically as the objects stored in the tuple will
|
||||
be heterogeneous.
|
||||
Users of the field are expected to call
|
||||
``_PyEval_RequestCodeExtraIndex()`` to receive (what should be
|
||||
considered) an opaque index value to adding data into ``co-extra``.
|
||||
With that index, users can set data using ``_PyCode_SetExtra()`` and
|
||||
later retrieve the data with ``_PyCode_GetExtra()``. The API is
|
||||
purposefully listed as private to communicate the fact that there are
|
||||
no semantic guarantees of the API between Python releases.
|
||||
|
||||
Using a list and tuple were considered but was found to be less
|
||||
performant, and with a key use-case being JIT usage the performance
|
||||
consideration won out for using a custom struct instead of a Python
|
||||
object.
|
||||
|
||||
A dict was also considered, but once again performance was more
|
||||
important. While a dict will have constant overhead in looking up
|
||||
|
|
Loading…
Reference in New Issue