PEP 688: Enhance and clarify the specification (#2917)

Co-authored-by: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
Jelle Zijlstra 2022-12-20 09:58:44 -08:00 committed by GitHub
parent f68b3c1898
commit 58d49df46a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 27 additions and 6 deletions

View File

@ -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``
-----------------------