python-peps/pep-0738/index.html

547 lines
40 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 738 Adding Android 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-0738/">
<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 738 Adding Android as a supported platform | peps.python.org'>
<meta property="og:description" content="This PEP proposes adding Android as a supported platform in CPython. The initial goal is for Android to achieve Tier 3 support in Python 3.13.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0738/">
<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 Android as a supported platform in CPython. The initial goal is for Android to achieve Tier 3 support in Python 3.13.">
<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 738</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 738 Adding Android 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">Malcolm Smith &lt;smith&#32;&#97;t&#32;chaquo.com&gt;</dd>
<dt class="field-even">Sponsor<span class="colon">:</span></dt>
<dd class="field-even">Petr Viktorin &lt;encukou&#32;&#97;t&#32;gmail.com&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/pep-738-adding-android-as-a-supported-platform/40975">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">12-Dec-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-738-adding-android-as-a-supported-platform/40975/23">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="#general">General</a></li>
<li><a class="reference internal" href="#os-versions">OS versions</a></li>
<li><a class="reference internal" href="#development-tools">Development tools</a></li>
<li><a class="reference internal" href="#architectures">Architectures</a></li>
<li><a class="reference internal" href="#app-lifecycle">App lifecycle</a></li>
</ul>
</li>
<li><a class="reference internal" href="#specification">Specification</a><ul>
<li><a class="reference internal" href="#scope-of-work">Scope of work</a></li>
<li><a class="reference internal" href="#linkage">Linkage</a></li>
<li><a class="reference internal" href="#standard-library">Standard library</a><ul>
<li><a class="reference internal" href="#unsupported-modules">Unsupported modules</a></li>
<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>
</ul>
</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></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/using/android.html#using-android" title="(in Python v3.13)"><span>Using Python on Android</span></a>.</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>This PEP proposes adding Android as a supported platform in CPython. The initial
goal is for Android to achieve Tier 3 support in Python 3.13.</p>
<p>This PEP is based on <a class="pep reference internal" href="../pep-0730/" title="PEP 730 Adding iOS as a supported platform">PEP 730</a> “Adding iOS as a supported platform” by
Russell Keith-Magee, and covers many of the same issues. Notable differences
between the two platforms can be found by searching for the word “iOS”.</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. Android is the operating system that runs on
about <a class="reference external" href="https://gs.statcounter.com/os-market-share/mobile/worldwide">70% of these devices</a>. However, there
is no official support for Android in CPython.</p>
<p>The <a class="reference external" href="https://chaquo.com/chaquopy/">Chaquopy</a>, <a class="reference external" href="https://beeware.org">BeeWare</a> and <a class="reference external" href="https://kivy.org">Kivy</a> projects
have all supported Android for many years, and they have all been used to
generate applications that have been accepted for publication in the Google Play
Store. This demonstrates the technical feasibility of Android support.</p>
<p>It is important for the future of Python as a language that it is able to be
used on any platform that has widespread adoption. Otherwise, potential users
will choose other languages that <em>do</em> provide support for these platforms. This
is especially true in education, where the next generation of developers is in
many cases already spending more time using mobile platforms than desktop ones.</p>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<section id="general">
<h3><a class="toc-backref" href="#general" role="doc-backlink">General</a></h3>
<p>Android is broadly a POSIX platform, based on a Linux kernel and the
ELF binary format. It does not use glibc, instead providing its own C
library implementation called Bionic. As a result, it is generally not
binary-compatible with any other Linux distribution, even if the architecture
matches. It also has its own filesystem layout which doesnt resemble any other
Unix.</p>
<p>However, Androids source-compatibility with Linux is quite good. In its early years,
the C library was very incomplete, but most of the gaps were filled by around
2014. Since then, any C code that compiles for Linux can usually be compiled for
Android, unless it involves direct access to hardware devices or operating
system services.</p>
<p>This is also true of CPython. Although it has never officially supported
Android, recent versions (since 3.6) can already be compiled for Android with
minimal patching.</p>
</section>
<section id="os-versions">
<span id="id1"></span><h3><a class="toc-backref" href="#os-versions" role="doc-backlink">OS versions</a></h3>
<p>Each Android version can be identified in three ways:</p>
<ul class="simple">
<li>A conventional dotted version number (though recent versions have all used
whole numbers)</li>
<li>A sequential integer “API level” (the most common form in developer
documentation)</li>
<li>An alphabetic confectionery-themed code name (no longer used for marketing,
but still appears in developer documentation)</li>
</ul>
<p>There is no consistent pattern to link one of these to another; they must be
looked up in <a class="reference external" href="https://en.wikipedia.org/wiki/Android_version_history">a table</a>.</p>
<p>A new major Android version is released each year, but the updates available to
each device are entirely under the control of its manufacturer. Unfortunately
many manufacturers stop sending updates to devices long before their users are
ready to dispose of them. For example, as of October 2023, the oldest Android
version still receiving security updates was API level 30, but according to
<a class="reference external" href="https://dl.google.com/android/studio/metadata/distributions.json">Googles own statistics</a>, only 60%
of devices were on that version or newer.</p>
<p>For Python 3.13 we therefore propose the minimum Android version to be 5.0
(API level 21), which was released in 2014. According to the statistics above,
this would cover 99% of active devices.</p>
</section>
<section id="development-tools">
<h3><a class="toc-backref" href="#development-tools" role="doc-backlink">Development tools</a></h3>
<p>The Android development tools are equally supported on Linux (x86_64), Windows
(x86_64) and macOS (x86_64 and ARM64). For CPython, the most important tools
are:</p>
<ul>
<li>The NDK (native development kit) contains a C and C++ compiler (clang),
linker (lld), and headers for all the system libraries.<p>Binary compatibility between libraries compiled with different versions of the
NDK is generally very good, but for reproducibility it would be best for each
Python version to stick with one NDK version throughout its life. For Python
3.13, this would be the current NDK long-term support version, r26.</p>
<p>Each NDK version can be set to target any of a wide range of Android versions.
For example, NDK r26 supports <a class="reference internal" href="#os-versions"><span class="std std-ref">API levels</span></a> 21 to 34.
However, binaries compiled for an older Android version will usually keep on
working indefinitely on newer versions; exceptions to this rule are only made
for security reasons.</p>
</li>
<li>Gradle is the tool used to build complete, deployable apps.</li>
<li>The emulator, based on QEMU, is a simulated Android device running on a
development machine. Unlike on iOS, an emulator uses the same ABI as a real
device of the same architecture, and can run the same binaries.</li>
</ul>
<p>These tools may all be used either from the command line, or through the Android
Studio IDE, which is based on IntelliJ IDEA.</p>
</section>
<section id="architectures">
<h3><a class="toc-backref" href="#architectures" role="doc-backlink">Architectures</a></h3>
<p>Android currently supports 4 architectures. Their names as used by the Android
tools are:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">armeabi-v7a</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">arm64-v8a</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">x86</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">x86_64</span></code></li>
</ul>
<p>Virtually all current physical devices use one of the ARM architectures. <code class="docutils literal notranslate"><span class="pre">x86</span></code>
and <code class="docutils literal notranslate"><span class="pre">x86_64</span></code> are supported for use in the emulator.</p>
<p>For Python 3.13 we propose that Tier 3 support will only cover the 64-bit platforms
(<code class="docutils literal notranslate"><span class="pre">arm64-v8a</span></code> and <code class="docutils literal notranslate"><span class="pre">x86_64</span></code>):</p>
<ul>
<li><code class="docutils literal notranslate"><span class="pre">x86</span></code> has not been supported as a development platform since 2020, and no
new emulator images have been released since then.</li>
<li><code class="docutils literal notranslate"><span class="pre">armeabi-v7a</span></code>s proportion of active devices is now
<a class="reference external" href="https://github.com/chaquo/chaquopy/issues/709#issuecomment-1744541892">less than 10% and steadily falling</a>.<p>It would also be more difficult to cover with a reliable buildbot, since there
are no native hosts available for the emulator (ARM64 Macs dont have hardware
support for ARM32 code). Although cross-architecture emulation is possible, it
has much worse performance and stability, which is why the <code class="docutils literal notranslate"><span class="pre">armeabi-v7a</span></code>
emulator images have not been updated since 2016.</p>
<p>However, it continues to be used for watches and ultra-low-cost phones. If
this persists, we may need to consider adding it in a future Python version.</p>
</li>
</ul>
<p>Even if 32-bit architectures are not officially supported, no changes should be
made which would impede any downstream projects which still wish to build them.</p>
</section>
<section id="app-lifecycle">
<h3><a class="toc-backref" href="#app-lifecycle" role="doc-backlink">App lifecycle</a></h3>
<p>The primary programming language in Android apps is Java, or its modern descendant
Kotlin. As such, an app does not provide its own executable file. Instead, all
apps start off as a Java virtual machine running an executable provided by the
operating system. The apps Java code can then add native code to the process by
loading dynamic libraries and calling them through JNI.</p>
<p>Unlike iOS, creating subprocesses <em>is</em> supported on Android. However apps may
only run executables in <a class="reference external" href="https://issuetracker.google.com/issues/128554619#comment4">certain locations</a>, none of which
are writable at runtime. Long-running subprocesses are <a class="reference external" href="https://issuetracker.google.com/issues/128554619#comment4">officially discouraged</a>, and are not
guaranteed to be supported in future Android versions.</p>
<p>Android does provide a command-line shell, but this is intended only for use by
developers, and is not available to the typical end user.</p>
<p>For these reasons, the recommended way of running Python on Android will be by
loading <code class="docutils literal notranslate"><span class="pre">libpython3.x.so</span></code> into the main app process. A <code class="docutils literal notranslate"><span class="pre">python3.x</span></code>
executable will not be officially supported on this platform.</p>
</section>
</section>
<section id="specification">
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
<section id="scope-of-work">
<h3><a class="toc-backref" href="#scope-of-work" role="doc-backlink">Scope of work</a></h3>
<p>The focus of this work will be to produce an Android equivalent to the existing
<a class="reference external" href="https://docs.python.org/3/using/windows.html#the-embeddable-package">Windows embeddable package</a>,
i.e. a set of compiled libraries which developers
can add to their apps. No installer will be required.</p>
<p>Adding Android as a Tier 3 platform only requires adding support for compiling
an Android-compatible build from the unpatched CPython source code. It does not
necessarily require there to be any officially distributed Android artifacts on
python.org, although these could be added in the future.</p>
<p>Android will be built using the same configure and Makefile system as other
POSIX platforms, and must therefore be built <em>on</em> a POSIX platform. Both Linux
and macOS will be supported.</p>
<p>A Gradle project will be provided for the purpose of running the CPython test
suite. Tooling will be provided to automate the process of building the test
suite app, starting the emulator, installing the test suite, and executing
it.</p>
</section>
<section id="linkage">
<h3><a class="toc-backref" href="#linkage" role="doc-backlink">Linkage</a></h3>
<p>For the reasons discussed in <a class="reference internal" href="#app-lifecycle">App lifecycle</a>, Python will be included in the
app as a dynamic <code class="docutils literal notranslate"><span class="pre">libpython3.x.so</span></code> library which can be loaded into an app
using <code class="docutils literal notranslate"><span class="pre">dlopen</span></code>.</p>
<p>Unlike Linux, Android does not implicitly use a dlopened library to resolve
relocations in subsequently-loaded libraries, <a class="reference external" href="https://github.com/android/ndk/issues/1244#issuecomment-620310397">even if RTLD_GLOBAL is used</a>. All
Python extension modules must therefore be explicitly linked against
<code class="docutils literal notranslate"><span class="pre">libpython3.x.so</span></code> when building for Android.</p>
<p>An extension module linked against <code class="docutils literal notranslate"><span class="pre">libpython3.x.so</span></code> cannot be loaded 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> library will not be supported on Android.
This is the same pattern used by CPython on Windows.</p>
<p>This approach also allows using the <code class="docutils literal notranslate"><span class="pre">-Wl,--no-undefined</span></code> option to detect
missing symbols at build time, which can be a significant time-saver.</p>
<p>Unlike iOS, Android allows dynamic libraries to be loaded from any location, so
a directory tree containing co-located .py, .pyc and .so files can be handled by
Pythons standard importer.</p>
</section>
<section id="standard-library">
<h3><a class="toc-backref" href="#standard-library" role="doc-backlink">Standard library</a></h3>
<section id="unsupported-modules">
<h4><a class="toc-backref" href="#unsupported-modules" role="doc-backlink">Unsupported modules</a></h4>
<p>A number of standard library modules will not be supported on Android because
the underlying C APIs are not available:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">curses</span></code> and <code class="docutils literal notranslate"><span class="pre">readline</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">dbm.gnu</span></code> and <code class="docutils literal notranslate"><span class="pre">dbm.ndbm</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">grp</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">multiprocessing</span></code> although subprocesses in general are allowed (see <a class="reference internal" href="#app-lifecycle">App
lifecycle</a>), Android does not support any part of the <a class="reference external" href="https://man7.org/linux/man-pages/man7/sysvipc.7.html">System V IPC API</a>.</li>
<li><code class="docutils literal notranslate"><span class="pre">tkinter</span></code> and <code class="docutils literal notranslate"><span class="pre">turtle</span></code> these would require an Android build of Tk
itself, which is not officially supported.</li>
</ul>
</section>
<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 return <code class="docutils literal notranslate"><span class="pre">&quot;android&quot;</span></code>. Although Android is based on Linux,
it differs in enough significant ways that a separate name is justified.</p>
<p>When embedded in an Android app, the C-level stdio streams are not connected to
anything. So in this mode, <code class="docutils literal notranslate"><span class="pre">sys.stdout</span></code> and <code class="docutils literal notranslate"><span class="pre">sys.stderr</span></code> will be redirected
to the system <a class="reference external" href="https://developer.android.com/studio/debug/logcat">Logcat</a>,
which can be viewed with the Android development tools. <code class="docutils literal notranslate"><span class="pre">sys.stdin</span></code> will
always return EOF.</p>
</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>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;Android&quot;</span></code>, instead of the default <code class="docutils literal notranslate"><span class="pre">&quot;Linux&quot;</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">platform.release()</span></code> - Android version number, as a string (e.g. <code class="docutils literal notranslate"><span class="pre">&quot;14&quot;</span></code>),
instead of the Linux kernel version</li>
</ul>
<p>In addition, a <code class="docutils literal notranslate"><span class="pre">platform.android_ver()</span></code> method will be added, which returns a
namedtuple containing the following:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">release</span></code> - Android version of the device, as a string (e.g. <code class="docutils literal notranslate"><span class="pre">&quot;14&quot;</span></code>)</li>
<li><code class="docutils literal notranslate"><span class="pre">api_level</span></code> - <a class="reference internal" href="#os-versions"><span class="std std-ref">API level</span></a> of the device, as an
integer (e.g. <code class="docutils literal notranslate"><span class="pre">34</span></code>)</li>
<li><code class="docutils literal notranslate"><span class="pre">manufacturer</span></code> - <a class="reference external" href="https://developer.android.com/reference/android/os/Build#MANUFACTURER">manufacturer</a> of
the device, as a string (e.g. <code class="docutils literal notranslate"><span class="pre">&quot;Google&quot;</span></code>)</li>
<li><code class="docutils literal notranslate"><span class="pre">model</span></code> - <a class="reference external" href="https://developer.android.com/reference/android/os/Build#MODEL">model name</a> of the
device, as a string (e.g. <code class="docutils literal notranslate"><span class="pre">&quot;Pixel</span> <span class="pre">7&quot;</span></code>)</li>
<li><code class="docutils literal notranslate"><span class="pre">device</span></code> - <a class="reference external" href="https://developer.android.com/reference/android/os/Build#DEVICE">device name</a> of the
device, as a string (e.g. <code class="docutils literal notranslate"><span class="pre">&quot;panther&quot;</span></code>)</li>
<li><code class="docutils literal notranslate"><span class="pre">is_emulator</span></code> - <code class="docutils literal notranslate"><span class="pre">True</span></code> if the device is an emulator; <code class="docutils literal notranslate"><span class="pre">False</span></code> if its a
physical device.</li>
</ul>
<p>Which one of <code class="docutils literal notranslate"><span class="pre">model</span></code> and <code class="docutils literal notranslate"><span class="pre">device</span></code> is more likely to be unique, and which one
is more likely to resemble the marketing name, varies between different
manufacturers.</p>
</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;Linux&quot;</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">release</span></code> - The Linux kernel version (e.g.
<code class="docutils literal notranslate"><span class="pre">&quot;5.10.157-android13-4-00003-gdfb1120f912b-ab10994928&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>
<section id="ci-resources">
<h3><a class="toc-backref" href="#ci-resources" role="doc-backlink">CI resources</a></h3>
<p>Since Android emulators and physical devices use the same ABI, and come with
identical or very similar operating system binaries, testing on emulators will
be adequate. x86_64 emulators can be run on Linux, macOS or Windows, but ARM64
emulators are only supported on ARM64 Macs.</p>
<p>Anaconda <a class="reference external" href="https://discuss.python.org/t/pep-738-adding-android-as-a-supported-platform/40975/20">has offered</a>
to provide physical hardware to run Android buildbots. These will include both
Linux x86_64 and macOS ARM64 machines, which would cover both supported runtime
architectures and both supported build platforms.</p>
<p>CPython does not currently test Tier 3 platforms on GitHub Actions, but if this
ever changes, their Linux and macOS runners are also able to host Android
emulators. macOS ARM64 runners have been free to all public repositories
<a class="reference external" href="https://github.blog/changelog/2024-01-30-github-actions-introducing-the-new-m1-macos-runner-available-to-open-source/">since January 2024</a>.</p>
</section>
<section id="packaging">
<h3><a class="toc-backref" href="#packaging" role="doc-backlink">Packaging</a></h3>
<p>Android wheels will use tags in the format <code class="docutils literal notranslate"><span class="pre">android_&lt;api-level&gt;_&lt;abi&gt;</span></code>. For
example:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">android_21_arm64_v8a</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">android_21_x86_64</span></code></li>
</ul>
<p>For the meaning of <code class="docutils literal notranslate"><span class="pre">&lt;api-level&gt;</span></code>, see <a class="reference internal" href="#id1">OS versions</a>. In the context of
the wheel tag, it indicates the minimum Android version that was selected when
the wheel was compiled. Installation tools such as pip should interpret this in
a similar way to the existing macOS tags, i.e. an app with a minimum API level
of N can incorporate wheels tagged with API level N or older.</p>
<p>This format originates from the Chaquopy project, which currently maintains a
<a class="reference external" href="https://chaquo.com/pypi-13.1/">wheel repository</a> with tags varying between
API levels 16 and 21.</p>
<p>However, relying on a small group of Android enthusiasts to build the whole
Python ecosystem is not a scalable solution. Until prominent libraries routinely
release their own Android wheels, the ability of the community to adopt
Python on Android will be limited.</p>
<p>Therefore, it will be necessary to clearly document how projects can add Android
builds to their CI and release tooling. Adding Android 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>
<p>The Android wheel tag format should also be added to the list of tags accepted
by PyPI.</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 the two supported Android ABIs. Autoconf
already identifies them with the following triplets:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">aarch64-linux-android</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">x86_64-linux-android</span></code></li>
</ul>
<p>Petr Viktorin will serve as the initial core team contact for these ABIs.</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. However, 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>
</section>
<section id="security-implications">
<h2><a class="toc-backref" href="#security-implications" role="doc-backlink">Security Implications</a></h2>
<p>Adding a new platform does not add any new 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 relate to two groups of developers.</p>
<p>First, developers of <em>apps</em> need to know how to build Python into an Android
app, along with their own Python code and any supporting packages, and how to
use them all at runtime. The documentation will cover this in a similar form to
the existing <a class="reference external" href="https://docs.python.org/3/using/windows.html#the-embeddable-package">Windows embeddable package</a>.
However, it will recommend most developers to use higher-level tools such as
<a class="reference external" href="https://briefcase.readthedocs.io/en/stable/">Briefcase</a>,
<a class="reference external" href="https://chaquo.com/chaquopy/">Chaquopy</a> and <a class="reference external" href="https://buildozer.readthedocs.io/en/latest/">Buildozer</a>, all of which already have
comprehensive documentation.</p>
<p>Second, developers of <em>packages</em> with binary components need to know how to
build and release them for Android (see <a class="reference internal" href="#packaging">Packaging</a>).</p>
</section>
<section id="reference-implementation">
<h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2>
<p>The <a class="reference external" href="https://github.com/chaquo/chaquopy/tree/master/target">Chaquopy repository</a> contains a reference
patch and build scripts. These will have to be decoupled from the other
components of Chaquopy before they can be upstreamed.</p>
<p><a class="reference external" href="https://briefcase.readthedocs.org">Briefcase</a> provides a reference
implementation of code to execute test suites on Android devices and emulators.
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 Android emulator using GitHub
Actions.</p>
</section>
<section id="rejected-ideas">
<h2><a class="toc-backref" href="#rejected-ideas" role="doc-backlink">Rejected Ideas</a></h2>
<p>The following changes were made to the original specification of
<code class="docutils literal notranslate"><span class="pre">platform.android_ver()</span></code>:</p>
<ul class="simple">
<li>The <code class="docutils literal notranslate"><span class="pre">min_api_level</span></code> field was removed, because unlike all the other fields,
it isnt a property of the current device. This information is still available
from the pre-existing function <code class="docutils literal notranslate"><span class="pre">sys.getandroidapilevel()</span></code>.</li>
<li>The <code class="docutils literal notranslate"><span class="pre">is_emulator</span></code> field was added, since experience during testing showed
that some issues were emulator-specific.</li>
</ul>
</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-0738.rst">https://github.com/python/peps/blob/main/peps/pep-0738.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0738.rst">2024-10-07 17:43:06 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="#general">General</a></li>
<li><a class="reference internal" href="#os-versions">OS versions</a></li>
<li><a class="reference internal" href="#development-tools">Development tools</a></li>
<li><a class="reference internal" href="#architectures">Architectures</a></li>
<li><a class="reference internal" href="#app-lifecycle">App lifecycle</a></li>
</ul>
</li>
<li><a class="reference internal" href="#specification">Specification</a><ul>
<li><a class="reference internal" href="#scope-of-work">Scope of work</a></li>
<li><a class="reference internal" href="#linkage">Linkage</a></li>
<li><a class="reference internal" href="#standard-library">Standard library</a><ul>
<li><a class="reference internal" href="#unsupported-modules">Unsupported modules</a></li>
<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>
</ul>
</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></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-0738.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>