PEP 688: Enhance and clarify the specification (#2917)
Co-authored-by: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
parent
f68b3c1898
commit
58d49df46a
33
pep-0688.rst
33
pep-0688.rst
|
@ -122,14 +122,16 @@ object, for example by the ``memoryview()`` constructor.
|
|||
It corresponds to the ``bf_getbuffer`` C slot.
|
||||
The Python signature for this method is
|
||||
``def __buffer__(self, flags: int, /) -> memoryview: ...``. The method
|
||||
must return a ``memoryview`` object. If the method is called from C
|
||||
code, the interpreter extracts the underlying ``Py_buffer`` from the
|
||||
``memoryview`` and returns it to the C caller. Similarly, if the
|
||||
``__buffer__`` method is called on an instance of a C class that
|
||||
must return a ``memoryview`` object. If the ``bf_getbuffer`` slot
|
||||
is invoked on a Python class with a ``__buffer__`` method,
|
||||
the interpreter extracts the underlying ``Py_buffer`` from the
|
||||
``memoryview`` returned by the method
|
||||
and returns it to the C caller. Similarly, if Python code calls the
|
||||
``__buffer__`` method on an instance of a C class that
|
||||
implements ``bf_getbuffer``, the returned buffer is wrapped in a
|
||||
``memoryview`` for consumption by Python code.
|
||||
|
||||
The ``__release_buffer__`` method is called when a caller no
|
||||
The ``__release_buffer__`` method should be called when a caller no
|
||||
longer needs the buffer returned by ``__buffer__``. It corresponds to the
|
||||
``bf_releasebuffer`` C slot. This is an
|
||||
optional part of the buffer protocol.
|
||||
|
@ -137,11 +139,30 @@ The Python signature for this method is
|
|||
``def __release_buffer__(self, buffer: memoryview, /) -> None: ...``.
|
||||
The buffer to be released is wrapped in a ``memoryview``. When this
|
||||
method is invoked through CPython's buffer API (for example, through
|
||||
``memoryview.release``), the passed ``memoryview`` is the same object
|
||||
calling ``memoryview.release`` on a ``memoryview`` returned by
|
||||
``__buffer__``), the passed ``memoryview`` is the same object
|
||||
as was returned by ``__buffer__``. It is
|
||||
also possible to call ``__release_buffer__`` on a C class that
|
||||
implements ``bf_releasebuffer``.
|
||||
|
||||
If ``__release_buffer__`` exists on an object,
|
||||
Python code that calls ``__buffer__`` directly on the object must
|
||||
call ``__release_buffer__`` on the same object when it is done
|
||||
with the buffer. Otherwise, resources used by the object may
|
||||
not be reclaimed. Similarly, it is a programming error
|
||||
to call ``__release_buffer__`` without a previous call to
|
||||
``__buffer__``, or to call it multiple times for a single call
|
||||
to ``__buffer__``. For objects that implement the C buffer protocol,
|
||||
calls to ``__release_buffer__`` where the argument is not a
|
||||
``memoryview`` wrapping the same object will raise an exception.
|
||||
After a valid call to ``__release_buffer__``, the ``memoryview``
|
||||
is invalidated (as if its ``release()`` method had been called),
|
||||
and any subsequent calls to ``__release_buffer__`` with the same
|
||||
``memoryview`` will raise an exception.
|
||||
The interpreter will ensure that misuse
|
||||
of the Python API will not break invariants at the C level -- for
|
||||
example, it will not cause memory safety violations.
|
||||
|
||||
``inspect.BufferFlags``
|
||||
-----------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue