PEP 689: Updates from discussion & initial implementation (GH-2901)

The prefix is very visible, so:
- No opt-in macro
- No new Include/ subdirectory

Removed frame evaluation API: I haven't found a way to use it,
so I can't test it.

Mention that unstable API should be documented and tested.

Add link to rough reference implementation.
This commit is contained in:
Petr Viktorin 2022-11-28 15:27:37 +01:00 committed by GitHub
parent 9d19f3952f
commit 580f8e3c70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 35 additions and 43 deletions

View File

@ -70,19 +70,20 @@ If it only marked *private* API, CPython developers could change underscored
functions, or remove unused ones, without researching how they're functions, or remove unused ones, without researching how they're
documented or used outside CPython. documented or used outside CPython.
With the introduction of an unstable tier, we can clarify the meaning With the introduction of a dedicated unstable tier, we can clarify the meaning
of the leading underscore, eventually making it OK to skip that research. of the leading underscore. It should mark private API only.
Not breaking code unnecessarily Not breaking code unnecessarily
------------------------------- -------------------------------
This PEP specifies that API should be renamed so that the This PEP specifies that API in the unstable tier should have a special name
public/unstable/internal stability tier is expressed in function names. prefix. This means functions (macros, etc.) will need to be renamed.
Whenever this happens, the old name should continue to be available until After a rename, the old name should continue to be available until
an incompatible change is made (i.e. until call sites need to be updated an incompatible change is made (i.e. until call sites need to be updated
anyway). anyway).
In other words, just changing tiers shouldn't break users' code. In other words, just changing the tier of a function shouldn't break users'
code.
Specification Specification
@ -97,14 +98,8 @@ An *Unstable tier* will be added.
APIs (functions, types, etc.) in this tier will named with the ``PyUnstable_`` APIs (functions, types, etc.) in this tier will named with the ``PyUnstable_``
prefix, with no leading underscore. prefix, with no leading underscore.
Internally, they will be declared in headers in a new directory, They will be declared in headers used for public API (``Include/*.h``,
``Include/unstable/``. rather than in a subdirectory like ``Include/ustable/``).
Users should include ``Python.h`` rather than using these headers directly.
These APIs will only be declared when the
``Py_USING_UNSTABLE_API`` macro is defined.
CPython will define the macro for building CPython itself
(``Py_BUILD_CORE``).
Several rules for dealing with the unstable tier will be introduced: Several rules for dealing with the unstable tier will be introduced:
@ -118,9 +113,10 @@ Several rules for dealing with the unstable tier will be introduced:
the new version (e.g. arguments should be added/removed, or a function should the new version (e.g. arguments should be added/removed, or a function should
be renamed, but the semantic meaning of an argument should not change). be renamed, but the semantic meaning of an argument should not change).
- Unstable API should be documented and tested.
- To move an API from the public tier to the unstable tier, it should be - To move an API from the public tier to the unstable tier, it should be
exposed under the new ``PyUnstable_*`` name and the definition should be exposed under the new ``PyUnstable_*`` name.
guarded with ``Py_USING_UNSTABLE_API``.
The old name should be deprecated (e.g. with ``Py_DEPRECATED``), but The old name should be deprecated (e.g. with ``Py_DEPRECATED``), but
continue to be available until an incompatible change is made to the API. continue to be available until an incompatible change is made to the API.
@ -129,7 +125,7 @@ Several rules for dealing with the unstable tier will be introduced:
But it can also last indefinitely -- for example, if :pep:`590`'s But it can also last indefinitely -- for example, if :pep:`590`'s
:pep:`“provisional” <590#finalizing-the-api>` :pep:`“provisional” <590#finalizing-the-api>`
``_PyObject_Vectorcall`` was added today, it would be initially named ``_PyObject_Vectorcall`` was added today, it would be initially named
``PyUnstable_Object_Vectorcall`` and there would be no plan to ever remove ``PyUnstable_Object_Vectorcall`` and there would be no plan to remove
this name. this name.
In the following cases, an incompatible change (and thus removing the In the following cases, an incompatible change (and thus removing the
@ -141,29 +137,26 @@ Several rules for dealing with the unstable tier will be introduced:
- Any API introduced before Python 3.12 that was named with a leading - Any API introduced before Python 3.12 that was named with a leading
underscore. underscore.
For examples, see the :ref:`initial unstaple API <pep689-initial-list>` For examples, see the :ref:`initial unstable API <pep689-initial-list>`
specified in this PEP. specified in this PEP.
- To move an *internal* API to the unstable tier, it should be - To move an *internal* API to the unstable tier, it should be
exposed under the new ``PyUnstable_*`` name and the definition should be exposed under the new ``PyUnstable_*`` name.
guarded with ``Py_USING_UNSTABLE_API``.
If the old name is documented, or widely used externally, If the old name is documented, or widely used externally,
it should continue to be available until an it should continue to be available until an
incompatible change is made (and call sites need to be updated). incompatible change is made (and call sites need to be updated).
It should start raising deprecation warnings. It should start raising deprecation warnings (e.g. using ``Py_DEPRECATED``).
- To move an API from the unstable tier to the public tier, it should be - To move an API from the unstable tier to the public tier, it should be
exposed without the ``PyUnstable_*`` prefix. exposed without the ``PyUnstable_*`` prefix.
The old name should remain available, possibly without requiring The old name should remain available until the first incompatible change
``Py_USING_UNSTABLE_API``, until the first incompatible change is made is made or the API is removed.
otr the API is removed.
- Adding new unstable API *for existing features* is allowed even after - Adding new unstable API *for existing features* is allowed even after
the feature freeze, up until the first Release Candidate. Beta feature freeze, up until the first Release Candidate.
Consensus on Core Development Discourse or ``capi-sig`` is needed in the Consensus on Core Development Discourse or is needed in the Beta period.
Beta period.
These rules will be documented in the `devguide <https://devguide.python.org/developer-workflow/c-api/index.html>`__, These rules will be documented in the `devguide <https://devguide.python.org/developer-workflow/c-api/index.html>`__,
and `user documentation <https://docs.python.org/3/c-api/stable.html>`__ and `user documentation <https://docs.python.org/3/c-api/stable.html>`__
@ -215,19 +208,13 @@ Code object constructors:
- ``PyUnstable_Code_New()`` (renamed from ``PyCode_New``) - ``PyUnstable_Code_New()`` (renamed from ``PyCode_New``)
- ``PyUnstable_Code_NewWithPosOnlyArgs()`` (renamed from ``PyCode_NewWithPosOnlyArgs``) - ``PyUnstable_Code_NewWithPosOnlyArgs()`` (renamed from ``PyCode_NewWithPosOnlyArgs``)
Frame evaluation API (:pep:`523`): Code extra information (:pep:`523`):
- ``PyUnstable_FrameEvalFunction`` (renamed from ``_PyFrameEvalFunction``)
- ``PyUnstable_InterpreterState_GetEvalFrameFunc()`` (renamed from ``_PyInterpreterState_GetEvalFrameFunc``)
- ``PyUnstable_InterpreterState_SetEvalFrameFunc()`` (renamed from ``_PyInterpreterState_SetEvalFrameFunc``)
- ``PyUnstable_Eval_RequestCodeExtraIndex()`` (renamed from ``_PyEval_RequestCodeExtraIndex``) - ``PyUnstable_Eval_RequestCodeExtraIndex()`` (renamed from ``_PyEval_RequestCodeExtraIndex``)
- ``PyUnstable_Code_GetExtra()`` (renamed from ``_PyCode_GetExtra``) - ``PyUnstable_Code_GetExtra()`` (renamed from ``_PyCode_GetExtra``)
- ``PyUnstable_Code_SetExtra()`` (renamed from ``_PyCode_SetExtra``) - ``PyUnstable_Code_SetExtra()`` (renamed from ``_PyCode_SetExtra``)
- ``PyUnstable_InterpreterFrame`` (typedef for ``_PyInterpreterFrame``, as an opaque struct)
- ``PyUnstable_Frame_GetFrameObject`` (renamed from ``_PyFrame_GetFrameObject``) More are expected in Python 3.12, without the need for another PEP.
- ``PyUnstable_EvalFrameDefault``
(new function that calls ``_PyEval_EvalFrameDefault``, but takes
``PyFrameObject`` rather than ``_PyInterpreterFrame``)
Backwards Compatibility Backwards Compatibility
@ -248,13 +235,7 @@ updated reference documentation, devguide and/or What's New document.
Reference Implementation Reference Implementation
======================== ========================
https://github.com/python/cpython/issues/91744 https://github.com/python/cpython/compare/main...encukou:unstable-tier
Open Issues
===========
With the ``PyUnstable_`` prefix, is the opt-in macro necessary?
Rejected Ideas Rejected Ideas
@ -281,6 +262,17 @@ However, that would dilute the meaning of ``_Py`` prefix.
Reserving the prefix for internal API only makes it trivial to search for. Reserving the prefix for internal API only makes it trivial to search for.
New header directory
--------------------
Other API tiers have dedicated directories for headers
(``Include/cpython/``, ``Include/internal/``).
Since the unstable tier uses a very obvious naming convention
and the names are always available,
a directory like ``Include/unstable/`` is unnecessary.
Python API Python API
---------- ----------