Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 286 – Verbesserte Argument-Tupel

Autor:
Martin von Löwis <martin at v.loewis.de>
Status:
Verschoben
Typ:
Standards Track
Erstellt:
03.03.2002
Python-Version:
2.3
Post-History:


Inhaltsverzeichnis

Zusammenfassung

PyArg_ParseTuple hat Probleme mit der Speicherverwaltung, wenn ein Argumentkonverter neuen Speicher erstellt. Um diese Fälle zu behandeln, wird ein spezialisierter Argumenttyp vorgeschlagen.

PEP Verschiebung

Die weitere Erforschung der in diesem PEP behandelten Konzepte wurde mangels eines aktuellen Vertreters, der an der Förderung der Ziele des PEP interessiert ist und Feedback sammelt und einarbeitet, sowie über ausreichend verfügbare Zeit zur effektiven Umsetzung, zurückgestellt.

Die Auflösung dieses PEP kann auch durch die Auflösung von PEP 426 beeinflusst werden, der die Verwendung eines Vorverarbeitungsschritts zur Generierung einiger Aspekte des C-API-Schnittstellencodes vorschlägt.

Problembeschreibung

Heutzutage behalten Argument-Tupel Referenzen auf die Funktionsargumente, deren Lebensdauer garantiert so lang ist wie die des Argument-Tupels, was mindestens so lang ist wie die Ausführung des Funktionsaufrufs.

In einigen Fällen weist das Parsen eines Arguments neuen Speicher zu, der dann vom Aufrufer freigegeben werden muss. Dies hat zwei Probleme:

  1. Im Fehlerfall kann die Anwendung nicht wissen, welcher Speicher freigegeben werden muss; die meisten Aufrufer wissen nicht einmal, dass sie die Verantwortung für die Freigabe dieses Speichers haben. Beispiele hierfür sind der N-Konverter (Fehler #416288 [1]) und der es#-Konverter (Fehler #501716 [2]).
  2. Selbst bei erfolgreichem Parsen von Argumenten ist es für den Aufrufer immer noch umständlich, für die Freigabe des Speichers verantwortlich zu sein. In einigen Fällen ist dies unnötig ineffizient. Zum Beispiel kopiert der es-Konverter das Konvertierungsergebnis in den Speicher, obwohl bereits ein String-Objekt mit dem richtigen Inhalt vorhanden ist.

Vorgeschlagene Lösung

Ein neuer Typ 'Argument-Tupel' wird eingeführt. Dieser Typ leitet sich von Tupel ab und fügt ein __dict__-Mitglied hinzu (bei tp_dictoffset -4). Instanzen dieses Typs könnten folgende Attribute erhalten:

  • 'failobjects', eine Liste von Objekten, die im Fehlerfall freigegeben werden müssen
  • 'okobjects', eine Liste von Objekten, die freigegeben werden, wenn das Argument-Tupel freigegeben wird

Zur Verwaltung dieses Typs werden folgende Funktionen hinzugefügt und angemessen in ceval.c und getargs.c verwendet:

  • PyArgTuple_New(int);
  • PyArgTuple_AddFailObject(PyObject*, PyObject*);
  • PyArgTuple_AddFailMemory(PyObject*, void*);
  • PyArgTuple_AddOkObject(PyObject*, PyObject*);
  • PyArgTuple_AddOkMemory(PyObject*, void*);
  • PyArgTuple_ClearFailed(PyObject*);

Wenn das Parsen von Argumenten fehlschlägt, werden alle 'failobjects' über Py_DECREF und aller 'failmemory' über PyMem_Free freigegeben. Wenn das Parsen erfolgreich ist, werden die Referenzen auf die 'failobjects' und 'failmemory' fallen gelassen, ohne etwas freizugeben.

Wenn das Argument-Tupel freigegeben wird, werden alle 'okobjects' und 'okmemory' freigegeben.

Wenn diese Funktionen mit einem Objekt eines anderen Typs aufgerufen werden, wird eine Warnung ausgegeben und keine weitere Aktion durchgeführt; die Verwendung der betroffenen Konverter ohne Argument-Tupel wird als veraltet markiert.

Betroffene Konverter

Die folgenden Konverter werden 'failmemory' und 'failobjects' hinzufügen: N, es, et, es#, et# (es sei denn, Speicher wird in den Konverter übergeben)

Neue Konverter

Um die Unicode-Konvertierung zu vereinfachen, werden die e*-Konverter als E*-Konverter dupliziert (Es, Et, Es#, Et#). Die Verwendung der E*-Konverter ist identisch mit der der e*-Konverter, mit der Ausnahme, dass die Anwendung den resultierenden Speicher nicht verwalten muss. Dies wird durch die Registrierung von Ok-Objekten im Argument-Tupel implementiert. Die e*-Konverter werden als veraltet markiert.

Referenzen


Quelle: https://github.com/python/peps/blob/main/peps/pep-0286.rst

Zuletzt geändert: 2025-02-01 08:55:40 GMT