Buffer-Protokoll
****************

Bestimmte in Python verfügbare Objekte verpacken den Zugriff auf ein
zugrunde liegendes Speicherarray oder einen *Puffer*. Zu diesen
Objekten gehören die integrierten Typen „ "bytes" “ und „ "bytearray"
“ sowie einige Erweiterungstypen wie „ "array.array" “. Bibliotheken
von Drittanbietern können eigene Typen für spezielle Zwecke
definieren, beispielsweise für die Bildverarbeitung oder die
numerische Analyse.

Zwar hat jeder dieser Typen seine eigene Semantik, doch haben sie alle
gemeinsam, dass sie auf einem möglicherweise großen Speicherpuffer
basieren. In manchen Situationen ist es daher wünschenswert, direkt
und ohne zwischengeschaltete Kopiervorgänge auf diesen Puffer
zuzugreifen.

Python bietet eine solche Funktion auf C- und Python-Ebene in Form des
Buffer-Protokolls. Dieses Protokoll hat zwei Seiten:

* Auf der Produzentenseite kann ein Typ eine „Puffer-Schnittstelle“
  exportieren, die es Objekten dieses Typs ermöglicht, Informationen
  über ihren zugrunde liegenden Puffer bereitzustellen. Diese
  Schnittstelle wird im Abschnitt „ Buffer Object Structures “
  beschrieben; Informationen zu Python finden Sie unter Puffertypen
  emulieren.

* Auf der Verbraucherseite stehen verschiedene Möglichkeiten zur
  Verfügung, um einen Zeiger auf die zugrunde liegenden Rohdaten eines
  Objekts (beispielsweise einen Methodenparameter) zu erhalten. Für
  Python siehe "memoryview".

Einfache Objekte wie „ "bytes" “ und „ "bytearray" “ stellen ihren
zugrunde liegenden Puffer in byteorientierter Form bereit. Andere
Formen sind möglich; beispielsweise können die von einem „
"array.array" “ bereitgestellten Elemente Mehrbyte-Werte sein.

Ein Beispiel für die Nutzung der Puffer-Schnittstelle ist die Methode
„ "write()" “ von Datei-Objekten: Jedes Objekt, das eine Reihe von
Bytes über die Puffer-Schnittstelle exportieren kann, lässt sich in
eine Datei schreiben. Während „ "write()" “ lediglich Lesezugriff auf
den internen Inhalt des übergebenen Objekts benötigt, benötigen andere
Methoden wie „ "readinto()" “ Schreibzugriff auf den Inhalt ihres
Arguments.  Die Puffer-Schnittstelle ermöglicht es Objekten, den
Export von Lese-/Schreib- und Nur-Lese-Puffern selektiv zuzulassen
oder abzulehnen.

Es gibt zwei Möglichkeiten für einen Nutzer der Puffer-Schnittstelle,
einen Puffer über ein Zielobjekt zu beziehen:

* Rufen Sie „ "PyObject_GetBuffer()" “ mit den richtigen Parametern
  auf;

* rufe "PyArg_ParseTuple()" (oder eine der verwandten Funktionen) mit
  einem der Formatcodes "y*", "w*" oder "s*" auf.

In beiden Fällen muss „ "PyBuffer_Release()" “ aufgerufen werden,
sobald der Puffer nicht mehr benötigt wird.  Wird dies versäumt, kann
dies zu verschiedenen Problemen wie beispielsweise Ressourcenlecks
führen.

Added in version 3.12: Das Buffer-Protokoll ist nun in Python
verfügbar, siehe Puffertypen emulieren und "memoryview".


Pufferstruktur
==============

Pufferstrukturen (oder einfach „Puffer“) sind nützlich, um dem Python-
Programmierer die Binärdaten eines anderen Objekts zugänglich zu
machen. Sie können auch als Zero-Copy-Slicing-Mechanismus verwendet
werden. Dank ihrer Fähigkeit, auf einen Speicherblock zu verweisen,
ist es möglich, dem Python-Programmierer beliebige Daten ganz einfach
zugänglich zu machen.  Bei dem Speicher könnte es sich um ein großes,
konstantes Array in einer C-Erweiterung handeln, um einen rohen
Speicherblock, der vor der Übergabe an eine Betriebssystembibliothek
bearbeitet werden soll, oder um strukturierte Daten, die in ihrem
nativen Speicherformat weitergegeben werden sollen.

Im Gegensatz zu den meisten vom Python-Interpreter bereitgestellten
Datentypen sind Puffer keine Zeiger vom Typ „ "PyObject" “, sondern
einfache C-Strukturen. Dadurch lassen sie sich sehr einfach erstellen
und kopieren. Wenn ein generischer Wrapper um einen Puffer benötigt
wird, kann ein memoryview- -Objekt erstellt werden.

Eine kurze Anleitung zum Erstellen eines Exportobjekts finden Sie
unter Buffer Object Structures. Informationen zum Abrufen eines
Puffers finden Sie unter "PyObject_GetBuffer()".

type Py_buffer
    * Teil der Stable ABI (einschließlich aller Member) seit Version
   3.11.*

   void *buf

      Ein Zeiger auf den Anfang der durch die Pufferfelder
      beschriebenen logischen Struktur. Dies kann eine beliebige
      Stelle innerhalb des zugrunde liegenden physischen
      Speicherblocks des Exporteurs sein. Bei negativen Werten von `
      "strides" ` kann der Zeiger beispielsweise auf das Ende des
      Speicherblocks verweisen.

      Bei *zusammenhängenden* Arrays verweist der Wert auf den Anfang
      des Speicherblocks.

   PyObject *obj

      Eine neue Referenz auf das exportierende Objekt. Die Referenz
      befindet sich im Besitz des Verbrauchers und wird automatisch
      freigegeben (d.h., die Referenzzählung wird verringert) und von
      "PyBuffer_Release()" auf ` "NULL" gesetzt. Das Feld entspricht
      dem Rückgabewert einer beliebigen Standard-C-API-Funktion.

      Als Sonderfall gilt für *temporäre* Puffer, die von
      "PyMemoryView_FromBuffer()" oder "PyBuffer_FillInfo()"
      umschlossen sind, dass dieses Feld "NULL" lautet. Im Allgemeinen
      DÜRFEN exportierende Objekte dieses Schema NICHT verwenden.

   Py_ssize_t len

      "product(shape) * itemsize". Bei zusammenhängenden Arrays
      entspricht dies der Länge des zugrunde liegenden Speicherblocks.
      Bei nicht zusammenhängenden Arrays entspricht dies der Länge,
      die die logische Struktur hätte, wenn sie in eine
      zusammenhängende Darstellung kopiert würde.

      Der Zugriff auf "((char *)buf)[0] up to ((char *)buf)[len-1]"
      ist nur zulässig, wenn der Puffer durch eine Anfrage abgerufen
      wurde, die zusammenhängende Daten garantiert. In den meisten
      Fällen handelt es sich bei einer solchen Anfrage um
      "PyBUF_SIMPLE" oder "PyBUF_WRITABLE".

   int readonly

      Ein Indikator dafür, ob der Puffer schreibgeschützt ist. Dieses
      Feld wird durch das Flag „ "PyBUF_WRITABLE" “ gesteuert.

   Py_ssize_t itemsize

      Größe eines einzelnen Elements in Byte. Entspricht dem Wert von
      „ "struct.calcsize()" “, der für Werte aufgerufen wird, die
      nicht „"NULL" “ "format" sind.

      Wichtige Ausnahme: Wenn ein Verbraucher einen Puffer ohne das
      Flag „ "PyBUF_FORMAT" “ anfordert, wird „ "format" “ auf „
      "NULL" “ gesetzt, „ "itemsize" “ behält jedoch weiterhin den
      Wert des ursprünglichen Formats bei.

      Wenn „ "shape" “ vorhanden ist, gilt weiterhin die Gleichung „
      "product(shape) * itemsize == len" “, und der Verbraucher kann „
      "itemsize" “ verwenden, um durch den Puffer zu navigieren.

      Wenn „ "shape" “ infolge einer Anfrage an „ "PyBUF_SIMPLE" “
      oder „ "PyBUF_WRITABLE" “ zu „ "NULL" “ führt, muss der
      Verbraucher „ "itemsize" “ ignorieren und von „ "itemsize == 1"
      “ ausgehen.

   char *format

      Eine mit *NULL* abgeschlossene Zeichenkette im Syntaxstil des
      Moduls „ "struct" “, die den Inhalt eines einzelnen Elements
      beschreibt. Handelt es sich dabei um „ "NULL" “, wird „ ""B"" “
      (vorzeichenlose Bytes) angenommen.

      Dieses Feld wird durch das Flag „ "PyBUF_FORMAT" “ gesteuert.

   int ndim

      Die Anzahl der Dimensionen, die der Speicher als n-dimensionales
      Array darstellt. Wenn diese Zahl "0" ist, verweist "buf" auf ein
      einzelnes Element, das einen Skalar darstellt. In diesem Fall
      MÜSSEN "shape", "strides" und "suboffsets" "NULL" sein. Die
      maximale Anzahl der Dimensionen ist durch "PyBUF_MAX_NDIM"
      gegeben.

   Py_ssize_t *shape

      Ein Array von Typ „ "Py_ssize_t" “ der Länge „ "ndim" “, das die
      Form des Speichers als n-dimensionales Array angibt. Beachten
      Sie, dass „ "shape[0] * ... * shape[ndim-1] * itemsize" “
      unbedingt gleich „ "len" “ sein MUSS.

      Die Werte für „Shape“ sind auf „ "shape[n] >= 0" “ beschränkt.
      Der Fall „ "shape[n] == 0" “ erfordert besondere Beachtung.
      Weitere Informationen finden Sie unter „*complex arrays*“.

      Das Shape-Array ist für den Verbraucher schreibgeschützt.

   Py_ssize_t *strides

      Ein Array mit dem Namen „ "Py_ssize_t" “ der Länge „ "ndim" “,
      das die Anzahl der Bytes angibt, die übersprungen werden müssen,
      um in jeder Dimension zu einem neuen Element zu gelangen.

      Stride-Werte können beliebige ganze Zahlen sein. Bei regulären
      Arrays sind Strides in der Regel positiv, aber ein Verbraucher
      MUSS in der Lage sein, den Fall "strides[n] <= 0" zu
      verarbeiten. Weitere Informationen finden Sie unter *komplexe
      Arrays*.

      Das „strides“-Array ist für den Verbraucher schreibgeschützt.

   Py_ssize_t *suboffsets

      Ein Array von "Py_ssize_t" der Länge "ndim". Wenn "suboffsets[n]
      >= 0", sind die in der n-ten Dimension gespeicherten Werte
      Zeiger, und der Suboffset-Wert gibt an, wie viele Bytes nach der
      Dereferenzierung zu jedem Zeiger addiert werden sollen. Ein
      negativer Suboffset-Wert bedeutet, dass keine Dereferenzierung
      erfolgen soll (Striding in einem zusammenhängenden
      Speicherblock).

      Sind alle Teilversätze negativ (d. h., es ist keine
      Dereferenzierung erforderlich), muss dieses Feld den Wert „
      "NULL" “ annehmen (Standardwert).

      Diese Art der Array-Darstellung wird von der Python Imaging
      Library (PIL) verwendet. Weitere Informationen zum Zugriff auf
      Elemente eines solchen Arrays finden Sie unter complex arrays.

      Das „suboffsets“-Array ist für den Verbraucher schreibgeschützt.

   void *internal

      Dieser Wert ist für die interne Verwendung durch das
      exportierende Objekt bestimmt. Er kann beispielsweise vom
      Exporter in einen Ganzzahlwert umgewandelt und dazu verwendet
      werden, Flags zu speichern, die angeben, ob die Arrays „shape“,
      „strides“ und „suboffsets“ freigegeben werden müssen, wenn der
      Puffer freigegeben wird. Der Verbraucher DARF diesen Wert NICHT
      ändern.

Konstanten:

PyBUF_MAX_NDIM
    * Teil der Stable ABI seit Version 3.11.*

   Die maximale Anzahl an Dimensionen, die der Speicher darstellt.
   Exporteure MÜSSEN diese Grenze einhalten; Nutzer mehrdimensionaler
   Puffer SOLLTEN in der Lage sein, bis zu "PyBUF_MAX_NDIM"
   Dimensionen zu verarbeiten. Derzeit auf 64 festgelegt.


Arten von Pufferanforderungen
=============================

Puffer werden in der Regel dadurch abgerufen, dass eine
Pufferanforderung über "PyObject_GetBuffer()" an ein exportierendes
Objekt gesendet wird. Da die Komplexität der logischen Struktur des
Speichers stark variieren kann, gibt der Verbraucher über das Argument
*flags* den genauen Puffertyp an, den er verarbeiten kann.

Alle „ "Py_buffer" “-Felder werden durch den Anfragetyp eindeutig
definiert.


anfrageunabhängige Felder
-------------------------

Die folgenden Felder werden von *Flags* nicht beeinflusst und müssen
stets mit den richtigen Werten ausgefüllt werden: "obj", "buf", "len",
"itemsize", "ndim".


schreibgeschützt, Format
------------------------

   PyBUF_WRITABLE
       * Teil der Stable ABI seit Version 3.11.*

      Steuert das Feld „ "readonly" “. Ist dieses gesetzt, MUSS der
      Exporter einen beschreibbaren Puffer bereitstellen oder
      andernfalls einen Fehler melden. Andernfalls DARF der Exporter
      entweder einen schreibgeschützten oder einen beschreibbaren
      Puffer bereitstellen, die Wahl MUSS jedoch für alle Verbraucher
      einheitlich sein. Beispielsweise kann PyBUF_SIMPLE |
      PyBUF_WRITABLE verwendet werden, um einen einfachen
      beschreibbaren Puffer anzufordern.

   PyBUF_WRITEABLE

      This is a *soft deprecated* alias to "PyBUF_WRITABLE".

   PyBUF_FORMAT
       * Teil der Stable ABI seit Version 3.11.*

      Steuert das Feld „ "format" “. Wenn diese Option aktiviert ist,
      MUSS dieses Feld korrekt ausgefüllt werden. Andernfalls MUSS
      dieses Feld auf „ "NULL" “ gesetzt sein.

"PyBUF_WRITABLE" kann mit | an jedes der Flags im nächsten Abschnitt
angehängt werden. Da „ "PyBUF_SIMPLE" “ auf 0 gesetzt ist, kann „
"PyBUF_WRITABLE" “ als eigenständiges Flag verwendet werden, um einen
einfachen beschreibbaren Puffer anzufordern.

"PyBUF_FORMAT" muss mit einem der Flags außer „ "PyBUF_SIMPLE" “
kombiniert werden, da letzteres bereits das Format „ "B" “
(vorzeichenlose Bytes) impliziert. „ "PyBUF_FORMAT" “ kann nicht
eigenständig verwendet werden.


Form, Schrittlängen, Teilversätze
---------------------------------

Die Flags, die die logische Struktur des Speichers steuern, sind in
absteigender Reihenfolge ihrer Komplexität aufgeführt. Beachten Sie,
dass jedes Flag alle Bits der darunter liegenden Flags enthält.

+-------------------------------+---------+-----------+--------------+
| Anfrage                       | Form    | Schritte  | Teilversätze |
|===============================|=========|===========|==============|
| PyBUF_INDIRECT  * Teil der    | ja      | ja        | falls nötig  |
| Stable ABI seit Version       |         |           |              |
| 3.11.*                        |         |           |              |
+-------------------------------+---------+-----------+--------------+
| PyBUF_STRIDES  * Teil der     | ja      | ja        | NULL         |
| Stable ABI seit Version       |         |           |              |
| 3.11.*                        |         |           |              |
+-------------------------------+---------+-----------+--------------+
| PyBUF_ND  * Teil der Stable   | ja      | NULL      | NULL         |
| ABI seit Version 3.11.*       |         |           |              |
+-------------------------------+---------+-----------+--------------+
| PyBUF_SIMPLE  * Teil der      | NULL    | NULL      | NULL         |
| Stable ABI seit Version       |         |           |              |
| 3.11.*                        |         |           |              |
+-------------------------------+---------+-----------+--------------+


Anträge auf zusammenhängende Grundstücke
----------------------------------------

Ein *Zusammenhang* nach C- oder Fortran-Ordnung kann ausdrücklich
angefordert werden, mit oder ohne Stride-Angabe. Ohne Stride-Angabe
muss der Puffer C-zusammenhängend sein.

+-------------------------------------+---------+-----------+--------------+----------+
| Anfrage                             | Form    | Schritte  | Teilversätze | Contig   |
|=====================================|=========|===========|==============|==========|
| PyBUF_C_CONTIGUOUS  * Teil der      | ja      | ja        | NULL         | C        |
| Stable ABI seit Version 3.11.*      |         |           |              |          |
+-------------------------------------+---------+-----------+--------------+----------+
| PyBUF_F_CONTIGUOUS  * Teil der      | ja      | ja        | NULL         | F        |
| Stable ABI seit Version 3.11.*      |         |           |              |          |
+-------------------------------------+---------+-----------+--------------+----------+
| PyBUF_ANY_CONTIGUOUS  * Teil der    | ja      | ja        | NULL         | C oder F |
| Stable ABI seit Version 3.11.*      |         |           |              |          |
+-------------------------------------+---------+-----------+--------------+----------+
| "PyBUF_ND"                          | ja      | NULL      | NULL         | C        |
+-------------------------------------+---------+-----------+--------------+----------+


zusammengesetzte Anfragen
-------------------------

Alle möglichen Anfragen werden vollständig durch eine Kombination der
im vorigen Abschnitt genannten Flags definiert. Der Einfachheit halber
stellt das Pufferprotokoll häufig verwendete Kombinationen als
einzelne Flags zur Verfügung.

In der folgenden Tabelle steht *U* für eine undefinierte Kontiguität.
Der Verbraucher müsste die Funktion „ "PyBuffer_IsContiguous()" “
aufrufen, um die Kontiguität zu ermitteln.

+---------------------------------+---------+-----------+--------------+----------+------------+----------+
| Anfrage                         | Form    | Schritte  | Teilversätze | Contig   | schreibge  | Format   |
|                                 |         |           |              |          | schützt    |          |
|=================================|=========|===========|==============|==========|============|==========|
| PyBUF_FULL  * Teil der Stable   | ja      | ja        | falls nötig  | U        | 0          | ja       |
| ABI seit Version 3.11.*         |         |           |              |          |            |          |
+---------------------------------+---------+-----------+--------------+----------+------------+----------+
| PyBUF_FULL_RO  * Teil der       | ja      | ja        | falls nötig  | U        | 1 oder 0   | ja       |
| Stable ABI seit Version 3.11.*  |         |           |              |          |            |          |
+---------------------------------+---------+-----------+--------------+----------+------------+----------+
| PyBUF_RECORDS  * Teil der       | ja      | ja        | NULL         | U        | 0          | ja       |
| Stable ABI seit Version 3.11.*  |         |           |              |          |            |          |
+---------------------------------+---------+-----------+--------------+----------+------------+----------+
| PyBUF_RECORDS_RO  * Teil der    | ja      | ja        | NULL         | U        | 1 oder 0   | ja       |
| Stable ABI seit Version 3.11.*  |         |           |              |          |            |          |
+---------------------------------+---------+-----------+--------------+----------+------------+----------+
| PyBUF_STRIDED  * Teil der       | ja      | ja        | NULL         | U        | 0          | NULL     |
| Stable ABI seit Version 3.11.*  |         |           |              |          |            |          |
+---------------------------------+---------+-----------+--------------+----------+------------+----------+
| PyBUF_STRIDED_RO  * Teil der    | ja      | ja        | NULL         | U        | 1 oder 0   | NULL     |
| Stable ABI seit Version 3.11.*  |         |           |              |          |            |          |
+---------------------------------+---------+-----------+--------------+----------+------------+----------+
| PyBUF_CONTIG  * Teil der Stable | ja      | NULL      | NULL         | C        | 0          | NULL     |
| ABI seit Version 3.11.*         |         |           |              |          |            |          |
+---------------------------------+---------+-----------+--------------+----------+------------+----------+
| PyBUF_CONTIG_RO  * Teil der     | ja      | NULL      | NULL         | C        | 1 oder 0   | NULL     |
| Stable ABI seit Version 3.11.*  |         |           |              |          |            |          |
+---------------------------------+---------+-----------+--------------+----------+------------+----------+


Komplexe Arrays
===============


NumPy-Stil: Form und Schritte
-----------------------------

Die logische Struktur von Arrays im NumPy-Stil wird durch "itemsize",
"ndim", "shape" und "strides" definiert.

Wenn "ndim == 0" gilt, wird die Speicheradresse, auf die "buf"
verweist, als Skalar der Größe "itemsize" interpretiert. In diesem
Fall sind sowohl "shape" als auch "strides" "NULL" .

Wenn „ "strides" “ auf „ "NULL" “ gesetzt ist, wird das Array als
standardmäßiges n-dimensionales C-Array interpretiert. Andernfalls
muss der Verbraucher wie folgt auf ein n-dimensionales Array
zugreifen:

   ptr = (char *)buf + indices[0] * strides[0] + ... + indices[n-1] * strides[n-1];
   item = *((typeof(item) *)ptr);

Wie oben bereits erwähnt, kann ` "buf" ` auf eine beliebige Stelle
innerhalb des eigentlichen Speicherblocks verweisen. Ein Exporter kann
die Gültigkeit eines Puffers mit dieser Funktion überprüfen:

   def verify_structure(memlen, itemsize, ndim, shape, strides, offset):
       """Überprüft, ob die Parameter ein gültiges Array innerhalb
          der Grenzen des zugewiesenen Speichers darstellen:
              char *mem: Anfang des physischen Speicherblocks
              memlen: Länge des physischen Speicherblocks
              offset: (char *)buf – mem
       """
       if offset % itemsize:
           return False
       if offset < 0 or offset+itemsize > memlen:
           return False
       if any(v % itemsize for v in strides):
           return False

       wenn ndim <= 0:
           gibt ndim == 0 und nicht shape und nicht strides zurück
       wenn 0 in shape enthalten ist:
           gibt True zurück

       imin = sum(strides[j]*(shape[j]-1) for j in range(ndim)
                  if strides[j] <= 0)
       imax = sum(strides[j]*(shape[j]-1) for j in range(ndim)
                  if strides[j] > 0)

       return 0 <= offset+imin and offset+imax+itemsize <= memlen


PIL-Stil: Form, Schritte und Teilversätze
-----------------------------------------

Zusätzlich zu den regulären Elementen können Arrays im PIL-Stil Zeiger
enthalten, denen man folgen muss, um zum nächsten Element einer
Dimension zu gelangen. Beispielsweise lässt sich das reguläre
dreidimensionale C-Array "char v[2][2][3]" auch als Array aus 2
Zeigern auf 2 zweidimensionale Arrays betrachten: "char
(*v[2])[2][3]". In der Suboffset-Darstellung können diese beiden
Zeiger am Anfang von "buf" eingebettet werden und auf zwei Arrays vom
Typ "char x[2][3]" verweisen, die sich an beliebiger Stelle im
Speicher befinden können.

Hier ist eine Funktion, die einen Zeiger auf das Element in einem
N-dimensionalen Array zurückgibt, auf das ein N-dimensionaler Index
verweist, wenn sowohl nicht-"NULL" e Schritte als auch Teilversätze
vorhanden sind:

   void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides,
                          Py_ssize_t *suboffsets, Py_ssize_t *indices) {
       char *pointer = (char*)buf;
       int i;
       for (i = 0; i < ndim; i++) {
           pointer += strides[i] * indices[i];
           if (suboffsets[i] >= 0) {
               pointer = *((char**)pointer) + suboffsets[i];
           }
       }
       return (void*)pointer;
   }


Funktionen im Zusammenhang mit Puffern
======================================

int PyObject_CheckBuffer(PyObject *obj)
    * Teil der Stable ABI seit Version 3.11.*

   Gibt „ "1" “ zurück, wenn *obj* die Puffer-Schnittstelle
   unterstützt, andernfalls „ "0" “. Wenn „ "1" “ zurückgegeben wird,
   ist nicht garantiert, dass „ "PyObject_GetBuffer()" “ erfolgreich
   ist. Diese Funktion ist immer erfolgreich.

int PyObject_GetBuffer(PyObject *exporter, Py_buffer *view, int flags)
    * Teil der Stable ABI seit Version 3.11.*

   Sende eine Anfrage an *exporter*, um *view* gemäß den Angaben in
   *flags* auszufüllen. Wenn der Exporter keinen Puffer des genau
   angegebenen Typs bereitstellen kann, MUSS er eine Ausnahme vom Typ
   „ "BufferError" “ auslösen, "view->obj" auf „ "NULL" “ setzen und „
   "-1" “ zurückgeben.

   Bei Erfolg *view* ausfüllen, "view->obj" auf einen neuen Verweis
   auf *exporter* setzen und 0 zurückgeben. Bei verketteten Puffer-
   Providern, die Anfragen an ein einzelnes Objekt umleiten, KANN
   "view->obj" statt auf *exporter* auf dieses Objekt verweisen (siehe
   Buffer Object Structures).

   Erfolgreiche Aufrufe von „ "PyObject_GetBuffer()" “ müssen mit
   Aufrufen von „ "PyBuffer_Release()" “ gepaart werden, ähnlich wie
   bei „ "malloc()" “ und „ "free()" “. Nachdem der Verbraucher den
   Puffer verarbeitet hat, muss daher „ "PyBuffer_Release()" “ genau
   einmal aufgerufen werden.

void PyBuffer_Release(Py_buffer *view)
    * Teil der Stable ABI seit Version 3.11.*

   Geben Sie die *Ansicht* des Puffers frei und heben Sie die *starke
   Referenz* (d. h. verringern Sie die Referenzanzahl) auf das
   zugehörige Objekt der Ansicht, "view->obj", auf. Diese Funktion
   MUSS aufgerufen werden, wenn der Puffer nicht mehr verwendet wird,
   da es andernfalls zu Referenzlecks kommen kann.

   Es ist ein Fehler, diese Funktion für einen Puffer aufzurufen, der
   nicht über „ "PyObject_GetBuffer()" “ abgerufen wurde.

Py_ssize_t PyBuffer_SizeFromFormat(const char *format)
    * Teil der Stable ABI seit Version 3.11.*

   Gibt den impliziten „ "itemsize" “ aus „ "format" “ zurück. Bei
   einem Fehler wird eine Ausnahme ausgelöst und -1 zurückgegeben.

   Added in version 3.9.

int PyBuffer_IsContiguous(const Py_buffer *view, char order)
    * Teil der Stable ABI seit Version 3.11.*

   Gibt „ "1" “ zurück, wenn der durch *view* definierte Speicher im
   C-Stil (*order* ist „ "'C'" “) oder im Fortran-Stil (*order* ist „
   "'F'" “) *contiguous* ist oder beides (*order* ist „ "'A'" “).
   Andernfalls gibt die Funktion „ "0" “ zurück. Diese Funktion läuft
   immer erfolgreich ab.

void *PyBuffer_GetPointer(const Py_buffer *view, const Py_ssize_t *indices)
    * Teil der Stable ABI seit Version 3.11.*

   Rufe den Speicherbereich ab, auf den die *indices* innerhalb der
   angegebenen *view* verweisen. *indices* muss auf ein Array von
   "view->ndim" -Indizes verweisen.

int PyBuffer_FromContiguous(const Py_buffer *view, const void *buf, Py_ssize_t len, char fort)
    * Teil der Stable ABI seit Version 3.11.*

   Kopiert *len* zusammenhängende Bytes von *buf* nach *view*. *fort*
   kann entweder „ "'C'" “ oder „ "'F'" “ lauten (für die Reihenfolge
   im C- bzw. Fortran-Stil). Bei Erfolg wird „ "0" “ zurückgegeben,
   bei einem Fehler „ "-1" “.

int PyBuffer_ToContiguous(void *buf, const Py_buffer *src, Py_ssize_t len, char order)
    * Teil der Stable ABI seit Version 3.11.*

   Kopiert *len* Bytes von *src* in die zusammenhängende Darstellung
   in *buf*. *order* kann „ "'C'" “, „ "'F'" “ oder „ "'A'" “ lauten
   (für die Reihenfolge im C- oder Fortran-Stil bzw. eine beliebige
   davon). Bei Erfolg wird „ "0" “ zurückgegeben, bei einem Fehler „
   "-1" “.

   Diese Funktion schlägt fehl, wenn *len* != *src->len* ist.

int PyObject_CopyData(PyObject *dest, PyObject *src)
    * Teil der Stable ABI seit Version 3.11.*

   Kopiert Daten aus dem *src*-Puffer in den *dest*-Puffer. Ermöglicht
   die Konvertierung zwischen Puffern im C-Stil und im Fortran-Stil.

   "0" wird bei Erfolg zurückgegeben, bei einem Fehler „ "-1" “.

void PyBuffer_FillContiguousStrides(int ndims, Py_ssize_t *shape, Py_ssize_t *strides, int itemsize, char order)
    * Teil der Stable ABI seit Version 3.11.*

   Füllt das Array *strides* mit Byte-Strides eines
   *contiguous*-Arrays (im C-Stil, wenn *order* auf „ "'C'" “ gesetzt
   ist, oder im Fortran-Stil, wenn *order* auf „ "'F'" “ gesetzt ist)
   mit der angegebenen Form und der angegebenen Anzahl von Bytes pro
   Element.

int PyBuffer_FillInfo(Py_buffer *view, PyObject *exporter, void *buf, Py_ssize_t len, int readonly, int flags)
    * Teil der Stable ABI seit Version 3.11.*

   Behandelt Pufferanforderungen für einen Exporter, der *buf* mit der
   Größe *len* bereitstellen möchte, wobei die Schreibbarkeit
   entsprechend *readonly* festgelegt ist. *buf* wird als Folge von
   Bytes ohne Vorzeichen interpretiert.

   Das Argument *flags* gibt den Anforderungstyp an. Diese Funktion
   füllt *view* immer gemäß den in *flags* angegebenen Einstellungen,
   es sei denn, *buf* wurde als schreibgeschützt gekennzeichnet und in
   *flags* ist „ "PyBUF_WRITABLE" “ gesetzt.

   Bei Erfolg wird "view->obj" auf einen neuen Verweis auf
   **exporter** gesetzt und 0 zurückgegeben. Andernfalls wird ein
   "BufferError" ausgelöst, "view->obj" auf "NULL" gesetzt und "-1"
   zurückgegeben;

   Wird diese Funktion als Teil eines getbufferproc verwendet, MUSS
   *exporter* auf das exportierende Objekt gesetzt und *flags*
   unverändert übergeben werden. Andernfalls MUSS *exporter* auf „
   "NULL" “ gesetzt sein.
