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:
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:
- 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 deres#-Konverter (Fehler #501716 [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
Urheberrecht
Dieses Dokument wurde gemeinfrei erklärt.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0286.rst
Zuletzt geändert: 2025-02-01 08:55:40 GMT