python-peps/pep-0652/index.html

554 lines
36 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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="CPythons 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="CPythons 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> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </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 &lt;encukou&#32;&#97;t&#32;gmail.com&gt;</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&#64;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 Pythons 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>CPythons 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 APIs 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 theres a list thats <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 CPythons 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 CPythons 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 Pythons 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">&amp;&amp;</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 Pythons 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 couldnt 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 its 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">&gt;=</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 arent.
<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 teams 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>Whats 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>