Skip to content

Add support for Android and iOS platforms#12220

Open
timrid wants to merge 5 commits intoaio-libs:masterfrom
timrid:android-and-ios-wheels
Open

Add support for Android and iOS platforms#12220
timrid wants to merge 5 commits intoaio-libs:masterfrom
timrid:android-and-ios-wheels

Conversation

@timrid
Copy link

@timrid timrid commented Mar 9, 2026

What do these changes do?

This PR adds support for Android and iOS platforms.

Since Python 3.13, Android (PEP738) and iOS (PEP730) are officially supported. In addition, Android and iOS have been supported since cibuildwheel v3.1. This makes it very easy to build wheels for Android and iOS.

PyPI now also supports uploading Android and iOS wheels (see pypi/warehouse#17559).

At https://beeware.org/mobile-wheels/, you can find an overview of all binary packages available for Android and iOS. Currently, there aren't that many, but I hope aiohttp will appear there soon :)

Are there changes in behavior for the user?

No.

Is it a substantial burden for the maintainers to support this?

Most of the compiling work is taken care of by cibuildwheel. However, the pytests are currently not run on Android and iOS, so it is theoretically possible that there may be problems during runtime on Android/iOS.

In principle, cibuildwheel also offers the option of running the pytests on Android and iOS using test-command, but this requires the Android emulator/iOS simulator to be started in the CI, which significantly slows down the building of the wheels. In addition, test-command is not currently used, which would require more adjustments to the CI. Therefore, I have decided not to use it for now and have only manually performed a very simple “smoke test” in a briefcase application to check whether the wheel is importable and usable.

Related issue number

Fixes #11750

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
  • Add a new news fragment into the CHANGES/ folder

@timrid timrid requested review from asvetlov and webknjaz as code owners March 9, 2026 20:03
@psf-chronographer psf-chronographer bot added the bot:chronographer:provided There is a change note present in this PR label Mar 9, 2026
@codspeed-hq
Copy link

codspeed-hq bot commented Mar 9, 2026

Merging this PR will not alter performance

✅ 59 untouched benchmarks


Comparing timrid:android-and-ios-wheels (257947d) with master (d9f9207)

Open in CodSpeed

@Dreamsorcerer
Copy link
Member

Therefore, I have decided not to use it for now and have only manually performed a very simple “smoke test” in a briefcase application to check whether the wheel is importable and usable.

Have you tested a simple server app too?

@timrid
Copy link
Author

timrid commented Mar 9, 2026

Have you tested a simple server app too?

Not yet, but I can also do a simple test for this. But it will take a few days.

@codecov
Copy link

codecov bot commented Mar 9, 2026

Codecov Report

❌ Patch coverage is 80.70175% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.08%. Comparing base (d9f9207) to head (257947d).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
tests/test_web_sendfile_functional.py 35.71% 5 Missing and 4 partials ⚠️
tests/test_web_functional.py 66.66% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #12220      +/-   ##
==========================================
- Coverage   99.11%   99.08%   -0.03%     
==========================================
  Files         130      130              
  Lines       45373    45420      +47     
  Branches     2397     2401       +4     
==========================================
+ Hits        44970    45006      +36     
- Misses        271      278       +7     
- Partials      132      136       +4     
Flag Coverage Δ
CI-GHA 98.94% <80.70%> (-0.03%) ⬇️
OS-Linux 98.68% <80.70%> (-0.03%) ⬇️
OS-Windows 96.95% <77.19%> (-0.03%) ⬇️
OS-macOS 97.84% <80.70%> (-0.03%) ⬇️
Py-3.10.11 97.39% <80.70%> (-0.03%) ⬇️
Py-3.10.19 97.21% <80.70%> (-0.68%) ⬇️
Py-3.10.20 97.73% <80.70%> (-0.17%) ⬇️
Py-3.11.14 97.93% <80.70%> (-0.16%) ⬇️
Py-3.11.15 97.40% <80.70%> (-0.69%) ⬇️
Py-3.11.9 97.60% <80.70%> (-0.03%) ⬇️
Py-3.12.10 97.68% <80.70%> (-0.03%) ⬇️
Py-3.12.12 98.02% <80.70%> (-0.16%) ⬇️
Py-3.12.13 97.50% <80.70%> (-0.69%) ⬇️
Py-3.13.12 98.40% <80.70%> (-0.03%) ⬇️
Py-3.14.3 98.47% <80.70%> (-0.03%) ⬇️
Py-3.14.3t 97.47% <80.70%> (-0.03%) ⬇️
Py-pypy3.11.13-7.3.20 97.50% <73.68%> (-0.04%) ⬇️
VM-macos 97.84% <80.70%> (-0.03%) ⬇️
VM-ubuntu 98.68% <80.70%> (-0.03%) ⬇️
VM-windows 96.95% <77.19%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@timrid
Copy link
Author

timrid commented Mar 14, 2026

I now added the unittests for Android and iOS to the CI, to verify that everything is working. To run the unittests I use cibuildwheel, that automatically starts an Android Emulator / iOS Simulator and runs the whole pytests inside this Emulator/Simulator.

The only issue is that the unit tests have some binary dependencies that aren't yet available for Android and iOS. Hopefully this will improve over time, but for now I had to add environment markers to quite a few dependencies and skip the tests that use these dependencies.

Another problem was that pip-compile doesn’t use the environment markers for transitive dependencies as well. Therefore, I had to include some of the transitive dependencies in the *.in files so that I could explicitly set the environment markers there.

Copy link
Member

Choose a reason for hiding this comment

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

This seems a bit messy to maintain. Maybe @webknjaz has a better idea.

cryptography; sys_platform != 'android' and sys_platform != 'ios' # used by trustme
forbiddenfruit; implementation_name == "cpython" and sys_platform != 'android' and sys_platform != 'ios' # used by blockbuster
freezegun
isal; python_version < "3.14" # no wheel for 3.14
Copy link
Member

Choose a reason for hiding this comment

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

The 3.14 check is actually not needed anymore.

Comment on lines +25 to +28
try:
import trustme
except ImportError: # pragma: no cover
pass
Copy link
Member

@Dreamsorcerer Dreamsorcerer Mar 14, 2026

Choose a reason for hiding this comment

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

Shouldn't need this and the importerskip, right?

Comment on lines +120 to +121
trustme = pytest.importorskip("trustme")
return trustme.CA() # type: ignore[no-any-return]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
trustme = pytest.importorskip("trustme")
return trustme.CA() # type: ignore[no-any-return]
if TYPE_CHECKING:
import trustme
else:
trustme = pytest.importorskip("trustme")
return trustme.CA()


try:
import trustme
except ImportError: # pragma: no cover
Copy link
Member

Choose a reason for hiding this comment

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

This should be covered if we need it. If we see the coverage disappear, then we no longer need the except.

Suggested change
except ImportError: # pragma: no cover
except ImportError:



@pytest.mark.skipif(
sys.platform in ("android", "ios"), reason="README.md not supported"
Copy link
Member

Choose a reason for hiding this comment

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

I'm unclear what this reason means?

speedups = [
"aiodns >= 3.3.0",
"Brotli >= 1.2; platform_python_implementation == 'CPython'",
"aiodns >= 3.3.0; sys_platform != 'android' and sys_platform != 'ios'",
Copy link
Member

@Dreamsorcerer Dreamsorcerer Mar 14, 2026

Choose a reason for hiding this comment

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

If you could make a PR to pycares to support this, we could probably get this resolved pretty quick. Unless there's a technical difficulty in supporting these platforms?

isal; python_version < "3.14" and sys_platform != 'android' and sys_platform != 'ios' # no wheel for 3.14
librt; platform_python_implementation != 'PyPy' and sys_platform != 'android' and sys_platform != 'ios' # used by mypy
mypy; implementation_name == "cpython" and sys_platform != 'android' and sys_platform != 'ios'
mypy-extensions; sys_platform != 'android' and sys_platform != 'ios' # used by mypy
Copy link
Member

Choose a reason for hiding this comment

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

In fact, why would we even need these extra dependencies here? If this is pulled in by mypy and we've already excluded mypy, then surely it won't get pulled in..?

Copy link
Member

Choose a reason for hiding this comment

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

Another problem was that pip-compile doesn’t use the environment markers for transitive dependencies as well. Therefore, I had to include some of the transitive dependencies in the *.in files so that I could explicitly set the environment markers there.

CIBW_TEST_REQUIRES: -r requirements/test.txt
CIBW_TEST_SOURCES: setup.cfg tests
CIBW_TEST_COMMAND: >-
python -m pytest -o 'addopts='-v -ra --showlocals -m 'not dev_mode and not autobahn'
Copy link
Member

Choose a reason for hiding this comment

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

This workflow is missing the coverage steps, which is why codecov is complaining.

@Dreamsorcerer Dreamsorcerer added the backport-3.14 Trigger automatic backporting to the 3.14 release branch by Patchback robot label Mar 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-3.14 Trigger automatic backporting to the 3.14 release branch by Patchback robot bot:chronographer:provided There is a change note present in this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build wheels for Android and iOS

2 participants