547 lines
40 KiB
HTML
547 lines
40 KiB
HTML
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="color-scheme" content="light dark">
|
||
<title>PEP 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> » </li>
|
||
<li><a href="../pep-0000/">PEP Index</a> » </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 <smith at chaquo.com></dd>
|
||
<dt class="field-even">Sponsor<span class="colon">:</span></dt>
|
||
<dd class="field-even">Petr Viktorin <encukou at gmail.com></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 doesn’t resemble any other
|
||
Unix.</p>
|
||
<p>However, Android’s 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">Google’s 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 don’t 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 app’s 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
|
||
Python’s 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">"android"</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">"Android"</span></code>, instead of the default <code class="docutils literal notranslate"><span class="pre">"Linux"</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">"14"</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">"14"</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">"Google"</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">"Pixel</span> <span class="pre">7"</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">"panther"</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 it’s 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">"Linux"</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">"5.10.157-android13-4-00003-gdfb1120f912b-ab10994928"</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_<api-level>_<abi></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"><api-level></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 don’t 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 isn’t 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> |