Skip to content

fix: platform.system() on Android for Python 3.13+#2992

Merged
messense merged 5 commits intoPyO3:mainfrom
thunder-coding:python313-termux
Feb 13, 2026
Merged

fix: platform.system() on Android for Python 3.13+#2992
messense merged 5 commits intoPyO3:mainfrom
thunder-coding:python313-termux

Conversation

@thunder-coding
Copy link
Contributor

@thunder-coding thunder-coding commented Feb 13, 2026

Python from 3.13 onwards supports Android as an official platform. As a part of this official support, there were a bunch of changes including platform.system() returning "Android" and sys.platform being "android" instead of "Linux" and "linux" on earlier versions. This is a breaking change.

Also try to be backwards compatible while running on Android for older python versions in environments like Termux

This maturin bug was found as a part of testing of builds of python packages for Termux as part of Python 3.13 migration. Downstream Python distribution update PR: termux/termux-packages#27739

Ideally we would like to ensure that get_python_os() returns "linux" for Python versions <= 3.12, but that'd require additional work in supplying python version to get_python_os(), but that'd complicate some things. This works well enough, and shouldn't be necessary in future when Python >= 3.13 becomes the standard target by most (which should ideally happen soon since upstream Python is supporting Android from this version).

My analysis of maturin reveal that get_python_os() returning "android" shouldn't cause any side effects for Python <= 3.12 on Android.

Issue also reported to maturin in #2945

Partially based of off work by @robertkirkman in the linked issue. Further fixup was done to ensure suitability for upstream acceptance.

Ref: python/cpython#116215

CC @mhsmith Android support for Python

Python from 3.13 onwards supports Android as an official platform. As a
part of this official support, there were a bunch of changes including
`platform.system()` returning "Android" and `sys.platform` being
"android" instead of "Linux" and "linux" on earlier versions. This is a
breaking change.

Also try to be backwards compatible while running on Android for older
python versions in environments like Termux

This maturin bug was found as a part of testing of builds of python
packages for Termux as part of Python 3.13 migration. Downstream Python
distribution update PR: termux/termux-packages#27739

Ideally we would like to ensure that get_python_os() returns "linux" for
Python versions <= 3.12, but that'd require additional work in supplying
python version to get_python_os(), but that'd complicate some things.
This works well enough, and shouldn't be necessary in future when Python
>= 3.13 becomes the standard target by most (which should ideally happen
soon since upstream Python is supporting Android from this version).

My analysis of maturin reveal that get_python_os() returning "android"
shouldn't cause any effects on Android targets that do need to be
patched.

Issue also reported to maturin in PyO3#2945

Partially based of off work by @robertkirkman in the linked issue.
Further fixup was done to ensure suitability for upstream acceptance.

Ref: python/cpython#116215
@robertkirkman
Copy link

My analysis of maturin reveal that get_python_os() returning "android" shouldn't cause any effects on Android targets that do need to be patched.

Do you mean "don't need to be patched" rather than "do need to be patched" here, or did you really mean to say "do need to be patched"?

@thunder-coding
Copy link
Contributor Author

Do you mean "don't need to be patched" rather than "do need to be patched" here, or did you really mean to say "do need to be patched"?

I meant to say that. get_python_os() returning "android" instead of "linux" for Python <= 3.12 should not be an issue in maturin's codebase as far as I can see. Apologies for the confusing sentence, English is a funny language which can be difficult to grasp depending on context :)

@robertkirkman
Copy link

get_python_os() returning "android" instead of "linux" for Python <= 3.12 should not be an issue in maturin's codebase as far as I can see

what's confusing me is that Maturin doesn't need to be patched when running on Python 3.12 on Android, so what did you mean is the thing being patched?

@thunder-coding
Copy link
Contributor Author

what's confusing me is that Maturin doesn't need to be patched when running on Python 3.12 on Android, so what did you mean is the thing being patched?

Yes Maturin doesn't need to be patched for Python 3.12 on Android. But this change does cause get_python_os to behave differently on android than the code comments above. on Android it will not return the value of platform.system() for Python <= 3.12. This value is compared against the Python runtime detected when maturin is run, and it tries to check if it matches message.system, which doesn't for Python <= 3.12. I was refering to this difference over in my comment. Seems like I should have worded that a bit more clearly

@robertkirkman
Copy link

robertkirkman commented Feb 13, 2026

Thanks for explaining, that makes sense. If I understand now, this means that you could say 'get_python_os() returning "android" shouldn't cause any effects on Android targets that do need to be granted an exception in fun_with_abiflags() along with these changes' instead of 'get_python_os() returning "android" shouldn't cause any effects on Android targets that do need to be patched'?

Edit: new description in the PR is good

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for Python 3.13+ on Android, where platform.system() returns "Android" instead of "Linux". It introduces a new Os::Android enum variant and handles backwards compatibility for Python versions <= 3.12 on Android (such as in Termux environments) where Python still reports "Linux".

Changes:

  • Introduced Os::Android as a separate operating system variant instead of treating Android as a Linux variant
  • Updated platform tag validation to recognize Android as a distinct platform with its specific architecture mappings
  • Added backwards compatibility logic to allow Python <= 3.12 on Android to report "linux" from platform.system() while targeting Android

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/target/mod.rs Adds Os::Android enum variant with Display implementation, architecture support, platform detection from target triple environment, and helper method is_android()
src/target/pypi_tags.rs Changes Android detection from string-based triple check to enum-based Os::Android match
src/python_interpreter/mod.rs Implements backwards compatibility for Python 3.12 and earlier on Android by allowing "linux" from platform.system() when target is Android
src/python_interpreter/config.rs Includes Android in the platforms that use the standard extension suffix format (alongside Linux, macOS, and Hurd)

@messense messense merged commit a23a6b5 into PyO3:main Feb 13, 2026
45 checks passed
@robertkirkman
Copy link

@thunder-coding unfortunately, after this PR, this command

scripts/run-docker.sh ./build-package.sh -I -f ruff

has this error for me:

📦 Built wheel to /home/builder/.termux-build/ruff/src/target/wheels/ruff-0.15.2-py3-none-android_6_12_47_gentoo_dist_x86_64.whl
mv: cannot stat 'target/wheels/ruff-0.15.2-py3-none-android_24_arm64_v8a.whl': No such file or directory

it looks like the result from the uname -r command, which can vary greatly by what computer is running Maturin, is getting into the name of the .whl file, but I'm not sure how.

I'm sorry that I don't know how to fix this other than to bisect it to this PR, but I just thought you would want to know.

thunder-coding added a commit to thunder-coding/maturin that referenced this pull request Feb 20, 2026
Follow up of a23a6b5 (PyO3#2992)

It is recommended to go through the commit message linked above before
trying to decode this. Since earlier Android was detected as Os::Linux,
this extra condition was required, this should no longer be the case. So
clean it up

Issue originally reported in PyO3#2992 (comment)
thunder-coding added a commit to thunder-coding/maturin that referenced this pull request Feb 20, 2026
Follow up of a23a6b5 (PyO3#2992)

It is recommended to go through the commit message linked above before
trying to decode this. Since earlier Android was detected as Os::Linux,
this extra condition was required, this should no longer be the case. So
clean it up

A workaround is to set
_PYTHON_HOST_PLATFORM=android_{ANDROID_API_LEVEL}_{ANDROID_ARCH} for
build scripts that expect that wheels are named in a certain pattern

Issue originally reported in PyO3#2992 (comment)
messense pushed a commit that referenced this pull request Feb 20, 2026
Follow up of a23a6b5 (#2992)

It is recommended to go through the commit message linked above before
trying to decode this. Since earlier Android was detected as Os::Linux,
this extra condition was required, this should no longer be the case. So
clean it up

A workaround is to set
`_PYTHON_HOST_PLATFORM=android_{ANDROID_API_LEVEL}_{ANDROID_ARCH}` for
build scripts that expect that wheels are named in a certain pattern

Issue originally reported in
#2992 (comment)

CC @robertkirkman

Additionally, I'd appreciate if we can get a patch release with this
commit for maturin, as this issue is causing our CI to fail for Python
packages for Termux
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants