python-peps/pep-0730/index.html

700 lines
56 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 730 Adding iOS as a supported platform | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0730/">
<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 730 Adding iOS as a supported platform | peps.python.org'>
<meta property="og:description" content="This PEP proposes adding iOS as a supported platform in CPython. The initial goal is to achieve Tier 3 support for Python 3.13. This PEP describes the technical aspects of the changes that are required to support iOS. It also describes the project manag...">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0730/">
<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="This PEP proposes adding iOS as a supported platform in CPython. The initial goal is to achieve Tier 3 support for Python 3.13. This PEP describes the technical aspects of the changes that are required to support iOS. It also describes the project manag...">
<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 730</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 730 Adding iOS as a supported platform</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Russell Keith-Magee &lt;russell&#32;&#97;t&#32;keith-magee.com&gt;</dd>
<dt class="field-even">Sponsor<span class="colon">:</span></dt>
<dd class="field-even">Ned Deily &lt;nad&#32;&#97;t&#32;python.org&gt;</dd>
<dt class="field-odd">Discussions-To<span class="colon">:</span></dt>
<dd class="field-odd"><a class="reference external" href="https://discuss.python.org/t/pep730-adding-ios-as-a-supported-platform/35854">Discourse thread</a></dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><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-even">Created<span class="colon">:</span></dt>
<dd class="field-even">09-Oct-2023</dd>
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
<dd class="field-odd">3.13</dd>
<dt class="field-even">Resolution<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://discuss.python.org/t/pep-730-adding-ios-as-a-supported-platform/35854/66">Discourse 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><ul>
<li><a class="reference internal" href="#development-landscape">Development landscape</a></li>
<li><a class="reference internal" href="#posix-compliance">POSIX compliance</a></li>
<li><a class="reference internal" href="#dynamic-libraries">Dynamic libraries</a></li>
<li><a class="reference internal" href="#console-and-interactive-usage">Console and interactive usage</a></li>
</ul>
</li>
<li><a class="reference internal" href="#specification">Specification</a><ul>
<li><a class="reference internal" href="#platform-identification">Platform identification</a><ul>
<li><a class="reference internal" href="#sys"><code class="docutils literal notranslate"><span class="pre">sys</span></code></a></li>
<li><a class="reference internal" href="#platform"><code class="docutils literal notranslate"><span class="pre">platform</span></code></a></li>
<li><a class="reference internal" href="#os"><code class="docutils literal notranslate"><span class="pre">os</span></code></a></li>
<li><a class="reference internal" href="#sysconfig"><code class="docutils literal notranslate"><span class="pre">sysconfig</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#subprocess-support">Subprocess support</a></li>
<li><a class="reference internal" href="#dynamic-module-loading">Dynamic module loading</a></li>
<li><a class="reference internal" href="#compilation">Compilation</a></li>
<li><a class="reference internal" href="#distribution">Distribution</a></li>
<li><a class="reference internal" href="#ci-resources">CI resources</a></li>
<li><a class="reference internal" href="#packaging">Packaging</a></li>
<li><a class="reference internal" href="#pep-11-update">PEP 11 Update</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="#rejected-ideas">Rejected Ideas</a><ul>
<li><a class="reference internal" href="#simulator-identification">Simulator identification</a></li>
<li><a class="reference internal" href="#gnu-compiler-triples">GNU compiler triples</a></li>
<li><a class="reference internal" href="#universal-wheel-format">“Universal” wheel format</a></li>
<li><a class="reference internal" href="#supporting-static-builds">Supporting static builds</a></li>
<li><a class="reference internal" href="#interactive-repl-mode">Interactive/REPL mode</a></li>
<li><a class="reference internal" href="#x86-64-simulator-support">x86_64 simulator support</a></li>
<li><a class="reference internal" href="#on-device-testing">On-device testing</a></li>
<li><a class="reference internal" href="#ordering-of-multiarch-tags">Ordering of <code class="docutils literal notranslate"><span class="pre">_multiarch</span></code> tags</a></li>
<li><a class="reference internal" href="#values-returned-by-platform-ios-ver">Values returned by <code class="docutils literal notranslate"><span class="pre">platform.ios_ver()</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This PEP proposes adding iOS as a supported platform in CPython. The initial
goal is to achieve Tier 3 support for Python 3.13. This PEP describes the
technical aspects of the changes that are required to support iOS. It also
describes the project management concerns related to adoption of iOS as a Tier 3
platform.</p>
</section>
<section id="motivation">
<h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2>
<p>Over the last 15 years, mobile platforms have become increasingly important
parts of the computing landscape. iOS is one of two operating systems that
control the vast majority of these devices. However, there is no official
support for iOS in CPython.</p>
<p>The <a class="reference external" href="https://beeware.org">BeeWare Project</a> and <a class="reference external" href="https://kivy.org">Kivy</a>
have both supported iOS for almost 10 years. This support has been able to
generate applications that have been accepted for publication in the iOS App
Store. This demonstrates the technical feasibility of iOS support.</p>
<p>It is important for the future of Python as a language that it is able to be
used on any hardware or OS that has widespread adoption. If Python cannot be
used a on a platform that has widespread use, adoption of the language will be
impacted as potential users will adopt other languages that <em>do</em> provide support
for these platforms.</p>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<section id="development-landscape">
<h3><a class="toc-backref" href="#development-landscape" role="doc-backlink">Development landscape</a></h3>
<p>iOS provides a single API, but 2 distinct ABIs - <code class="docutils literal notranslate"><span class="pre">iphoneos</span></code> (physical
devices), and <code class="docutils literal notranslate"><span class="pre">iphonesimulator</span></code>. Each of these ABIs can be provided on
multiple CPU architectures. At time of writing, Apple officially supports
<code class="docutils literal notranslate"><span class="pre">arm64</span></code> on the device ABI, and <code class="docutils literal notranslate"><span class="pre">arm64</span></code> and <code class="docutils literal notranslate"><span class="pre">x86_64</span></code> are supported on the
simulator ABI.</p>
<p>As with macOS, iOS supports the creation of “fat” binaries that contains
multiple CPU architectures. However, fat binaries <em>cannot</em> span ABIs. That is,
it is possible to have a fat <em>simulator</em> binary, and a fat <em>device</em> binary, but
it is not possible to create a single fat “iOS” binary that covers both
simulator and device needs. To support distribution of a single development
artefact, Apple uses an “XCframework” structure - a wrapper around multiple ABIs
that implement a common API.</p>
<p>iOS runs on a Darwin kernel, similar to macOS. However, there is a need to
differentiate between macOS and iOS at an implementation level, as there are
significant platform differences between iOS and macOS.</p>
<p>iOS code is compiled for compatibility against a minimum iOS version.</p>
<p>Apple frequently refers to “iPadOS” in their marketing material. However, from a
development perspective, there is no discernable difference between iPadOS and
iOS. A binary that has been compiled for the <code class="docutils literal notranslate"><span class="pre">iphoneos</span></code> or <code class="docutils literal notranslate"><span class="pre">iphonesimulator</span></code>
ABIs can be deployed on iPad.</p>
<p>Other Apple platforms, such as tvOS, watchOS, and visionOS, use different ABIs,
and are not covered by this PEP.</p>
</section>
<section id="posix-compliance">
<h3><a class="toc-backref" href="#posix-compliance" role="doc-backlink">POSIX compliance</a></h3>
<p>iOS is broadly a POSIX platform. However, similar to WASI/Emscripten, there are
POSIX APIs that exist on iOS, but cannot be used; and POSIX APIs that dont
exist at all.</p>
<p>Most notable of these is the fact that iOS does not provide any form of
multiprocess support. <code class="docutils literal notranslate"><span class="pre">fork</span></code> and <code class="docutils literal notranslate"><span class="pre">spawn</span></code> both <em>exist</em> in the iOS API;
however, if they are invoked, the invoking iOS process stops, and the new
process doesnt start.</p>
<p>Unlike WASI/Emscripten, threading <em>is</em> supported on iOS.</p>
<p>There are also significant limits to socket handling. Due to process sandboxing,
there is no availability of interprocess communication via socket. However,
sockets for network communication <em>are</em> available.</p>
</section>
<section id="dynamic-libraries">
<h3><a class="toc-backref" href="#dynamic-libraries" role="doc-backlink">Dynamic libraries</a></h3>
<p>The iOS <a class="reference external" href="https://developer.apple.com/app-store/review/guidelines">App Store guidelines</a> allow apps to be
written in languages other than Objective C or Swift. However, they have very
strict guidelines about the structure of apps that are submitted for
distribution.</p>
<p>iOS apps can use dynamically loaded libraries; however, there are very strict
requirements on how dynamically loaded content is packaged for use on iOS:</p>
<ul class="simple">
<li>Dynamic binary content must be compiled as dynamic libraries, not shared
objects or binary bundles.</li>
<li>They must be packaged in the app bundle as Frameworks.</li>
<li>Each Framework can only contain a single dynamic library.</li>
<li>The Framework <em>must</em> be contained in the iOS Apps <code class="docutils literal notranslate"><span class="pre">Frameworks</span></code> folder.</li>
<li>A Framework may not contain any non-library content.</li>
</ul>
<p>This imposes some constraints on the operation of CPython. It is not possible
store binary modules in the <code class="docutils literal notranslate"><span class="pre">lib-dynload</span></code> and/or <code class="docutils literal notranslate"><span class="pre">site-packages</span></code> folders;
they must be stored in the apps Frameworks folder, with each module wrapped in
a Framework. This also means that the common assumption that a Python module can
construct the location of a binary module by using the <code class="docutils literal notranslate"><span class="pre">__file__</span></code> attribute of
the Python module no longer holds.</p>
<p>As with macOS, compiling a binary module that is accessible from a
statically-linked build of Python requires the use of the <code class="docutils literal notranslate"><span class="pre">--undefined</span>
<span class="pre">dynamic_lookup</span></code> option to avoid linking <code class="docutils literal notranslate"><span class="pre">libpython3.x</span></code> into every binary
module. However, on iOS, this compiler flag raises a deprecation warning when it
is used. A warning from this flag has been observed on macOS as well - however,
responses from Apple staff suggest that they <a class="reference external" href="https://github.com/python/cpython/issues/97524#issuecomment-1458855301">do not intend to break the CPython
ecosystem by removing this option</a>. As
Python does not currently have a notable presence on iOS, it is difficult to
judge whether iOS usage of this flag would fall under the same umbrella.</p>
</section>
<section id="console-and-interactive-usage">
<h3><a class="toc-backref" href="#console-and-interactive-usage" role="doc-backlink">Console and interactive usage</a></h3>
<p>Distribution of a traditional CPython REPL or interactive “python.exe” should
not be considered a goal of this work.</p>
<p>Mobile devices (including iOS) do not provide a TTY-style console. They do not
provide <code class="docutils literal notranslate"><span class="pre">stdin</span></code>, <code class="docutils literal notranslate"><span class="pre">stdout</span></code> or <code class="docutils literal notranslate"><span class="pre">stderr</span></code>. iOS provides a system log, and it
is possible to install a redirection so that all <code class="docutils literal notranslate"><span class="pre">stdout</span></code> and <code class="docutils literal notranslate"><span class="pre">stderr</span></code>
content is redirected to the system log; but there is no analog for <code class="docutils literal notranslate"><span class="pre">stdin</span></code>.</p>
<p>In addition, iOS places restrictions on downloading additional code at runtime
(as this behavior would be functionally indistinguishable from trying to work
around App Store review). As a result, a traditional “create a virtual
environment and pip install” development experience will not be viable on iOS.</p>
<p>It is <em>possible</em> to build an native iOS application that provides a REPL
interface. This would be closer to an IDLE-style user experience; however,
Tkinter cannot be used on iOS, so any app would require a ground-up rewrite. The
iOS app store already contains several examples of apps in this category (e.g.,
<a class="reference external" href="http://www.omz-software.com/pythonista/">Pythonista</a> and <a class="reference external" href="https://pyto.readthedocs.io/">Pyto</a>). The focus of this work would be to provide
an embedded distribution that IDE-style native interfaces could utilize, not a
user-facing “app” interface to iOS on Python.</p>
</section>
</section>
<section id="specification">
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
<section id="platform-identification">
<h3><a class="toc-backref" href="#platform-identification" role="doc-backlink">Platform identification</a></h3>
<section id="sys">
<h4><a class="toc-backref" href="#sys" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">sys</span></code></a></h4>
<p><code class="docutils literal notranslate"><span class="pre">sys.platform</span></code> will identify as <code class="docutils literal notranslate"><span class="pre">&quot;ios&quot;</span></code> on both simulator and physical
devices.</p>
<p><code class="docutils literal notranslate"><span class="pre">sys.implementation._multiarch</span></code> will describe the ABI and CPU architecture:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">&quot;arm64-iphoneos&quot;</span></code> for ARM64 devices</li>
<li><code class="docutils literal notranslate"><span class="pre">&quot;arm64-iphonesimulator&quot;</span></code> for ARM64 simulators</li>
<li><code class="docutils literal notranslate"><span class="pre">&quot;x86_64-iphonesimulator&quot;</span></code> for x86_64 simulators</li>
</ul>
</section>
<section id="platform">
<h4><a class="toc-backref" href="#platform" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">platform</span></code></a></h4>
<p><code class="docutils literal notranslate"><span class="pre">platform</span></code> will be modified to support returning iOS-specific details. Most of
the values returned by the <code class="docutils literal notranslate"><span class="pre">platform</span></code> module will match those returned by
<code class="docutils literal notranslate"><span class="pre">os.uname()</span></code>, with the exception of:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">platform.system()</span></code> - <code class="docutils literal notranslate"><span class="pre">&quot;iOS&quot;</span></code> or <code class="docutils literal notranslate"><span class="pre">iPadOS</span></code> (depending on the hardware in
use), instead of <code class="docutils literal notranslate"><span class="pre">&quot;Darwin&quot;</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">platform.release()</span></code> - the iOS version number, as a string (e.g.,
<code class="docutils literal notranslate"><span class="pre">&quot;16.6.1&quot;</span></code>), instead of the Darwin kernel version.</li>
</ul>
<p>In addition, a <code class="docutils literal notranslate"><span class="pre">platform.ios_ver()</span></code> method will be added. This mirrors
<code class="docutils literal notranslate"><span class="pre">platform.mac_ver()</span></code>, which can be used to provide macOS version information.
<code class="docutils literal notranslate"><span class="pre">ios_ver()</span></code> will return a namedtuple that contains the following:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">system</span></code> - the OS name (<code class="docutils literal notranslate"><span class="pre">iOS</span></code> or <code class="docutils literal notranslate"><span class="pre">iPadOS</span></code>, depending on hardware)</li>
<li><code class="docutils literal notranslate"><span class="pre">release</span></code> - the iOS version, as a string (e.g., <code class="docutils literal notranslate"><span class="pre">&quot;16.6.1&quot;</span></code>).</li>
<li><code class="docutils literal notranslate"><span class="pre">model</span></code> - the model identifier of the device, as a string (e.g.,
<code class="docutils literal notranslate"><span class="pre">&quot;iPhone13,2&quot;</span></code>). On simulators, this will return <code class="docutils literal notranslate"><span class="pre">&quot;iPhone&quot;</span></code> or <code class="docutils literal notranslate"><span class="pre">&quot;iPad&quot;</span></code>,
depending on the simulator device.</li>
<li><code class="docutils literal notranslate"><span class="pre">is_simulator</span></code> - a boolean indicating if the device is a simulator.</li>
</ul>
</section>
<section id="os">
<h4><a class="toc-backref" href="#os" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">os</span></code></a></h4>
<p><code class="docutils literal notranslate"><span class="pre">os.uname()</span></code> will return the raw result of a POSIX <code class="docutils literal notranslate"><span class="pre">uname()</span></code> call. This will
result in the following values:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">sysname</span></code> - <code class="docutils literal notranslate"><span class="pre">&quot;Darwin&quot;</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">release</span></code> - The Darwin kernel version (e.g., <code class="docutils literal notranslate"><span class="pre">&quot;22.6.0&quot;</span></code>)</li>
</ul>
<p>This approach treats the <code class="docutils literal notranslate"><span class="pre">os</span></code> module as a “raw” interface to system APIs, and
<code class="docutils literal notranslate"><span class="pre">platform</span></code> as a higher-level API providing more generally useful values.</p>
</section>
<section id="sysconfig">
<h4><a class="toc-backref" href="#sysconfig" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">sysconfig</span></code></a></h4>
<p>The <code class="docutils literal notranslate"><span class="pre">sysconfig</span></code> module will use the minimum iOS version as part of
<code class="docutils literal notranslate"><span class="pre">sysconfig.get_platform()</span></code> (e.g., <code class="docutils literal notranslate"><span class="pre">&quot;ios-12.0-arm64-iphoneos&quot;</span></code>). The
<code class="docutils literal notranslate"><span class="pre">sysconfigdata_name</span></code> and Config makefile will follow the same patterns as
existing platforms (using <code class="docutils literal notranslate"><span class="pre">sys.platform</span></code>, <code class="docutils literal notranslate"><span class="pre">sys.implementation._multiarch</span></code>
etc.) to construct identifiers.</p>
</section>
</section>
<section id="subprocess-support">
<h3><a class="toc-backref" href="#subprocess-support" role="doc-backlink">Subprocess support</a></h3>
<p>iOS will leverage the pattern for disabling subprocesses established by
WASI/Emscripten. The <code class="docutils literal notranslate"><span class="pre">subprocess</span></code> module will raise an exception if an attempt
is made to start a subprocess, and <code class="docutils literal notranslate"><span class="pre">os.fork</span></code> and <code class="docutils literal notranslate"><span class="pre">os.spawn</span></code> calls will raise
an <code class="docutils literal notranslate"><span class="pre">OSError</span></code>.</p>
</section>
<section id="dynamic-module-loading">
<h3><a class="toc-backref" href="#dynamic-module-loading" role="doc-backlink">Dynamic module loading</a></h3>
<p>To accommodate iOS dynamic loading, the <code class="docutils literal notranslate"><span class="pre">importlib</span></code> bootstrap will be extended
to add a metapath finder that can convert a request for a Python binary module
into a Framework location. This finder will only be installed if <code class="docutils literal notranslate"><span class="pre">sys.platform</span>
<span class="pre">==</span> <span class="pre">&quot;ios&quot;</span></code>.</p>
<p>This finder will convert a Python module name (e.g., <code class="docutils literal notranslate"><span class="pre">foo.bar._whiz</span></code>) into a
unique Framework name by using the full module name as the framework name (i.e.,
<code class="docutils literal notranslate"><span class="pre">foo.bar._whiz.framework</span></code>). A framework is a directory; the finder will look
for a binary named <code class="docutils literal notranslate"><span class="pre">foo.bar._whiz</span></code> in that directory.</p>
</section>
<section id="compilation">
<h3><a class="toc-backref" href="#compilation" role="doc-backlink">Compilation</a></h3>
<p>The only binary format that will be supported is a dynamically-linkable
<code class="docutils literal notranslate"><span class="pre">libpython3.x.dylib</span></code>, packaged in an iOS-compatible framework format. While
the <code class="docutils literal notranslate"><span class="pre">--undefined</span> <span class="pre">dynamic_lookup</span></code> compiler option currently works, the
long-term viability of the option cannot be guaranteed. Rather than rely on a
compiler flag with an uncertain future, binary modules on iOS will be linked
with <code class="docutils literal notranslate"><span class="pre">libpython3.x.dylib</span></code>. This means iOS binary modules will not be loadable
by an executable that has been statically linked against <code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code>.
Therefore, a static <code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code> iOS library will not be supported. This
is the same pattern used by CPython on Windows.</p>
<p>Building CPython for iOS requires the use of the cross-platform tooling in
CPythons <code class="docutils literal notranslate"><span class="pre">configure</span></code> build system. A single <code class="docutils literal notranslate"><span class="pre">configure</span></code>/<code class="docutils literal notranslate"><span class="pre">make</span></code>/<code class="docutils literal notranslate"><span class="pre">make</span>
<span class="pre">install</span></code> pass will produce a <code class="docutils literal notranslate"><span class="pre">Python.framework</span></code> artefact that can be used on
a single ABI and architecture.</p>
<p>Additional tooling will be required to merge the <code class="docutils literal notranslate"><span class="pre">Python.framework</span></code> builds for
multiple architectures into a single “fat” library. Tooling will also be
required to merge multiple ABIs into the <code class="docutils literal notranslate"><span class="pre">XCframework</span></code> format that Apple uses
to distribute multiple frameworks for different ABIs in a single bundle.</p>
<p>An Xcode project will be provided for the purpose of running the CPython test
suite. Tooling will be provided to automate the process of compiling the test
suite binary, start the simulator, install the test suite, and execute it.</p>
</section>
<section id="distribution">
<h3><a class="toc-backref" href="#distribution" role="doc-backlink">Distribution</a></h3>
<p>Adding iOS as a Tier 3 platform only requires adding support for compiling an
iOS-compatible build from an unpatched CPython code checkout. It does not
require production of officially distributed iOS artefacts for use by end-users.</p>
<p>If/when iOS is updated to Tier 2 or 1 support, the tooling used to generate an
<code class="docutils literal notranslate"><span class="pre">XCframework</span></code> package could be used to produce an iOS distribution artefact.
This could then be distributed as an “embedded distribution” analogous to the
Windows embedded distribution, or as a CocoaPod or Swift package that could be
added to an Xcode project.</p>
</section>
<section id="ci-resources">
<h3><a class="toc-backref" href="#ci-resources" role="doc-backlink">CI resources</a></h3>
<p><a class="reference external" href="https://anaconda.com">Anaconda</a> has offered to provide physical hardware to
run iOS buildbots.</p>
<p>GitHub Actions is able to host iOS simulators on their macOS machines, and the
iOS simulator can be controlled by scripting environments. The free tier
currently only provides x86_64 macOS machines; however ARM64 runners <a class="reference external" href="https://github.blog/2023-10-02-introducing-the-new-apple-silicon-powered-m1-macos-larger-runner-for-github-actions/">recently
became available on paid plans</a>.
However, in order to avoid exhausting macOS runner resources, a GitHub Actions
run for iOS will not be added as part of the standard CI configuration.</p>
</section>
<section id="packaging">
<h3><a class="toc-backref" href="#packaging" role="doc-backlink">Packaging</a></h3>
<p>iOS will not provide a “universal” wheel format. Instead, wheels will be
provided for each ABI-arch combination.</p>
<p>iOS wheels will use tags:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">ios_12_0_arm64_iphoneos</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">ios_12_0_arm64_iphonesimulator</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">ios_12_0_x86_64_iphonesimulator</span></code></li>
</ul>
<p>In these tags, “12.0” is the minimum supported iOS version. As with macOS, the
tag will incorporate the minimum iOS version that is selected when the wheel is
compiled; a wheel compiled with a minimum iOS version of 15.0 would use the
<code class="docutils literal notranslate"><span class="pre">ios_15_0_*</span></code> tags. At time of writing, iOS 12.0 exposes most significant iOS
features, while reaching near 100% of devices; this will be used as a floor for
iOS version matching.</p>
<p>These wheels can include binary modules in-situ (i.e., co-located with the
Python source, in the same way as wheels for a desktop platform); however, they
will need to be post-processed as binary modules need to be moved into the
“Frameworks” location for distribution. This can be automated with an Xcode
build step.</p>
</section>
<section id="pep-11-update">
<h3><a class="toc-backref" href="#pep-11-update" role="doc-backlink">PEP 11 Update</a></h3>
<p><a class="pep reference internal" href="../pep-0011/" title="PEP 11 CPython platform support">PEP 11</a> will be updated to include two of the iOS ABIs:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">arm64-apple-ios</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">arm64-apple-ios-simulator</span></code></li>
</ul>
<p>Ned Deily will serve as the initial core team contact for these ABIs.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">x86_64-apple-ios-simulator</span></code> target will be supported on a best-effort
basis, but will not be targeted for tier 3 support. This is due to the impending
deprecation of x86_64 as a simulation platform, combined with the difficulty of
commissioning x86_64 macOS hardware at this time.</p>
</section>
</section>
<section id="backwards-compatibility">
<h2><a class="toc-backref" href="#backwards-compatibility" role="doc-backlink">Backwards Compatibility</a></h2>
<p>Adding a new platform does not introduce any backwards compatibility concerns to
CPython itself.</p>
<p>There may be some backwards compatibility implications on the projects that have
historically provided CPython support (i.e., BeeWare and Kivy) if the final form
of any CPython patches dont align with the patches they have historically used.</p>
<p>Although not strictly a backwards compatibility issue, there <em>is</em> a platform
adoption consideration. Although CPython itself may support iOS, if it is
unclear how to produce iOS-compatible wheels, and prominent libraries like
cryptography, Pillow, and NumPy dont provide iOS wheels, the ability of the
community to adopt Python on iOS will be limited. Therefore, it will be
necessary to clearly document how projects can add iOS builds to their CI and
release tooling. Adding iOS support to tools like <a class="reference external" href="https://crossenv.readthedocs.io/">crossenv</a> and <a class="reference external" href="https://cibuildwheel.readthedocs.io/">cibuildwheel</a> may be one way to achieve this.</p>
</section>
<section id="security-implications">
<h2><a class="toc-backref" href="#security-implications" role="doc-backlink">Security Implications</a></h2>
<p>Adding iOS as a new platform does not add any security implications.</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>The education needs related to this PEP mostly relate to how end-users can add
iOS support to their own Xcode projects. This can be accomplished with
documentation and tutorials on that process. The need for this documentation
will increase if/when support raises from Tier 3 to Tier 2 or 1; however, this
transition should also be accompanied with simplified deployment artefacts (such
as a Cocoapod or Swift package) that are integrated with Xcode development.</p>
</section>
<section id="reference-implementation">
<h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2>
<p>The BeeWare <a class="reference external" href="https://github.com/beeware/Python-Apple-support">Python-Apple-support</a> repository contains a
reference patch and build tooling to compile a distributable artefact.</p>
<p><a class="reference external" href="https://briefcase.readthedocs.org">Briefcase</a> provides a reference
implementation of code to execute test suites on iOS simulators. The <a class="reference external" href="https://github.com/beeware/toga/tree/main/testbed">Toga
Testbed</a> is an example of
a test suite that is executed on the iOS simulator using GitHub Actions.</p>
</section>
<section id="rejected-ideas">
<h2><a class="toc-backref" href="#rejected-ideas" role="doc-backlink">Rejected Ideas</a></h2>
<section id="simulator-identification">
<h3><a class="toc-backref" href="#simulator-identification" role="doc-backlink">Simulator identification</a></h3>
<p>Earlier versions of this PEP suggested the inclusion of
<code class="docutils literal notranslate"><span class="pre">sys.implementation._simulator</span></code> attribute to identify when code is running on
device, or on a simulator. This was rejected due to the use of a protected name
for a public API, plus the pollution of the <code class="docutils literal notranslate"><span class="pre">sys</span></code> namespace with an
iOS-specific detail.</p>
<p>Another proposal during discussion was to include a generic
<code class="docutils literal notranslate"><span class="pre">platform.is_emulator()</span></code> API that could be implemented by any platform - for
example to differentiate running on x86_64 code on ARM64 hardware, or when
running in QEMU or other virtualization methods. This was rejected on the basis
that it wasnt clear what a consistent interpretation of “emulator” would be, or
how an emulator would be detected outside of the iOS case.</p>
<p>The decision was made to keep this detail iOS-specific, and include it on the
<code class="docutils literal notranslate"><span class="pre">platform.ios_ver()</span></code> API.</p>
</section>
<section id="gnu-compiler-triples">
<h3><a class="toc-backref" href="#gnu-compiler-triples" role="doc-backlink">GNU compiler triples</a></h3>
<p><code class="docutils literal notranslate"><span class="pre">autoconf</span></code> requires the use of a GNU compiler triple to identify build and
host platforms. However, the <code class="docutils literal notranslate"><span class="pre">autoconf</span></code> toolchain doesnt provide native
support for iOS simulators, so we are left with the task of working out how to
squeeze iOS hardware into GNUs naming regimen.</p>
<p>This can be done (with some patching of <code class="docutils literal notranslate"><span class="pre">config.sub</span></code>), but it leads to 2 major
sources of naming inconsistency:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">arm64</span></code> vs <code class="docutils literal notranslate"><span class="pre">aarch64</span></code> as an identifier of 64-bit ARM hardware; and</li>
<li>What identifier is used to represent simulators.</li>
</ul>
<p>Apples own tools use <code class="docutils literal notranslate"><span class="pre">arm64</span></code> as the architecture, but appear to be tolerant
of <code class="docutils literal notranslate"><span class="pre">aarch64</span></code> in some cases. The device platform is identified as <code class="docutils literal notranslate"><span class="pre">iphoneos</span></code>
and <code class="docutils literal notranslate"><span class="pre">iphonesimulator</span></code>.</p>
<p>Rust toolchains uses <code class="docutils literal notranslate"><span class="pre">aarch64</span></code> as the architecture, and use
<code class="docutils literal notranslate"><span class="pre">aarch64-apple-ios</span></code> and <code class="docutils literal notranslate"><span class="pre">aarch64-apple-ios-sim</span></code> to identify the device
platform; however, they use <code class="docutils literal notranslate"><span class="pre">x86_64-apple-ios</span></code> to represent iOS <em>simulators</em>
on x86_64 hardware.</p>
<p>The decision was made to use <code class="docutils literal notranslate"><span class="pre">arm64-apple-ios</span></code> and
<code class="docutils literal notranslate"><span class="pre">arm64-apple-ios-simulator</span></code> because:</p>
<ol class="arabic simple">
<li>The <code class="docutils literal notranslate"><span class="pre">autoconf</span></code> toolchain already contains support for <code class="docutils literal notranslate"><span class="pre">ios</span></code> as a platform
in <code class="docutils literal notranslate"><span class="pre">config.sub</span></code>; its only the simulator that doesnt have a representation.</li>
<li>The third part of the host triple is used as <code class="docutils literal notranslate"><span class="pre">sys.platform</span></code>.</li>
<li>When Apples own tools reference CPU architecture, they use <code class="docutils literal notranslate"><span class="pre">arm64</span></code>, and
the GNU tooling usage of the architecture isnt visible outside the build
process.</li>
<li>When Apples own tools reference simulator status independent of the OS
(e.g., in the naming of Swift submodules), they use a <code class="docutils literal notranslate"><span class="pre">-simulator</span></code> suffix.</li>
<li>While <em>some</em> iOS packages will use Rust, <em>all</em> iOS packages will use Apples
tooling.</li>
</ol>
<p>The initially accepted version of this document used the <code class="docutils literal notranslate"><span class="pre">aarch64</span></code> form as the PEP 11 identifier; this was corrected during finalization.</p>
</section>
<section id="universal-wheel-format">
<h3><a class="toc-backref" href="#universal-wheel-format" role="doc-backlink">“Universal” wheel format</a></h3>
<p>macOS currently supports 2 CPU architectures. To aid the end-user development
experience, Python defines a “universal2” wheel format that incorporates both
x86_64 and ARM64 binaries.</p>
<p>It would be conceptually possible to offer an analogous “universal” iOS wheel
format. However, this PEP does not use this approach, for 2 reasons.</p>
<p>Firstly, the experience on macOS, especially in the numerical Python ecosystem,
has been that universal wheels can be exceedingly difficult to accommodate.
While native macOS libraries maintain strong multi-platform support, and Python
itself has been updated, the vast majority of upstream non-Python libraries do
not provide multi-architecture build support. As a result, compiling universal
wheels inevitably requires multiple compilation passes, and complex decisions
over how to distribute header files for different architectures. As a result of
this complexity, many popular projects (including NumPy and Pillow) do not
provide universal wheels at all, instead providing separate ARM64 and x86_64
wheels.</p>
<p>Secondly, historical experience is that iOS would require a much more fluid
“universal” definition. In the last 10 years, there have been <em>at least</em> 5
different possible interpretations of “universal” that would apply to iOS,
including various combinations of armv6, armv7, armv7s, arm64, x86 and x86_64
architectures, on device and simulator. If defined right now, “universal-iOS”
would likely include x86_64 and arm64 on simulator, and arm64 on device;
however, the pending deprecation of x86_64 hardware would add another
interpretation; and there may be a need to add arm64e as a new device
architecture in the future. Specifying iOS wheels as single-platform-only means
the Python core team can avoid an ongoing standardization discussion about the
updated “universal” formats.</p>
<p>It also means wheel publishers are able to make per-project decisions over which
platforms are feasible to support. For example, a project may choose to drop
x86_64 support, or adopt a new architecture earlier than other parts of the
Python ecosystem. Using platform-specific wheels means this decision can be left
to individual package publishers.</p>
<p>This decision comes at cost of making deployment more complicated. However,
deployment on iOS is already a complicated process that is best aided by tools.
At present, no binary merging is required, as there is only one on-device
architecture, and simulator binaries are not considered to be distributable
artefacts, so only one architecture is needed to build an app for a simulator.</p>
</section>
<section id="supporting-static-builds">
<h3><a class="toc-backref" href="#supporting-static-builds" role="doc-backlink">Supporting static builds</a></h3>
<p>While the long-term viability of the <code class="docutils literal notranslate"><span class="pre">--undefined</span> <span class="pre">dynamic_lookup</span></code> option
cannot be guaranteed, the option does exist, and it works. One option would be
to ignore the deprecation warning, and hope that Apple either reverses the
deprecation decision, or never finalizes the deprecation.</p>
<p>Given that Apples decision-making process is entirely opaque, this would be, at
best, a risky option. When combined with the fact that the broader iOS
development ecosystem encourages the use of frameworks, there are no legacy uses
of a static library to consider, and the only benefit to a statically-linked iOS
<code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code> is a very slightly reduced app startup time, omitting support
for static builds of <code class="docutils literal notranslate"><span class="pre">libpython3.x</span></code> seems a reasonable compromise.</p>
<p>It is worth noting that there has been some discussion on <a class="reference external" href="https://github.com/python/cpython/issues/103306">an alternate approach
to linking on macOS</a> that
would remove the need for the <code class="docutils literal notranslate"><span class="pre">--undefined</span> <span class="pre">dynamic_lookup</span></code> option, although
discussion on this approach appears to have stalled due to complications in
implementation. If those complications were to be overcome, it is highly likely
that the same approach <em>could</em> be used on iOS, which <em>would</em> make a statically
linked <code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code> plausible.</p>
<p>The decision to link binary modules against <code class="docutils literal notranslate"><span class="pre">libpython3.x.dylib</span></code> would
complicate the introduction of static <code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code> builds in the future,
as the process of moving to a different binary module linking approach would
require a clear way to differentate “dynamically-linked” iOS binary modules from
“static-compatible” iOS binary modules. However, given the lack of tangible
benefits of a static <code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code>, it seems unlikely that there will be
any requirement to make this change.</p>
</section>
<section id="interactive-repl-mode">
<h3><a class="toc-backref" href="#interactive-repl-mode" role="doc-backlink">Interactive/REPL mode</a></h3>
<p>A traditional <code class="docutils literal notranslate"><span class="pre">python.exe</span></code> command line experience isnt really viable on
mobile devices, because mobile devices dont have a command line. iOS apps dont
have a stdout, stderr or stdin; and while you can redirect stdout and stderr to
the system log, theres no source for stdin that exists that doesnt also
involve building a very specific user-facing app that would be closer to an
IDLE-style IDE experience. Therefore, the decision was made to only focus on
“embedded mode” as a target for mobile distribution.</p>
</section>
<section id="x86-64-simulator-support">
<h3><a class="toc-backref" href="#x86-64-simulator-support" role="doc-backlink">x86_64 simulator support</a></h3>
<p>Apple no longer sells x86_64 hardware. As a result, commissioning an x86_64
buildbot can be difficult. It is possible to run macOS binaries in x86_64
compatibility mode on ARM64 hardware; however, this isnt ideal for testing
purposes. Therefore, the x86_64 Simulator (<code class="docutils literal notranslate"><span class="pre">x86_64-apple-ios-simulator</span></code>) will
not be added as a Tier 3 target. It is highly likely that iOS support will work
on the x86_64 without any modification; this only impacts on the <em>official</em> Tier
3 status.</p>
</section>
<section id="on-device-testing">
<h3><a class="toc-backref" href="#on-device-testing" role="doc-backlink">On-device testing</a></h3>
<p>CI testing on simulators can be accommodated reasonably easily. On-device
testing is much harder, as availability of device farms that could be configured
to provide Buildbots or Github Actions runners is limited.</p>
<p>However, on device testing may not be necessary. As a data point - Apples Xcode
Cloud solution doesnt provide on-device testing. They rely on the fact that the
API is consistent between device and simulator, and ARM64 simulator testing is
sufficient to reveal CPU-specific issues.</p>
</section>
<section id="ordering-of-multiarch-tags">
<h3><a class="toc-backref" href="#ordering-of-multiarch-tags" role="doc-backlink">Ordering of <code class="docutils literal notranslate"><span class="pre">_multiarch</span></code> tags</a></h3>
<p>The initially accepted version of this document used <code class="docutils literal notranslate"><span class="pre">&lt;platform&gt;-&lt;arch&gt;</span></code>
ordering (e.g., <code class="docutils literal notranslate"><span class="pre">iphoneos-arm64</span></code>) for <code class="docutils literal notranslate"><span class="pre">sys.implementation._multiarch</span></code> (and
related values, such as wheel tags). The final merged version uses the
<code class="docutils literal notranslate"><span class="pre">&lt;arch&gt;-&lt;platform&gt;</span></code> ordering (e.g., <code class="docutils literal notranslate"><span class="pre">arm64-iphoneos</span></code>). This is for
consistency with compiler triples on other platforms (especially Linux), which
specify the architecture before the operating system.</p>
</section>
<section id="values-returned-by-platform-ios-ver">
<h3><a class="toc-backref" href="#values-returned-by-platform-ios-ver" role="doc-backlink">Values returned by <code class="docutils literal notranslate"><span class="pre">platform.ios_ver()</span></code></a></h3>
<p>The initially accepted version of this document didnt include a <code class="docutils literal notranslate"><span class="pre">system</span></code>
identifier. This was added during the implementation phase to support the implementation of <code class="docutils literal notranslate"><span class="pre">platform.system()</span></code>.</p>
<p>The initially accepted version of this document also described that
<code class="docutils literal notranslate"><span class="pre">min_release</span></code> would be returned in the <code class="docutils literal notranslate"><span class="pre">ios_ver()</span></code> result. The final version
omits the <code class="docutils literal notranslate"><span class="pre">min_release</span></code> value, as it is not significant at runtime; it only
impacts on binary compatibility. The minimum version <em>is</em> included in the value
returned by <code class="docutils literal notranslate"><span class="pre">sysconfig.get_platform()</span></code>, as this is used to define wheel (and
other binary) compatibility.</p>
</section>
</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-0730.rst">https://github.com/python/peps/blob/main/peps/pep-0730.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0730.rst">2024-04-21 03:05:49 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><ul>
<li><a class="reference internal" href="#development-landscape">Development landscape</a></li>
<li><a class="reference internal" href="#posix-compliance">POSIX compliance</a></li>
<li><a class="reference internal" href="#dynamic-libraries">Dynamic libraries</a></li>
<li><a class="reference internal" href="#console-and-interactive-usage">Console and interactive usage</a></li>
</ul>
</li>
<li><a class="reference internal" href="#specification">Specification</a><ul>
<li><a class="reference internal" href="#platform-identification">Platform identification</a><ul>
<li><a class="reference internal" href="#sys"><code class="docutils literal notranslate"><span class="pre">sys</span></code></a></li>
<li><a class="reference internal" href="#platform"><code class="docutils literal notranslate"><span class="pre">platform</span></code></a></li>
<li><a class="reference internal" href="#os"><code class="docutils literal notranslate"><span class="pre">os</span></code></a></li>
<li><a class="reference internal" href="#sysconfig"><code class="docutils literal notranslate"><span class="pre">sysconfig</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#subprocess-support">Subprocess support</a></li>
<li><a class="reference internal" href="#dynamic-module-loading">Dynamic module loading</a></li>
<li><a class="reference internal" href="#compilation">Compilation</a></li>
<li><a class="reference internal" href="#distribution">Distribution</a></li>
<li><a class="reference internal" href="#ci-resources">CI resources</a></li>
<li><a class="reference internal" href="#packaging">Packaging</a></li>
<li><a class="reference internal" href="#pep-11-update">PEP 11 Update</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="#rejected-ideas">Rejected Ideas</a><ul>
<li><a class="reference internal" href="#simulator-identification">Simulator identification</a></li>
<li><a class="reference internal" href="#gnu-compiler-triples">GNU compiler triples</a></li>
<li><a class="reference internal" href="#universal-wheel-format">“Universal” wheel format</a></li>
<li><a class="reference internal" href="#supporting-static-builds">Supporting static builds</a></li>
<li><a class="reference internal" href="#interactive-repl-mode">Interactive/REPL mode</a></li>
<li><a class="reference internal" href="#x86-64-simulator-support">x86_64 simulator support</a></li>
<li><a class="reference internal" href="#on-device-testing">On-device testing</a></li>
<li><a class="reference internal" href="#ordering-of-multiarch-tags">Ordering of <code class="docutils literal notranslate"><span class="pre">_multiarch</span></code> tags</a></li>
<li><a class="reference internal" href="#values-returned-by-platform-ios-ver">Values returned by <code class="docutils literal notranslate"><span class="pre">platform.ios_ver()</span></code></a></li>
</ul>
</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-0730.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>