554 lines
36 KiB
HTML
554 lines
36 KiB
HTML
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="color-scheme" content="light dark">
|
||
<title>PEP 652 – Maintaining the Stable ABI | peps.python.org</title>
|
||
<link rel="shortcut icon" href="../_static/py.png">
|
||
<link rel="canonical" href="https://peps.python.org/pep-0652/">
|
||
<link rel="stylesheet" href="../_static/style.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
|
||
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
|
||
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
|
||
<meta property="og:title" content='PEP 652 – Maintaining the Stable ABI | peps.python.org'>
|
||
<meta property="og:description" content="CPython’s Limited C-API and Stable ABI, introduced in PEP 384, will be formalized in a single definitive file, tested, and documented.">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:url" content="https://peps.python.org/pep-0652/">
|
||
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
|
||
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
|
||
<meta property="og:image:alt" content="Python PEPs">
|
||
<meta property="og:image:width" content="200">
|
||
<meta property="og:image:height" content="200">
|
||
<meta name="description" content="CPython’s Limited C-API and Stable ABI, introduced in PEP 384, will be formalized in a single definitive file, tested, and documented.">
|
||
<meta name="theme-color" content="#3776ab">
|
||
</head>
|
||
<body>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Following system colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="9"></circle>
|
||
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected dark colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected light colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="5"></circle>
|
||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||
</svg>
|
||
</symbol>
|
||
</svg>
|
||
<script>
|
||
|
||
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
|
||
</script>
|
||
<section id="pep-page-section">
|
||
<header>
|
||
<h1>Python Enhancement Proposals</h1>
|
||
<ul class="breadcrumbs">
|
||
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> » </li>
|
||
<li><a href="../pep-0000/">PEP Index</a> » </li>
|
||
<li>PEP 652</li>
|
||
</ul>
|
||
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
|
||
</button>
|
||
</header>
|
||
<article>
|
||
<section id="pep-content">
|
||
<h1 class="page-title">PEP 652 – Maintaining the Stable ABI</h1>
|
||
<dl class="rfc2822 field-list simple">
|
||
<dt class="field-odd">Author<span class="colon">:</span></dt>
|
||
<dd class="field-odd">Petr Viktorin <encukou at gmail.com></dd>
|
||
<dt class="field-even">Discussions-To<span class="colon">:</span></dt>
|
||
<dd class="field-even"><a class="reference external" href="https://discuss.python.org/t/pre-pep-maintaining-the-stable-abi/6986/">Discourse thread</a></dd>
|
||
<dt class="field-odd">Status<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
|
||
<dt class="field-even">Type<span class="colon">:</span></dt>
|
||
<dd class="field-even"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
|
||
<dt class="field-odd">Created<span class="colon">:</span></dt>
|
||
<dd class="field-odd">09-Feb-2021</dd>
|
||
<dt class="field-even">Python-Version<span class="colon">:</span></dt>
|
||
<dd class="field-even">3.10</dd>
|
||
<dt class="field-odd">Resolution<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><a class="reference external" href="https://mail.python.org/archives/list/python-dev@python.org/message/IN4XMFLQJ6D6V67EXU27GV3QWSEHHNNH/">Python-Dev message</a></dd>
|
||
</dl>
|
||
<hr class="docutils" />
|
||
<section id="contents">
|
||
<details><summary>Table of Contents</summary><ul class="simple">
|
||
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
||
<li><a class="reference internal" href="#motivation">Motivation</a></li>
|
||
<li><a class="reference internal" href="#rationale">Rationale</a></li>
|
||
<li><a class="reference internal" href="#stable-abi-vs-limited-api">Stable ABI vs. Limited API</a><ul>
|
||
<li><a class="reference internal" href="#stable-abi">Stable ABI</a></li>
|
||
<li><a class="reference internal" href="#limited-api">Limited API</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#specification">Specification</a><ul>
|
||
<li><a class="reference internal" href="#stable-abi-manifest">Stable ABI Manifest</a></li>
|
||
<li><a class="reference internal" href="#contents-of-the-stable-abi">Contents of the Stable ABI</a></li>
|
||
<li><a class="reference internal" href="#documenting-the-limited-api">Documenting the Limited API</a></li>
|
||
<li><a class="reference internal" href="#testing-the-stable-abi">Testing the Stable ABI</a></li>
|
||
<li><a class="reference internal" href="#changing-the-limited-api">Changing the Limited API</a></li>
|
||
<li><a class="reference internal" href="#advice-for-extenders-and-embedders">Advice for Extenders and Embedders</a></li>
|
||
<li><a class="reference internal" href="#note-for-redistributors-of-python">Note for Redistributors of Python</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li>
|
||
<li><a class="reference internal" href="#security-implications">Security Implications</a></li>
|
||
<li><a class="reference internal" href="#how-to-teach-this">How to Teach This</a></li>
|
||
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
|
||
<li><a class="reference internal" href="#ideas-for-the-future">Ideas for the Future</a><ul>
|
||
<li><a class="reference internal" href="#defining-a-process-for-deprecations-removals">Defining a process for deprecations/removals</a></li>
|
||
<li><a class="reference internal" href="#c-syntax-for-the-abi-manifest">C syntax for the ABI manifest</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#open-issues">Open Issues</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
</details></section>
|
||
<div class="pep-banner canonical-doc sticky-banner admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>This PEP is a historical document. The up-to-date, canonical documentation can now be found at <a class="reference external" href="https://docs.python.org/3/c-api/stable.html#stable" title="(in Python v3.13)"><span>C API Stability</span></a> (user docs) and
|
||
<a class="reference external" href="https://devguide.python.org/developer-workflow/c-api/#c-api" title="(in Python Developer's Guide)"><span>Changing Python’s C API</span></a> (development docs).</p>
|
||
<p class="close-button">×</p>
|
||
<p>See <a class="pep reference internal" href="../pep-0001/" title="PEP 1 – PEP Purpose and Guidelines">PEP 1</a> for how to propose changes.</p>
|
||
</div>
|
||
<section id="abstract">
|
||
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
|
||
<p>CPython’s Limited C-API and Stable ABI, introduced in <a class="pep reference internal" href="../pep-0384/" title="PEP 384 – Defining a Stable ABI">PEP 384</a>,
|
||
will be formalized in a single definitive file, tested, and documented.</p>
|
||
</section>
|
||
<section id="motivation">
|
||
<h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2>
|
||
<p><a class="pep reference internal" href="../pep-0384/" title="PEP 384 – Defining a Stable ABI">PEP 384</a> defined a Limited API and Stable ABI, which allow extenders and
|
||
embedders of CPython to compile extension modules that are binary-compatible
|
||
with any subsequent version of 3.x.
|
||
In theory, this brings several advantages:</p>
|
||
<ul class="simple">
|
||
<li>A module can be built only once per platform and support multiple versions
|
||
of Python, reducing time, power and maintainer attention needed for builds
|
||
(in exchange for potentially worse performance).</li>
|
||
<li>Binary wheels using the Stable ABI work with new versions of CPython
|
||
throughout the pre-release period, and can be tested in environments where
|
||
building from source is not practical.</li>
|
||
<li>As a welcome side effect of the Limited API’s hiding of implementation
|
||
details, this API is becoming a viable target for alternate Python
|
||
implementations that would be incompatible with the full C API.</li>
|
||
</ul>
|
||
<p>However, in hindsight, <a class="pep reference internal" href="../pep-0384/" title="PEP 384 – Defining a Stable ABI">PEP 384</a> and its implementation has several issues:</p>
|
||
<ul class="simple">
|
||
<li>It is ill-defined. According to <a class="pep reference internal" href="../pep-0384/" title="PEP 384 – Defining a Stable ABI">PEP 384</a>, functions are <em>opt-out</em>:
|
||
all functions not specially marked are part of the Stable ABI.
|
||
In practice, for Windows there’s a list that’s <em>opt-in</em>.
|
||
For users there is a <code class="docutils literal notranslate"><span class="pre">#define</span></code> that should make only the Stable ABI
|
||
available, but there is no process that ensures it is kept up-to date.
|
||
Neither is there a process for updating the documentation.</li>
|
||
<li>Until recently, the Stable ABI was not tested at all. It tends to break.
|
||
For example, changing a function to a macro can break the Stable ABI as the
|
||
function symbol is removed.</li>
|
||
<li>There is no way to deprecate parts of the Limited API.</li>
|
||
<li>It is incomplete. Some operations are not available in the Stable ABI,
|
||
with little reason except “we forgot”.
|
||
(This last point is one the PEP will not help with, however.)</li>
|
||
</ul>
|
||
<p>This PEP defines the Limited API more clearly and introducess process
|
||
designed to make the Stable ABI and Limited API more useful and robust.</p>
|
||
</section>
|
||
<section id="rationale">
|
||
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
|
||
<p>This PEP contains a lot of clarifications and definitions, but just one big
|
||
technical change: the Stable ABI will be explicitly listed in
|
||
a human-maintained “manifest” file.</p>
|
||
<p>There have been efforts to collect such lists automatically, e.g. by scanning
|
||
the symbols exported from Python.
|
||
Such automation might seem easier to maintain than a handcrafted file,
|
||
but has major issues: for example, the set exported symbols has
|
||
platform-specific variations.
|
||
Also, the cost of updating an explicit manifest is small compared
|
||
to the overall work that should go into changing API that will need to
|
||
be supported forever (or until Python 3 reaches end of life, if that
|
||
comes sooner).</p>
|
||
<p>This PEP proposes automatically generating things <em>from</em> the manifest:
|
||
initially documentation and DLL contents, with later possibilities
|
||
for also automating tests.</p>
|
||
</section>
|
||
<section id="stable-abi-vs-limited-api">
|
||
<h2><a class="toc-backref" href="#stable-abi-vs-limited-api" role="doc-backlink">Stable ABI vs. Limited API</a></h2>
|
||
<p><a class="pep reference internal" href="../pep-0384/" title="PEP 384 – Defining a Stable ABI">PEP 384</a> and this document deal with the <em>Limited API</em> and the <em>Stable ABI</em>,
|
||
two related but distinct concepts. In short:</p>
|
||
<ul class="simple">
|
||
<li>The <em>Stable ABI</em> is a promise that certain extensions compiled with
|
||
CPython 3.x will be binary compatible with all subsequent versions
|
||
of CPython 3.x.</li>
|
||
<li>The <em>Limited API</em> is a subset of CPython’s C API that produces such extensions.</li>
|
||
</ul>
|
||
<p>This section clarifies these terms and defines some of their semantics
|
||
(either pre-existing or newly proposed here).</p>
|
||
<p>The word “Extensions” is used as a shorthand for all code that uses the
|
||
Python API, e.g. extension modules or software that embeds Python.</p>
|
||
<section id="stable-abi">
|
||
<h3><a class="toc-backref" href="#stable-abi" role="doc-backlink">Stable ABI</a></h3>
|
||
<p>The CPython <em>Stable ABI</em> is a promise that extensions built against
|
||
a specific Stable ABI version will be compatible with any newer
|
||
interpreter of the same major version.</p>
|
||
<p>The Stable ABI does not define a complete binary interface:
|
||
important details like the layout of structures in memory or function
|
||
calling conventions are determined by the platform and the compiler and
|
||
its settings.
|
||
The Stable ABI promise only applies if these lower-details are also stable.</p>
|
||
<p>For example, an extension built with the CPython 3.10 Stable ABI will be usable
|
||
with CPython 3.11, 3.12, etc.
|
||
It will not necessarily be compatible with CPython 4.0, nor with CPython 3.10
|
||
on a different platform.</p>
|
||
<p>The Stable ABI is not generally forward-compatible: an extension built and
|
||
tested with CPython 3.10 will not generally be compatible with CPython 3.9.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>For example, starting in Python 3.10, the <code class="docutils literal notranslate"><span class="pre">Py_tp_doc</span></code> slot may be set to
|
||
<code class="docutils literal notranslate"><span class="pre">NULL</span></code>, while in older versions, a <code class="docutils literal notranslate"><span class="pre">NULL</span></code> value will likely crash the
|
||
interpreter.</p>
|
||
</div>
|
||
<p>The Stable ABI trades performance for its stability.
|
||
For example, extensions built for a specific CPython version will automatically
|
||
use faster macros instead of functions in the Stable ABI.</p>
|
||
<p>Future Python versions may deprecate some members of the Stable ABI.
|
||
Deprecated members will still work, but may suffer from issues like reduced
|
||
performance or, in the most extreme cases, memory/resource leaks.</p>
|
||
</section>
|
||
<section id="limited-api">
|
||
<h3><a class="toc-backref" href="#limited-api" role="doc-backlink">Limited API</a></h3>
|
||
<p>The Stable ABI promise holds for extensions compiled from code that restricts
|
||
itself to the <em>Limited API</em> (application programming interface).
|
||
The Limited API is a subset of CPython’s C API.</p>
|
||
<p>Extensions that target the Limited API should define the preprocessor macro
|
||
<code class="docutils literal notranslate"><span class="pre">Py_LIMITED_API</span></code> to either <code class="docutils literal notranslate"><span class="pre">3</span></code> or the current <code class="docutils literal notranslate"><span class="pre">PYTHON_API_VERSION</span></code>.
|
||
This will enable Stable ABI versions of several functions and limit definitions
|
||
to the Limited API.
|
||
(However, note that the macro is not perfect: due to technical issues or
|
||
oversights, some non-limited API might be exposed even with it defined.)</p>
|
||
<p>The Limited API is not guaranteed to be <em>stable</em>.
|
||
In the future, parts of the Limited API may be deprecated.
|
||
They may even be removed, as long as the <em>Stable ABI</em> is kept
|
||
stable and Python’s general backwards compatibility policy, <a class="pep reference internal" href="../pep-0387/" title="PEP 387 – Backwards Compatibility Policy">PEP 387</a>,
|
||
is followed.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>For example, a function declaration might be removed from public header
|
||
files but kept in the library.
|
||
This is currently a possibility for the future; this PEP does not to propose
|
||
a concrete process for deprecations and removals.</p>
|
||
</div>
|
||
<p>The goal for the Limited API is to cover everything needed to interact
|
||
with the interpreter.
|
||
The main reason to not include a public API in the Limited subset
|
||
should be that it needs implementation details that change between CPython
|
||
versions (like struct memory layouts) – usually for performance reasons.</p>
|
||
<p>The Limited API is not limited to CPython. Other implementations are
|
||
encouraged to implement it and help drive its design.</p>
|
||
</section>
|
||
</section>
|
||
<section id="specification">
|
||
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
|
||
<p>To make the Stable ABI more useful and robust, the following changes
|
||
are proposed.</p>
|
||
<section id="stable-abi-manifest">
|
||
<h3><a class="toc-backref" href="#stable-abi-manifest" role="doc-backlink">Stable ABI Manifest</a></h3>
|
||
<p>All members of the Stable ABI – functions, typedefs, structs, data, macros,
|
||
and constants – will be explicitly listed in a single “manifest” file,
|
||
<code class="docutils literal notranslate"><span class="pre">Misc/stable_abi.txt</span></code>.</p>
|
||
<p>For structs, any fields that users of the Stable ABI are allowed to access
|
||
will be listed explicitly.</p>
|
||
<p>The manifest will also serve as the definitive list of the Limited API.
|
||
Members that are not part of the Limited API, but are part of the Stable ABI
|
||
(e.g. <code class="docutils literal notranslate"><span class="pre">PyObject.ob_type</span></code>, which is accessible by the <code class="docutils literal notranslate"><span class="pre">Py_TYPE</span></code> macro),
|
||
will be annotated as such.</p>
|
||
<p>For items that are only available on some systems, the manifest will record the
|
||
feature macro that determines their presence (such as <code class="docutils literal notranslate"><span class="pre">MS_WINDOWS</span></code> or
|
||
<code class="docutils literal notranslate"><span class="pre">HAVE_FORK</span></code>).
|
||
To make the implementation (and usage from non-C languages) easier,
|
||
all such macros will be simple names.
|
||
If a future item needs a “negative” macro or complex expression (such as a
|
||
hypothetical <code class="docutils literal notranslate"><span class="pre">#ifndef</span> <span class="pre">MACOSX</span></code> or <code class="docutils literal notranslate"><span class="pre">#if</span> <span class="pre">defined(POSIX)</span> <span class="pre">&&</span> <span class="pre">!defined(LINUX)</span></code>),
|
||
a new feature macro will be derived.</p>
|
||
<p>The format of the manifest will be subject to change whenever needed.
|
||
It should be consumed only by scripts in the CPython repository.
|
||
If a stable list is needed, a script can be added to generate it.</p>
|
||
<p>The following will be generated from the ABI manifest:</p>
|
||
<ul class="simple">
|
||
<li>Source for the Windows shared library, <code class="docutils literal notranslate"><span class="pre">PC/python3dll.c</span></code>.</li>
|
||
<li>Input for documentation (see below).</li>
|
||
<li>Test case that checks the runtime availability of symbols (see below).</li>
|
||
</ul>
|
||
<p>The following will be checked against the Stable ABI manifest as part of
|
||
continuous integration:</p>
|
||
<ul class="simple">
|
||
<li>The reference count summary, <code class="docutils literal notranslate"><span class="pre">Doc/data/refcounts.txt</span></code>, includes all
|
||
function in the Stable ABI (among others).</li>
|
||
<li>The functions/structs declared and constants/macros defined
|
||
when <code class="docutils literal notranslate"><span class="pre">Python.h</span></code> is included with <code class="docutils literal notranslate"><span class="pre">Py_LIMITED_API</span></code> set.
|
||
(Initially Linux only; checks on other systems may be added in the future.)</li>
|
||
</ul>
|
||
<p>After the initial implementation, details such as function arguments will be
|
||
added and the manifest will be checked for internal consistency (e.g. all
|
||
types used in function signatures are part of the API).</p>
|
||
</section>
|
||
<section id="contents-of-the-stable-abi">
|
||
<h3><a class="toc-backref" href="#contents-of-the-stable-abi" role="doc-backlink">Contents of the Stable ABI</a></h3>
|
||
<p>The initial Stable ABI manifest will include:</p>
|
||
<ul class="simple">
|
||
<li>The Stable ABI specified in <a class="pep reference internal" href="../pep-0384/" title="PEP 384 – Defining a Stable ABI">PEP 384</a>.</li>
|
||
<li>Everything listed in <code class="docutils literal notranslate"><span class="pre">PC/python3dll.c</span></code>.</li>
|
||
<li>All structs (struct typedefs) which these functions return or take as
|
||
arguments. (Fields of such structs will not necessarily be added.)</li>
|
||
<li>New type slots, such as <code class="docutils literal notranslate"><span class="pre">Py_am_aiter</span></code>.</li>
|
||
<li>The type flags <code class="docutils literal notranslate"><span class="pre">Py_TPFLAGS_DEFAULT</span></code>, <code class="docutils literal notranslate"><span class="pre">Py_TPFLAGS_BASETYPE</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">Py_TPFLAGS_HAVE_GC</span></code>, <code class="docutils literal notranslate"><span class="pre">Py_TPFLAGS_METHOD_DESCRIPTOR</span></code>.</li>
|
||
<li>The calling conventions <code class="docutils literal notranslate"><span class="pre">METH_*</span></code> (except deprecated ones).</li>
|
||
<li>All API needed by macros is the Stable ABI (annotated as not being part of
|
||
the Limited API).</li>
|
||
</ul>
|
||
<p>Items that are no longer in CPython when this PEP is accepted will be removed
|
||
from the list.</p>
|
||
<p>Additional items may be added to the initial manifest according to
|
||
the checklist below.</p>
|
||
</section>
|
||
<section id="documenting-the-limited-api">
|
||
<h3><a class="toc-backref" href="#documenting-the-limited-api" role="doc-backlink">Documenting the Limited API</a></h3>
|
||
<p>Notes saying “Part of the Limited API” will be added to Python’s documentation
|
||
automatically, in a way similar to the notes on functions that return borrowed
|
||
references.</p>
|
||
<p>A complete list of all members of the Limited API will also be added to
|
||
the documentation.</p>
|
||
</section>
|
||
<section id="testing-the-stable-abi">
|
||
<h3><a class="toc-backref" href="#testing-the-stable-abi" role="doc-backlink">Testing the Stable ABI</a></h3>
|
||
<p>An automatically generated test module will be added to ensure that all symbols
|
||
included in the Stable ABI are available at compile time.</p>
|
||
</section>
|
||
<section id="changing-the-limited-api">
|
||
<h3><a class="toc-backref" href="#changing-the-limited-api" role="doc-backlink">Changing the Limited API</a></h3>
|
||
<p>A checklist for changing the Limited API, including adding new items to it
|
||
and removing existing ones, will be added to the <a class="reference external" href="https://devguide.python.org/">Devguide</a>.
|
||
The checklist will 1) mention best practices and common pitfalls in Python
|
||
C API design and 2) guide the developer around the files that need changing and
|
||
scripts that need running when the Limited API is changed.</p>
|
||
<p>Below is the initial proposal for the checklist.
|
||
(After the PEP is accepted, see the Devguide for the current version.)</p>
|
||
<p>Note that the checklist applies to new changes; several items
|
||
in the <em>existing</em> Limited API are grandfathered and couldn’t be added today.</p>
|
||
<p>Design considerations:</p>
|
||
<ul>
|
||
<li>Make sure the change does not break the Stable ABI of any version of Python
|
||
since 3.5.</li>
|
||
<li>Make sure no exposed names are private (i.e. begin with an underscore).</li>
|
||
<li>Make sure the new API is well documented.</li>
|
||
<li>Make sure the types of all parameters and return values of the added
|
||
function(s) and all fields of the added struct(s) are be part of the
|
||
Limited API (or standard C).</li>
|
||
<li>Make sure the new API and its intended use follows standard C, not just
|
||
features of currently supported platforms.
|
||
Specifically, follow the C dialect specified in <a class="pep reference internal" href="../pep-0007/" title="PEP 7 – Style Guide for C Code">PEP 7</a>.<ul class="simple">
|
||
<li>Do not cast a function pointer to <code class="docutils literal notranslate"><span class="pre">void*</span></code> (a data pointer) or vice versa.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Make sure the new API follows reference counting conventions. (Following them
|
||
makes the API easier to reason about, and easier use in other Python
|
||
implementations.)<ul class="simple">
|
||
<li>Do not return borrowed references from functions.</li>
|
||
<li>Do not steal references to function arguments.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Make sure the ownership rules and lifetimes of all applicable struct fields,
|
||
arguments and return values are well defined.</li>
|
||
<li>Think about ease of use for the user. (In C, ease of use itself is not very
|
||
important; what <em>is</em> useful is reducing boilerplate code needed to use the
|
||
API. Bugs like to hide in boiler plates.)<ul class="simple">
|
||
<li>If a function will be often called with specific value for an argument,
|
||
consider making it default (used when <code class="docutils literal notranslate"><span class="pre">NULL</span></code> is passed in).</li>
|
||
</ul>
|
||
</li>
|
||
<li>Think about future extensions: for example, if it’s possible that future
|
||
Python versions will need to add a new field to your struct,
|
||
how will that be done?</li>
|
||
<li>Make as few assumptions as possible about details that might change in
|
||
future CPython versions or differ across C API implementations:<blockquote>
|
||
<div><ul class="simple">
|
||
<li>The GIL</li>
|
||
<li>Garbage collection</li>
|
||
<li>Memory layout of PyObject, lists/tuples and other structures</li>
|
||
</ul>
|
||
</div></blockquote>
|
||
</li>
|
||
</ul>
|
||
<p>If following these guidelines would hurt performance, add a fast function
|
||
(or macro) to the non-limited API and a stable equivalent to the Limited API.</p>
|
||
<p>If anything is unclear, or you have a good reason to break the guidelines,
|
||
consider discussing the change at the <a class="reference external" href="https://mail.python.org/mailman3/lists/capi-sig.python.org/">capi-sig</a> mailing list.</p>
|
||
<p>Procedure:</p>
|
||
<ul class="simple">
|
||
<li>Move the declaration to a header file directly under <code class="docutils literal notranslate"><span class="pre">Include/</span></code>, into a
|
||
<code class="docutils literal notranslate"><span class="pre">#if</span> <span class="pre">!defined(Py_LIMITED_API)</span> <span class="pre">||</span> <span class="pre">Py_LIMITED_API+0</span> <span class="pre">>=</span> <span class="pre">0x03yy0000</span></code> block
|
||
(with the <code class="docutils literal notranslate"><span class="pre">yy</span></code> corresponding to the target CPython version).</li>
|
||
<li>Make an entry in the Stable ABI manifest, <code class="docutils literal notranslate"><span class="pre">Misc/stable_abi.txt</span></code>.</li>
|
||
<li>Regenerate the autogenerated files using <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">regen-all</span></code>.
|
||
(or the alternative for non-<code class="docutils literal notranslate"><span class="pre">make</span></code> platforms)</li>
|
||
<li>Build Python and run checks using <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">check-abi</span></code>.
|
||
(or the alternative for non-<code class="docutils literal notranslate"><span class="pre">make</span></code> platforms)</li>
|
||
</ul>
|
||
</section>
|
||
<section id="advice-for-extenders-and-embedders">
|
||
<h3><a class="toc-backref" href="#advice-for-extenders-and-embedders" role="doc-backlink">Advice for Extenders and Embedders</a></h3>
|
||
<p>The following notes will be added to documentation, along with better
|
||
information regarding this topic and what guarantees do we offer:</p>
|
||
<p>Extension authors should test with all Python versions they support,
|
||
and preferably build with the lowest such version.</p>
|
||
<p>Compiling with <code class="docutils literal notranslate"><span class="pre">Py_LIMITED_API</span></code> defined is <em>not</em> a guarantee that your code
|
||
conforms to the Limited API or the Stable ABI.
|
||
<code class="docutils literal notranslate"><span class="pre">Py_LIMITED_API</span></code> only covers definitions, but an API also includes other
|
||
issues, such as expected semantics.</p>
|
||
<p>Examples of issues that <code class="docutils literal notranslate"><span class="pre">Py_LIMITED_API</span></code> does not guard against are:</p>
|
||
<ul class="simple">
|
||
<li>Calling a function with invalid arguments</li>
|
||
<li>A function that started accepting <code class="docutils literal notranslate"><span class="pre">NULL</span></code> values for an argument
|
||
in Python 3.9 will fail if <code class="docutils literal notranslate"><span class="pre">NULL</span></code> is passed to it under Python 3.8.
|
||
Only testing with 3.8 (or lower versions) will uncover this issue.</li>
|
||
<li>Some structs include a few fields that are part of the Stable ABI and other
|
||
fields that aren’t.
|
||
<code class="docutils literal notranslate"><span class="pre">Py_LIMITED_API</span></code> does not filter out such “private” fields.</li>
|
||
<li>Code that uses something that is not documented as part of the Stable ABI,
|
||
but exposed even with <code class="docutils literal notranslate"><span class="pre">Py_LIMITED_API</span></code> defined, may break in the future.
|
||
Despite the team’s best efforts, such issues may happen.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="note-for-redistributors-of-python">
|
||
<h3><a class="toc-backref" href="#note-for-redistributors-of-python" role="doc-backlink">Note for Redistributors of Python</a></h3>
|
||
<p>The Stable ABI promise relies on stable underlying ABI details, such as the
|
||
layout of structures in memory and function calling conventions, which
|
||
are affected by the compiler and its settings.
|
||
For the promise to hold, these details must not change between CPython 3.x
|
||
releases on a particular platform.</p>
|
||
</section>
|
||
</section>
|
||
<section id="backwards-compatibility">
|
||
<h2><a class="toc-backref" href="#backwards-compatibility" role="doc-backlink">Backwards Compatibility</a></h2>
|
||
<p>Backwards compatibility is one honking great idea!</p>
|
||
<p>This PEP aims at full compatibility with the existing Stable ABI and Limited
|
||
API, but defines them terms more explicitly.
|
||
It might not be consistent with some interpretations of what the existing
|
||
Stable ABI/Limited API is.</p>
|
||
</section>
|
||
<section id="security-implications">
|
||
<h2><a class="toc-backref" href="#security-implications" role="doc-backlink">Security Implications</a></h2>
|
||
<p>None known.</p>
|
||
</section>
|
||
<section id="how-to-teach-this">
|
||
<h2><a class="toc-backref" href="#how-to-teach-this" role="doc-backlink">How to Teach This</a></h2>
|
||
<p>Technical documentation will be provided in <code class="docutils literal notranslate"><span class="pre">Doc/c-api/stable</span></code>
|
||
and linked from the <em>What’s New</em> document.
|
||
Docs for CPython core developers will be added to the devguide.</p>
|
||
</section>
|
||
<section id="reference-implementation">
|
||
<h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2>
|
||
<p>See <a class="reference external" href="https://bugs.python.org/issue43795">issue 43795</a>.</p>
|
||
</section>
|
||
<section id="ideas-for-the-future">
|
||
<h2><a class="toc-backref" href="#ideas-for-the-future" role="doc-backlink">Ideas for the Future</a></h2>
|
||
<p>The following issues are out of scope of this PEP, but show possible
|
||
future directions.</p>
|
||
<section id="defining-a-process-for-deprecations-removals">
|
||
<h3><a class="toc-backref" href="#defining-a-process-for-deprecations-removals" role="doc-backlink">Defining a process for deprecations/removals</a></h3>
|
||
<p>While this PEP acknowledges that parts of the Limited API might be deprecated
|
||
or removed in the future, a process to do this is not in scope, and is left
|
||
to a possible future PEP.</p>
|
||
</section>
|
||
<section id="c-syntax-for-the-abi-manifest">
|
||
<h3><a class="toc-backref" href="#c-syntax-for-the-abi-manifest" role="doc-backlink">C syntax for the ABI manifest</a></h3>
|
||
<p>It might be useful to have the ABI manifest be a C header file, or to
|
||
generate header files from the manifest.
|
||
Again, either are options for the future.</p>
|
||
</section>
|
||
</section>
|
||
<section id="open-issues">
|
||
<h2><a class="toc-backref" href="#open-issues" role="doc-backlink">Open Issues</a></h2>
|
||
<p>None so far.</p>
|
||
</section>
|
||
<section id="copyright">
|
||
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
|
||
<p>This document is placed in the public domain or under the
|
||
CC0-1.0-Universal license, whichever is more permissive.</p>
|
||
</section>
|
||
</section>
|
||
<hr class="docutils" />
|
||
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0652.rst">https://github.com/python/peps/blob/main/peps/pep-0652.rst</a></p>
|
||
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0652.rst">2023-09-09 17:39:29 GMT</a></p>
|
||
|
||
</article>
|
||
<nav id="pep-sidebar">
|
||
<h2>Contents</h2>
|
||
<ul>
|
||
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
||
<li><a class="reference internal" href="#motivation">Motivation</a></li>
|
||
<li><a class="reference internal" href="#rationale">Rationale</a></li>
|
||
<li><a class="reference internal" href="#stable-abi-vs-limited-api">Stable ABI vs. Limited API</a><ul>
|
||
<li><a class="reference internal" href="#stable-abi">Stable ABI</a></li>
|
||
<li><a class="reference internal" href="#limited-api">Limited API</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#specification">Specification</a><ul>
|
||
<li><a class="reference internal" href="#stable-abi-manifest">Stable ABI Manifest</a></li>
|
||
<li><a class="reference internal" href="#contents-of-the-stable-abi">Contents of the Stable ABI</a></li>
|
||
<li><a class="reference internal" href="#documenting-the-limited-api">Documenting the Limited API</a></li>
|
||
<li><a class="reference internal" href="#testing-the-stable-abi">Testing the Stable ABI</a></li>
|
||
<li><a class="reference internal" href="#changing-the-limited-api">Changing the Limited API</a></li>
|
||
<li><a class="reference internal" href="#advice-for-extenders-and-embedders">Advice for Extenders and Embedders</a></li>
|
||
<li><a class="reference internal" href="#note-for-redistributors-of-python">Note for Redistributors of Python</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li>
|
||
<li><a class="reference internal" href="#security-implications">Security Implications</a></li>
|
||
<li><a class="reference internal" href="#how-to-teach-this">How to Teach This</a></li>
|
||
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
|
||
<li><a class="reference internal" href="#ideas-for-the-future">Ideas for the Future</a><ul>
|
||
<li><a class="reference internal" href="#defining-a-process-for-deprecations-removals">Defining a process for deprecations/removals</a></li>
|
||
<li><a class="reference internal" href="#c-syntax-for-the-abi-manifest">C syntax for the ABI manifest</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#open-issues">Open Issues</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
|
||
<br>
|
||
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0652.rst">Page Source (GitHub)</a>
|
||
</nav>
|
||
</section>
|
||
<script src="../_static/colour_scheme.js"></script>
|
||
<script src="../_static/wrap_tables.js"></script>
|
||
<script src="../_static/sticky_banner.js"></script>
|
||
</body>
|
||
</html> |