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

Python Enhancement Proposals

PEP 689 – Instabile C-API-Tier

Autor:
Petr Viktorin <encukou at gmail.com>
Discussions-To:
Discourse thread
Status:
Final
Typ:
Standards Track
Benötigt:
523
Erstellt:
22. Apr. 2022
Python-Version:
3.12
Post-History:
27. Apr. 2022, 25. Aug. 2022, 27. Okt. 2022
Resolution:
Discourse-Nachricht

Inhaltsverzeichnis

Wichtig

Diese PEP ist ein historisches Dokument. Die aktuelle, kanonische Dokumentation finden Sie jetzt unter Änderung der Python C-API.

×

Die für Benutzer sichtbare Dokumentation finden Sie unter Instabile C-API.

Siehe PEP 1, um Änderungen vorzuschlagen.

Zusammenfassung

Einige Funktionen und Typen der C-API sind als instabil gekennzeichnet, was bedeutet, dass sie sich in Patch- (Bugfix/Sicherheits-) Versionen nicht ändern, aber zwischen Minor-Versionen (z. B. zwischen 3.11 und 3.12) ohne Deprecation-Warnungen geändert werden können.

Jede C-API mit einem führenden Unterstrich ist als intern gekennzeichnet, was bedeutet, dass sie sich jederzeit ändern oder verschwinden kann, ohne Vorankündigung.

Motivation & Rationale

Unstable C API tier

Die Python C-API ist derzeit in drei Stabilitätsstufen unterteilt.

  • Begrenzte API mit hohen Kompatibilitätserwartungen
  • Öffentliche API, die der Richtlinie zur Abwärtskompatibilität folgt und Deprecation-Warnungen vor Änderungen erfordert.
  • Interne (private) API, die sich jederzeit ändern kann.

Tools, die Zugriff auf CPython-Interna benötigen (z. B. fortgeschrittene Debugger und JIT-Compiler), werden oft für Minor-Series-Releases von CPython erstellt und gehen davon aus, dass sich die intern verwendeten C-API-Interna in Patch-Releases nicht ändern. Um diese Tools zu unterstützen, benötigen wir eine Stufe zwischen der öffentlichen und der privaten C-API mit Garantien für die Stabilität über die gesamte Minor-Series-Version hinweg: die vorgeschlagene instabile Stufe.

Einige Funktionen wie PyCode_New() sind als instabil dokumentiert ("Calling [it] directly can bind you to a precise Python version") und ändern sich oft auch in der Praxis. Die instabile Stufe sollte ihren Status selbst für Leute offensichtlich machen, die die Dokumentation nicht sorgfältig genug lesen, und sie somit schwer versehentlich zu verwenden machen.

Reservierung von führenden Unterstrichen für die private API

Derzeit sind sich die CPython-Entwickler nicht einig über die genaue Bedeutung eines führenden Unterstrichs in API-Namen. Er wird für zwei verschiedene Dinge verwendet:

  • API, die sich zwischen Minor-Versionen ändern kann, wie in der hier vorgeschlagenen instabilen Stufe (z. B. Funktionen, die in PEP 523 eingeführt wurden).
  • API, die privat ist und überhaupt nicht außerhalb von CPython verwendet werden sollte (z. B. weil sie sich ohne Vorankündigung ändern kann oder auf undokumentierten Annahmen beruht, die Nicht-CPython-Code nicht garantieren kann).

Die unklare Bedeutung macht den Unterstrich weniger nützlich, als er sein könnte. Wenn er nur private API markieren würde, könnten CPython-Entwickler unterstrichene Funktionen ändern oder ungenutzte entfernen, ohne zu recherchieren, wie sie außerhalb von CPython dokumentiert oder verwendet werden.

Mit der Einführung einer dedizierten instabilen Stufe können wir die Bedeutung des führenden Unterstrichs klären. Er sollte nur private API markieren.

Kein unnötiges Brechen von Code

Diese PEP legt fest, dass die API der instabilen Stufe ein spezielles Namenspräfix haben soll. Das bedeutet, dass Funktionen (Makros usw.) umbenannt werden müssen. Nach einer Umbenennung sollte der alte Name weiterhin verfügbar sein, bis eine inkompatible Änderung vorgenommen wird (d. h. bis die Aufrufstellen sowieso aktualisiert werden müssen). Mit anderen Worten: Allein die Änderung der Stufe einer Funktion sollte den Code der Benutzer nicht brechen.

Spezifikation

Die C-API wird nach Stabilitätserwartungen in drei „Abschnitte“ unterteilt (intern, öffentlich und begrenzt). Wir werden diese nun Stabilitätsstufen oder kurz Stufen nennen.

Eine instabile Stufe wird hinzugefügt.

APIs (Funktionen, Typen usw.) in dieser Stufe werden mit dem Präfix PyUnstable_ benannt, ohne führenden Unterstrich.

Sie werden in Headern deklariert, die für öffentliche APIs verwendet werden (Include/*.h, anstatt in einem Unterverzeichnis wie Include/unstable/).

Es werden mehrere Regeln für den Umgang mit der instabilen Stufe eingeführt.

  • Instabile API sollte keine abwärtsinkompatiblen Änderungen über Patch-Releases hinweg aufweisen, kann sich aber in Minor-Releases (3.x.0, einschließlich Alpha- und Beta-Releases von 3.x.0) ändern oder entfernt werden. Solche Änderungen müssen dokumentiert und im "What's New"-Dokument erwähnt werden.
  • Abwärtsinkompatible Änderungen an diesen APIs sollten so vorgenommen werden, dass Code, der sie verwendet, zur Kompilierung mit der neuen Version aktualisiert werden muss (z. B. sollten Argumente hinzugefügt/entfernt werden oder eine Funktion umbenannt werden, aber die semantische Bedeutung eines Arguments sollte sich nicht ändern).
  • Instabile API sollte dokumentiert und getestet werden.
  • Um eine API von der öffentlichen Stufe in die instabile Stufe zu verschieben, sollte sie unter dem neuen Namen PyUnstable_* verfügbar gemacht werden.

    Der alte Name sollte deprecated werden (z. B. mit Py_DEPRECATED), aber weiterhin verfügbar bleiben, bis eine inkompatible Änderung an der API vorgenommen wird. Gemäß der Abwärtskompatibilitätsrichtlinie von Python (PEP 387) muss diese Deprecation *mindestens* zwei Releases dauern (ohne SC-Ausnahmen). Sie kann aber auch unbegrenzt dauern – wenn beispielsweise PEP 590s „vorläufige“ _PyObject_Vectorcall heute hinzugefügt würde, würde sie zunächst PyUnstable_Object_Vectorcall heißen und es gäbe keine Pläne, diesen Namen zu entfernen.

    In den folgenden Fällen ist eine inkonsistente Änderung (und damit das Entfernen des deprecaded Namens) ohne SC-Ausnahme zulässig, als ob die Funktion bereits Teil der instabilen Stufe wäre:

    • Jede API, die vor Python 3.12 eingeführt wurde und deren Dokumentation besagt, dass sie weniger stabil als Standard ist.
    • Jede API, die vor Python 3.12 eingeführt wurde und mit einem führenden Unterstrich benannt war.

    Beispiele finden Sie in der initialen instabilen API, die in dieser PEP spezifiziert ist.

  • Um eine interne API in die instabile Stufe zu verschieben, sollte sie unter dem neuen Namen PyUnstable_* verfügbar gemacht werden.

    Wenn der alte Name dokumentiert oder extern weit verbreitet ist, sollte er weiterhin verfügbar bleiben, bis eine inkonsistente Änderung vorgenommen wird (und Aufrufstellen aktualisiert werden müssen). Er sollte beginnen, Deprecation-Warnungen auszugeben (z. B. mit Py_DEPRECATED).

  • Um eine API von der instabilen Stufe in die öffentliche Stufe zu verschieben, sollte sie ohne das Präfix PyUnstable_* verfügbar gemacht werden.

    Der alte Name sollte verfügbar bleiben, bis die API deprecad oder entfernt wird.

  • Das Hinzufügen neuer instabiler API für bestehende Funktionen ist auch nach dem Beta-Feature-Freeze zulässig, bis zum ersten Release Candidate. Ein Konsens auf dem Core Development Discourse ist in der Beta-Phase erforderlich.

Diese Regeln werden im Devguide dokumentiert und die Benutzerdokumentation wird entsprechend aktualisiert.

Referenzdokumente für C-APIs mit dem Namen PyUnstable_* zeigen automatisch Hinweise mit Links zur Dokumentation der instabilen Stufe.

Führender Unterstrich

C-API, die mit einem führenden Unterstrich benannt ist, sowie API, die nur mit Py_BUILD_CORE verfügbar ist, werden als intern betrachtet. Das bedeutet:

  • Sie kann sich ohne Vorankündigung in Minor-Releases (3.x.0, einschließlich Alpha- und Beta-Releases von 3.x.0) ändern oder entfernt werden. API-Änderungen in Patch-Releases oder Release Candidates sollten nur erfolgen, wenn es unbedingt notwendig ist.
  • Sie sollte in Quellcode-Kommentaren oder nur im Devguide dokumentiert werden, nicht in der öffentlichen Dokumentation.
  • API, die vor Python 3.12 eingeführt wurde und dokumentiert oder extern weit verbreitet ist, sollte wie oben beschrieben in die instabile Stufe verschoben werden.

    Dies kann lange nach der Annahme dieser PEP geschehen. Daher sollten die Kernentwickler einige Jahre lang recherchieren, bevor sie unterstrichene APIs ändern, insbesondere wenn sie kein Py_BUILD_CORE benötigen.

Benutzer der C-API werden ermutigt, ihren Code nach den Bezeichnerpräfixen _Py und _PY zu durchsuchen und alle Funde als Probleme zu behandeln, die schließlich behoben werden müssen – entweder durch Umstieg auf eine bestehende Alternative oder durch Eröffnung eines CPython-Issues, um die Bereitstellung öffentlicher API für ihren Anwendungsfall zu beantragen und schließlich darauf umzusteigen.

Initiale instabile API

Die folgende API wird in der initialen Implementierung als Proof of Concept in die instabile Stufe verschoben.

Konstruktoren für Code-Objekte

  • PyUnstable_Code_New() (umbenannt von PyCode_New)
  • PyUnstable_Code_NewWithPosOnlyArgs() (umbenannt von PyCode_NewWithPosOnlyArgs)

Zusatzinformationen für Code (PEP 523)

  • PyUnstable_Eval_RequestCodeExtraIndex() (umbenannt von _PyEval_RequestCodeExtraIndex)
  • PyUnstable_Code_GetExtra() (umbenannt von _PyCode_GetExtra)
  • PyUnstable_Code_SetExtra() (umbenannt von _PyCode_SetExtra)

Weitere werden für Python 3.12 erwartet, ohne dass eine weitere PEP erforderlich ist.

Abwärtskompatibilität

Die Erwartungen an die Abwärtskompatibilität der C-API werden verdeutlicht.

Alle umbenannten APIs werden so lange wie möglich unter den alten Namen verfügbar sein.

Wie man das lehrt

Die Änderungen betreffen fortgeschrittene C-Programmierer, die die aktualisierte Referenzdokumentation, den Devguide und/oder das "What's New"-Dokument konsultieren sollten.

Referenzimplementierung

https://github.com/python/cpython/compare/main…encukou:unstable-tier

Abgelehnte Ideen

Kein spezielles Präfix

In der initialen Version dieser PEP hatten instabile APIs nicht das Präfix PyUnstable. Stattdessen machte die Definition von Py_USING_UNSTABLE_API die API in einer bestimmten Quelldatei verfügbar, was die Anerkennung signalisierte, dass die Datei als Ganzes potenziell für jede Python-Version neu überarbeitet werden muss.

Es wurde jedoch entschieden, dass Instabilität in den einzelnen Namen sichtbar gemacht werden muss.

Unterstrich-Präfix

Es wäre möglich, sowohl private als auch instabile API mit führenden Unterstrichen zu kennzeichnen. Das würde jedoch die Bedeutung des Präfixes _Py verwässern. Die Reservierung des Präfixes nur für interne API macht es trivial, danach zu suchen.

Neues Header-Verzeichnis

Andere API-Stufen haben dedizierte Verzeichnisse für Header (Include/cpython/, Include/internal/).

Da die instabile Stufe eine sehr offensichtliche Namenskonvention verwendet und die Namen immer verfügbar sind, ist ein Verzeichnis wie Include/unstable/ unnötig.

Python API

Es könnte gut sein, eine ähnliche Stufe in der Python-API (nicht C-API) hinzuzufügen, z. B. für types.CodeType. Der Mechanismus dafür müsste jedoch anders sein. Dies liegt außerhalb des Rahmens der PEP.


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

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