summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalcolm Smith <smith@chaquo.com>2024-03-11 19:25:39 (GMT)
committerGitHub <noreply@github.com>2024-03-11 19:25:39 (GMT)
commit872c0714fcdc168ce4a69bdd0346f2d5dd488ec2 (patch)
tree84934c17e5561cc36d337d83b436fcc5bb40fd88
parent9f983e00ec55b87a098a4c8229fe5bb9acb9f3ac (diff)
downloadcpython-872c0714fcdc168ce4a69bdd0346f2d5dd488ec2.zip
cpython-872c0714fcdc168ce4a69bdd0346f2d5dd488ec2.tar.gz
cpython-872c0714fcdc168ce4a69bdd0346f2d5dd488ec2.tar.bz2
gh-71052: Change Android's `sys.platform` from "linux" to "android"
Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
-rw-r--r--Doc/library/sys.rst45
-rw-r--r--Lib/ctypes/__init__.py2
-rw-r--r--Lib/multiprocessing/util.py6
-rw-r--r--Lib/shutil.py3
-rw-r--r--Lib/test/support/__init__.py2
-rw-r--r--Lib/test/support/os_helper.py2
-rw-r--r--Lib/test/test_asyncio/test_subprocess.py3
-rw-r--r--Lib/test/test_c_locale_coercion.py21
-rw-r--r--Lib/test/test_fcntl.py4
-rw-r--r--Lib/test/test_logging.py4
-rw-r--r--Lib/test/test_mmap.py2
-rw-r--r--Lib/test/test_os.py7
-rw-r--r--Lib/test/test_resource.py2
-rw-r--r--Lib/test/test_socket.py17
-rw-r--r--Lib/test/test_ssl.py2
-rw-r--r--Lib/test/test_sys.py5
-rw-r--r--Lib/test/test_sysconfig.py22
-rw-r--r--Lib/test/test_tarfile.py2
-rw-r--r--Lib/test/test_time.py2
-rw-r--r--Lib/uuid.py2
-rw-r--r--Misc/NEWS.d/next/Build/2024-03-01-16-44-19.gh-issue-71052.Hs-9EP.rst1
-rw-r--r--Misc/platform_triplet.c14
-rwxr-xr-xconfigure1
-rw-r--r--configure.ac1
24 files changed, 94 insertions, 78 deletions
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index 380ba10..087a345 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -1367,47 +1367,42 @@ always available.
.. data:: platform
- This string contains a platform identifier that can be used to append
- platform-specific components to :data:`sys.path`, for instance.
-
- For Unix systems, except on Linux and AIX, this is the lowercased OS name as
- returned by ``uname -s`` with the first part of the version as returned by
- ``uname -r`` appended, e.g. ``'sunos5'`` or ``'freebsd8'``, *at the time
- when Python was built*. Unless you want to test for a specific system
- version, it is therefore recommended to use the following idiom::
-
- if sys.platform.startswith('freebsd'):
- # FreeBSD-specific code here...
- elif sys.platform.startswith('linux'):
- # Linux-specific code here...
- elif sys.platform.startswith('aix'):
- # AIX-specific code here...
-
- For other systems, the values are:
+ A string containing a platform identifier. Known values are:
================ ===========================
System ``platform`` value
================ ===========================
AIX ``'aix'``
+ Android ``'android'``
Emscripten ``'emscripten'``
+ iOS ``'ios'``
Linux ``'linux'``
- WASI ``'wasi'``
+ macOS ``'darwin'``
Windows ``'win32'``
Windows/Cygwin ``'cygwin'``
- macOS ``'darwin'``
+ WASI ``'wasi'``
================ ===========================
+ On Unix systems not listed in the table, the value is the lowercased OS name
+ as returned by ``uname -s``, with the first part of the version as returned by
+ ``uname -r`` appended, e.g. ``'sunos5'`` or ``'freebsd8'``, *at the time
+ when Python was built*. Unless you want to test for a specific system
+ version, it is therefore recommended to use the following idiom::
+
+ if sys.platform.startswith('freebsd'):
+ # FreeBSD-specific code here...
+
.. versionchanged:: 3.3
On Linux, :data:`sys.platform` doesn't contain the major version anymore.
- It is always ``'linux'``, instead of ``'linux2'`` or ``'linux3'``. Since
- older Python versions include the version number, it is recommended to
- always use the ``startswith`` idiom presented above.
+ It is always ``'linux'``, instead of ``'linux2'`` or ``'linux3'``.
.. versionchanged:: 3.8
On AIX, :data:`sys.platform` doesn't contain the major version anymore.
- It is always ``'aix'``, instead of ``'aix5'`` or ``'aix7'``. Since
- older Python versions include the version number, it is recommended to
- always use the ``startswith`` idiom presented above.
+ It is always ``'aix'``, instead of ``'aix5'`` or ``'aix7'``.
+
+ .. versionchanged:: 3.13
+ On Android, :data:`sys.platform` now returns ``'android'`` rather than
+ ``'linux'``.
.. seealso::
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py
index d54ee05..f63e31a 100644
--- a/Lib/ctypes/__init__.py
+++ b/Lib/ctypes/__init__.py
@@ -468,7 +468,7 @@ pydll = LibraryLoader(PyDLL)
if _os.name == "nt":
pythonapi = PyDLL("python dll", None, _sys.dllhandle)
-elif hasattr(_sys, "getandroidapilevel"):
+elif _sys.platform == "android":
pythonapi = PyDLL("libpython%d.%d.so" % _sys.version_info[:2])
elif _sys.platform == "cygwin":
pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py
index 3287185..75dde02 100644
--- a/Lib/multiprocessing/util.py
+++ b/Lib/multiprocessing/util.py
@@ -102,11 +102,7 @@ def log_to_stderr(level=None):
# Abstract socket support
def _platform_supports_abstract_sockets():
- if sys.platform == "linux":
- return True
- if hasattr(sys, 'getandroidapilevel'):
- return True
- return False
+ return sys.platform in ("linux", "android")
def is_abstract_socket_namespace(address):
diff --git a/Lib/shutil.py b/Lib/shutil.py
index c19ea06..f8be82d 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -47,7 +47,8 @@ else:
COPY_BUFSIZE = 1024 * 1024 if _WINDOWS else 64 * 1024
# This should never be removed, see rationale in:
# https://bugs.python.org/issue43743#msg393429
-_USE_CP_SENDFILE = hasattr(os, "sendfile") and sys.platform.startswith("linux")
+_USE_CP_SENDFILE = (hasattr(os, "sendfile")
+ and sys.platform.startswith(("linux", "android")))
_HAS_FCOPYFILE = posix and hasattr(posix, "_fcopyfile") # macOS
# CMD defaults in Windows 10
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 505d4be..af43446 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -520,7 +520,7 @@ MS_WINDOWS = (sys.platform == 'win32')
# Is not actually used in tests, but is kept for compatibility.
is_jython = sys.platform.startswith('java')
-is_android = hasattr(sys, 'getandroidapilevel')
+is_android = sys.platform == "android"
if sys.platform not in {"win32", "vxworks", "ios", "tvos", "watchos"}:
unix_shell = '/system/bin/sh' if is_android else '/bin/sh'
diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py
index ffa5fc5..8071c24 100644
--- a/Lib/test/support/os_helper.py
+++ b/Lib/test/support/os_helper.py
@@ -612,7 +612,7 @@ class FakePath:
def fd_count():
"""Count the number of open file descriptors.
"""
- if sys.platform.startswith(('linux', 'freebsd', 'emscripten')):
+ if sys.platform.startswith(('linux', 'android', 'freebsd', 'emscripten')):
fd_path = "/proc/self/fd"
elif sys.platform == "darwin":
fd_path = "/dev/fd"
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
index 890c0ac..cf1a198 100644
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -480,7 +480,8 @@ class SubprocessMixin:
self.assertEqual(output, None)
self.assertEqual(exitcode, 0)
- @unittest.skipIf(sys.platform != 'linux', "Don't have /dev/stdin")
+ @unittest.skipIf(sys.platform not in ('linux', 'android'),
+ "Don't have /dev/stdin")
def test_devstdin_input(self):
async def devstdin_input(message):
diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py
index 7334a32..e4b0b8c 100644
--- a/Lib/test/test_c_locale_coercion.py
+++ b/Lib/test/test_c_locale_coercion.py
@@ -26,17 +26,16 @@ EXPECT_COERCION_IN_DEFAULT_LOCALE = True
TARGET_LOCALES = ["C.UTF-8", "C.utf8", "UTF-8"]
# Apply some platform dependent overrides
-if sys.platform.startswith("linux"):
- if support.is_android:
- # Android defaults to using UTF-8 for all system interfaces
- EXPECTED_C_LOCALE_STREAM_ENCODING = "utf-8"
- EXPECTED_C_LOCALE_FS_ENCODING = "utf-8"
- else:
- # Linux distros typically alias the POSIX locale directly to the C
- # locale.
- # TODO: Once https://bugs.python.org/issue30672 is addressed, we'll be
- # able to check this case unconditionally
- EXPECTED_C_LOCALE_EQUIVALENTS.append("POSIX")
+if sys.platform == "android":
+ # Android defaults to using UTF-8 for all system interfaces
+ EXPECTED_C_LOCALE_STREAM_ENCODING = "utf-8"
+ EXPECTED_C_LOCALE_FS_ENCODING = "utf-8"
+elif sys.platform.startswith("linux"):
+ # Linux distros typically alias the POSIX locale directly to the C
+ # locale.
+ # TODO: Once https://bugs.python.org/issue30672 is addressed, we'll be
+ # able to check this case unconditionally
+ EXPECTED_C_LOCALE_EQUIVALENTS.append("POSIX")
elif sys.platform.startswith("aix"):
# AIX uses iso8859-1 in the C locale, other *nix platforms use ASCII
EXPECTED_C_LOCALE_STREAM_ENCODING = "iso8859-1"
diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py
index 8b4ed4a..5fae0de 100644
--- a/Lib/test/test_fcntl.py
+++ b/Lib/test/test_fcntl.py
@@ -129,8 +129,8 @@ class TestFcntl(unittest.TestCase):
fcntl.fcntl(BadFile(INT_MIN - 1), fcntl.F_SETFL, os.O_NONBLOCK)
@unittest.skipIf(
- any(platform.machine().startswith(name) for name in {"arm", "aarch"})
- and platform.system() in {"Linux", "Android"},
+ platform.machine().startswith(("arm", "aarch"))
+ and platform.system() in ("Linux", "Android"),
"ARM Linux returns EINVAL for F_NOTIFY DN_MULTISHOT")
def test_fcntl_64_bit(self):
# Issue #1309352: fcntl shouldn't fail when the third arg fits in a
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 1dfad6e..32bb517 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -603,7 +603,7 @@ class HandlerTest(BaseTest):
def test_builtin_handlers(self):
# We can't actually *use* too many handlers in the tests,
# but we can try instantiating them with various options
- if sys.platform in ('linux', 'darwin'):
+ if sys.platform in ('linux', 'android', 'darwin'):
for existing in (True, False):
fn = make_temp_file()
if not existing:
@@ -667,7 +667,7 @@ class HandlerTest(BaseTest):
(logging.handlers.RotatingFileHandler, (pfn, 'a')),
(logging.handlers.TimedRotatingFileHandler, (pfn, 'h')),
)
- if sys.platform in ('linux', 'darwin'):
+ if sys.platform in ('linux', 'android', 'darwin'):
cases += ((logging.handlers.WatchedFileHandler, (pfn, 'w')),)
for cls, args in cases:
h = cls(*args, encoding="utf-8")
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index ac75975..ee86227 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -837,7 +837,7 @@ class MmapTests(unittest.TestCase):
mm.write(b'python')
result = mm.flush()
self.assertIsNone(result)
- if sys.platform.startswith('linux'):
+ if sys.platform.startswith(('linux', 'android')):
# 'offset' must be a multiple of mmap.PAGESIZE on Linux.
# See bpo-34754 for details.
self.assertRaises(OSError, mm.flush, 1, len(b'python'))
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index ae8b405..fc886f9 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -3533,9 +3533,8 @@ class ProgramPriorityTests(unittest.TestCase):
class TestSendfile(unittest.IsolatedAsyncioTestCase):
DATA = b"12345abcde" * 16 * 1024 # 160 KiB
- SUPPORT_HEADERS_TRAILERS = not sys.platform.startswith("linux") and \
- not sys.platform.startswith("solaris") and \
- not sys.platform.startswith("sunos")
+ SUPPORT_HEADERS_TRAILERS = (
+ not sys.platform.startswith(("linux", "android", "solaris", "sunos")))
requires_headers_trailers = unittest.skipUnless(SUPPORT_HEADERS_TRAILERS,
'requires headers and trailers support')
requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
@@ -5256,7 +5255,7 @@ class ForkTests(unittest.TestCase):
else:
assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug")
- @unittest.skipUnless(sys.platform in ("linux", "darwin"),
+ @unittest.skipUnless(sys.platform in ("linux", "android", "darwin"),
"Only Linux and macOS detect this today.")
def test_fork_warns_when_non_python_thread_exists(self):
code = """if 1:
diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py
index 317e7ca..d23d362 100644
--- a/Lib/test/test_resource.py
+++ b/Lib/test/test_resource.py
@@ -138,7 +138,7 @@ class ResourceTest(unittest.TestCase):
self.assertIsInstance(pagesize, int)
self.assertGreaterEqual(pagesize, 0)
- @unittest.skipUnless(sys.platform == 'linux', 'test requires Linux')
+ @unittest.skipUnless(sys.platform in ('linux', 'android'), 'Linux only')
def test_linux_constants(self):
for attr in ['MSGQUEUE', 'NICE', 'RTPRIO', 'RTTIME', 'SIGPENDING']:
with contextlib.suppress(AttributeError):
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index b936e9a..a7e657f 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -1199,8 +1199,8 @@ class GeneralModuleTests(unittest.TestCase):
# I've ordered this by protocols that have both a tcp and udp
# protocol, at least for modern Linuxes.
if (
- sys.platform.startswith(('freebsd', 'netbsd', 'gnukfreebsd'))
- or sys.platform == 'linux'
+ sys.platform.startswith(
+ ('linux', 'android', 'freebsd', 'netbsd', 'gnukfreebsd'))
or is_apple
):
# avoid the 'echo' service on this platform, as there is an
@@ -1218,8 +1218,7 @@ class GeneralModuleTests(unittest.TestCase):
raise OSError
# Try same call with optional protocol omitted
# Issue #26936: Android getservbyname() was broken before API 23.
- if (not hasattr(sys, 'getandroidapilevel') or
- sys.getandroidapilevel() >= 23):
+ if (not support.is_android) or sys.getandroidapilevel() >= 23:
port2 = socket.getservbyname(service)
eq(port, port2)
# Try udp, but don't barf if it doesn't exist
@@ -1577,8 +1576,7 @@ class GeneralModuleTests(unittest.TestCase):
# port can be a string service name such as "http", a numeric
# port number or None
# Issue #26936: Android getaddrinfo() was broken before API level 23.
- if (not hasattr(sys, 'getandroidapilevel') or
- sys.getandroidapilevel() >= 23):
+ if (not support.is_android) or sys.getandroidapilevel() >= 23:
socket.getaddrinfo(HOST, "http")
socket.getaddrinfo(HOST, 80)
socket.getaddrinfo(HOST, None)
@@ -3196,7 +3194,7 @@ class SendmsgStreamTests(SendmsgTests):
# Linux supports MSG_DONTWAIT when sending, but in general, it
# only works when receiving. Could add other platforms if they
# support it too.
- @skipWithClientIf(sys.platform not in {"linux"},
+ @skipWithClientIf(sys.platform not in {"linux", "android"},
"MSG_DONTWAIT not known to work on this platform when "
"sending")
def testSendmsgDontWait(self):
@@ -5634,7 +5632,7 @@ class TestExceptions(unittest.TestCase):
sock.setblocking(False)
-@unittest.skipUnless(sys.platform == 'linux', 'Linux specific test')
+@unittest.skipUnless(sys.platform in ('linux', 'android'), 'Linux specific test')
class TestLinuxAbstractNamespace(unittest.TestCase):
UNIX_PATH_MAX = 108
@@ -5759,7 +5757,8 @@ class TestUnixDomain(unittest.TestCase):
self.addCleanup(os_helper.unlink, path)
self.assertEqual(self.sock.getsockname(), path)
- @unittest.skipIf(sys.platform == 'linux', 'Linux specific test')
+ @unittest.skipIf(sys.platform in ('linux', 'android'),
+ 'Linux behavior is tested by TestLinuxAbstractNamespace')
def testEmptyAddress(self):
# Test that binding empty address fails.
self.assertRaises(OSError, self.sock.bind, "")
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index cdf96c8..489cb5e 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -4914,7 +4914,7 @@ class TestPreHandshakeClose(unittest.TestCase):
pass # closed, protocol error, etc.
def non_linux_skip_if_other_okay_error(self, err):
- if sys.platform == "linux":
+ if sys.platform in ("linux", "android"):
return # Expect the full test setup to always work on Linux.
if (isinstance(err, ConnectionResetError) or
(isinstance(err, OSError) and err.errno == errno.EINVAL) or
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 38dcabd..37c16cd 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -668,7 +668,7 @@ class SysModuleTest(unittest.TestCase):
self.assertEqual(len(info), 3)
self.assertIn(info.name, ('nt', 'pthread', 'pthread-stubs', 'solaris', None))
self.assertIn(info.lock, ('semaphore', 'mutex+cond', None))
- if sys.platform.startswith(("linux", "freebsd")):
+ if sys.platform.startswith(("linux", "android", "freebsd")):
self.assertEqual(info.name, "pthread")
elif sys.platform == "win32":
self.assertEqual(info.name, "nt")
@@ -1101,8 +1101,7 @@ class SysModuleTest(unittest.TestCase):
self.assertEqual(stdout.rstrip(), b"")
self.assertEqual(stderr.rstrip(), b"")
- @unittest.skipUnless(hasattr(sys, 'getandroidapilevel'),
- 'need sys.getandroidapilevel()')
+ @unittest.skipUnless(sys.platform == "android", "Android only")
def test_getandroidapilevel(self):
level = sys.getandroidapilevel()
self.assertIsInstance(level, int)
diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py
index bb87bf0..c8315bb 100644
--- a/Lib/test/test_sysconfig.py
+++ b/Lib/test/test_sysconfig.py
@@ -1,3 +1,5 @@
+import platform
+import re
import unittest
import sys
import os
@@ -516,12 +518,9 @@ class TestSysConfig(unittest.TestCase):
vars = sysconfig.get_config_vars()
self.assertEqual(vars['EXT_SUFFIX'], _imp.extension_suffixes()[0])
- @unittest.skipUnless(sys.platform == 'linux' and
- hasattr(sys.implementation, '_multiarch'),
- 'multiarch-specific test')
- def test_triplet_in_ext_suffix(self):
+ @unittest.skipUnless(sys.platform == 'linux', 'Linux-specific test')
+ def test_linux_ext_suffix(self):
ctypes = import_module('ctypes')
- import platform, re
machine = platform.machine()
suffix = sysconfig.get_config_var('EXT_SUFFIX')
if re.match('(aarch64|arm|mips|ppc|powerpc|s390|sparc)', machine):
@@ -534,6 +533,19 @@ class TestSysConfig(unittest.TestCase):
self.assertTrue(suffix.endswith(expected_suffixes),
f'unexpected suffix {suffix!r}')
+ @unittest.skipUnless(sys.platform == 'android', 'Android-specific test')
+ def test_android_ext_suffix(self):
+ machine = platform.machine()
+ suffix = sysconfig.get_config_var('EXT_SUFFIX')
+ expected_triplet = {
+ "x86_64": "x86_64-linux-android",
+ "i686": "i686-linux-android",
+ "aarch64": "aarch64-linux-android",
+ "armv7l": "arm-linux-androideabi",
+ }[machine]
+ self.assertTrue(suffix.endswith(f"-{expected_triplet}.so"),
+ f"{machine=}, {suffix=}")
+
@unittest.skipUnless(sys.platform == 'darwin', 'OS X-specific test')
def test_osx_ext_suffix(self):
suffix = sysconfig.get_config_var('EXT_SUFFIX')
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index a047780..39541fa 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -1186,7 +1186,7 @@ class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase):
#
# The function returns False if page size is larger than 4 KiB.
# For example, ppc64 uses pages of 64 KiB.
- if sys.platform.startswith("linux"):
+ if sys.platform.startswith(("linux", "android")):
# Linux evidentially has 512 byte st_blocks units.
name = os.path.join(TEMPDIR, "sparse-test")
with open(name, "wb") as fobj:
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
index a0aeea5..fb234b7 100644
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -511,7 +511,7 @@ class TimeTestCase(unittest.TestCase):
def test_thread_time(self):
if not hasattr(time, 'thread_time'):
- if sys.platform.startswith(('linux', 'win')):
+ if sys.platform.startswith(('linux', 'android', 'win')):
self.fail("time.thread_time() should be available on %r"
% (sys.platform,))
else:
diff --git a/Lib/uuid.py b/Lib/uuid.py
index d4e486d..da2f1d5 100644
--- a/Lib/uuid.py
+++ b/Lib/uuid.py
@@ -62,7 +62,7 @@ else:
import platform
_platform_system = platform.system()
_AIX = _platform_system == 'AIX'
- _LINUX = _platform_system == 'Linux'
+ _LINUX = _platform_system in ('Linux', 'Android')
_MAC_DELIM = b':'
_MAC_OMITS_LEADING_ZEROES = False
diff --git a/Misc/NEWS.d/next/Build/2024-03-01-16-44-19.gh-issue-71052.Hs-9EP.rst b/Misc/NEWS.d/next/Build/2024-03-01-16-44-19.gh-issue-71052.Hs-9EP.rst
new file mode 100644
index 0000000..187475f
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2024-03-01-16-44-19.gh-issue-71052.Hs-9EP.rst
@@ -0,0 +1 @@
+Change Android's :data:`sys.platform` from ``"linux"`` to ``"android"``.
diff --git a/Misc/platform_triplet.c b/Misc/platform_triplet.c
index 0b912e3..06b03bf 100644
--- a/Misc/platform_triplet.c
+++ b/Misc/platform_triplet.c
@@ -12,8 +12,20 @@
#undef powerpc
#undef sparc
#undef unix
+
#if defined(__ANDROID__)
- # Android is not a multiarch system.
+# if defined(__x86_64__)
+PLATFORM_TRIPLET=x86_64-linux-android
+# elif defined(__i386__)
+PLATFORM_TRIPLET=i686-linux-android
+# elif defined(__aarch64__)
+PLATFORM_TRIPLET=aarch64-linux-android
+# elif defined(__arm__)
+PLATFORM_TRIPLET=arm-linux-androideabi
+# else
+# error unknown Android platform
+# endif
+
#elif defined(__linux__)
/*
* BEGIN of Linux block
diff --git a/configure b/configure
index 5e8c9af..267a518 100755
--- a/configure
+++ b/configure
@@ -4071,6 +4071,7 @@ then
case $MACHDEP in
aix*) MACHDEP="aix";;
+ linux-android*) MACHDEP="android";;
linux*) MACHDEP="linux";;
cygwin*) MACHDEP="cygwin";;
darwin*) MACHDEP="darwin";;
diff --git a/configure.ac b/configure.ac
index e615259..681d081 100644
--- a/configure.ac
+++ b/configure.ac
@@ -362,6 +362,7 @@ then
case $MACHDEP in
aix*) MACHDEP="aix";;
+ linux-android*) MACHDEP="android";;
linux*) MACHDEP="linux";;
cygwin*) MACHDEP="cygwin";;
darwin*) MACHDEP="darwin";;