Skip to content

Merge recent changes from main. #311

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 35 commits into from
Jul 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3a7cd86
More updates to USAGE and README (#250)
freakboy3742 Feb 17, 2025
1158013
Bump ncipollo/release-action from 1.15.0 to 1.16.0 (#253)
dependabot[bot] Feb 23, 2025
832d393
Bump actions/upload-artifact from 4.6.0 to 4.6.1 (#254)
dependabot[bot] Feb 23, 2025
aa545e9
Add patch for handling empty simulator lists.
freakboy3742 Feb 25, 2025
c794b06
Bump actions/download-artifact from 4.1.8 to 4.1.9 (#255)
dependabot[bot] Mar 3, 2025
0013ca0
Update patch for Python 3.14.0a6 (#258)
freakboy3742 Mar 18, 2025
ca43143
Bump actions/download-artifact from 4.1.9 to 4.2.1 (#265)
dependabot[bot] Mar 23, 2025
cfd548d
Bump actions/upload-artifact from 4.6.1 to 4.6.2 (#266)
dependabot[bot] Mar 23, 2025
db04fbd
Bump actions/setup-python from 5.4.0 to 5.5.0 (#267)
dependabot[bot] Mar 30, 2025
81428db
Add Python.patch Note to Contributing.md (#271)
johnzhou721 Apr 17, 2025
92d8d95
Add support for visionOS (#270)
johnzhou721 Apr 23, 2025
f8fd686
Fix an iOS reference in testbed cloning. (#272)
johnzhou721 Apr 23, 2025
344aaf6
Update patch to include visionOS plist changes.
freakboy3742 Apr 25, 2025
515625c
visionOS Support and Other Fixes (#276)
johnzhou721 Apr 27, 2025
e29c0fd
Bump actions/setup-python from 5.5.0 to 5.6.0 (#277)
dependabot[bot] Apr 27, 2025
80296f0
Bump actions/download-artifact from 4.2.1 to 4.3.0 (#278)
dependabot[bot] Apr 27, 2025
b5bed64
Ensure base_prefix is set in a cross-venv. (#279)
freakboy3742 May 1, 2025
7a7aad1
Document the Patch Tree Approach. (#281)
johnzhou721 May 4, 2025
6583edf
Update CONTRIBUTING.md for Grammar + Clarity (#282)
johnzhou721 May 4, 2025
a041905
Remove some useless PATHs in Usage.md (#284)
johnzhou721 May 6, 2025
76b7f30
Bump patch to Python 3.14.0b2. (#290)
freakboy3742 Jun 3, 2025
c012e5d
Add xcprivacy and dSYM handling (#285)
freakboy3742 Jun 3, 2025
8019835
Temporarily disable dSYM production. (#293)
freakboy3742 Jun 3, 2025
a7aaafe
Correct issues with testing in CI (#295)
freakboy3742 Jun 4, 2025
119de47
Correct handling of sysconfig._BASE_PREFIX in cross environments. (#297)
freakboy3742 Jun 6, 2025
5b1bb20
Bump ncipollo/release-action from 1.16.0 to 1.17.0 (#299)
dependabot[bot] Jun 29, 2025
6366590
Bump ncipollo/release-action from 1.17.0 to 1.18.0 (#300)
dependabot[bot] Jul 6, 2025
42c9975
Fix markdown (#302)
johnzhou721 Jul 8, 2025
162523d
Fixed typos (#305)
radarhere Jul 15, 2025
207110a
convert README from .rst to .md (#306)
yoorimgye-dw Jul 20, 2025
b65dbf5
Update patch for 3.14.0rc1 (#307)
freakboy3742 Jul 24, 2025
28af999
Correct cross-platform venv path handling (#310)
freakboy3742 Jul 28, 2025
2568e12
Merge recent changes from main.
freakboy3742 Jul 28, 2025
5d0c165
Drop CI trigger on push.
freakboy3742 Jul 28, 2025
62f3a68
Correct typo in action version.
freakboy3742 Jul 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 81 additions & 18 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ jobs:
strategy:
fail-fast: false
matrix:
target: ['macOS', 'iOS', 'tvOS', 'watchOS']
platform: ['macOS', 'iOS', 'tvOS', 'watchOS']

steps:
- uses: actions/[email protected]
Expand All @@ -104,29 +104,29 @@ jobs:
# It's an edge case, but when a new alpha is released, we need to use it ASAP.
check-latest: true

- name: Build ${{ matrix.target }}
- name: Build ${{ matrix.platform }}
run: |
# Do the build for the requested target.
make ${{ matrix.target }} BUILD_NUMBER=${{ needs.config.outputs.BUILD_NUMBER }}
# Do the build for the requested platform.
make ${{ matrix.platform }} BUILD_NUMBER=${{ needs.config.outputs.BUILD_NUMBER }}

- name: Upload build artefacts
uses: actions/[email protected]
with:
name: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
path: dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
name: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.platform }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
path: dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.platform }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz

briefcase-testbed:
name: Briefcase testbed (${{ matrix.target }})
name: Briefcase testbed (${{ matrix.platform }})
runs-on: macOS-latest
needs: [ config, build ]
strategy:
fail-fast: false
matrix:
target: ["macOS", "iOS"]
platform: ["macOS", "iOS"]
include:
- briefcase-run-args:

- target: iOS
- platform: iOS
briefcase-run-args: ' -d "iPhone SE (3rd generation)"'

steps:
Expand All @@ -135,7 +135,7 @@ jobs:
- name: Get build artifact
uses: actions/[email protected]
with:
pattern: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
pattern: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.platform }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
path: dist
merge-multiple: true

Expand All @@ -162,24 +162,24 @@ jobs:
- name: Run support testbed check
timeout-minutes: 10
working-directory: Python-support-testbed
run: briefcase run ${{ matrix.target }} Xcode --test ${{ matrix.briefcase-run-args }} -C support_package=\'../dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz\'
run: briefcase run ${{ matrix.platform }} Xcode --test ${{ matrix.briefcase-run-args }} -C support_package=\'../dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.platform }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz\'

cpython-testbed:
name: CPython testbed (${{ matrix.target }})
name: CPython testbed (${{ matrix.platform }})
runs-on: macOS-latest
needs: [ config, build ]
strategy:
fail-fast: false
matrix:
target: ["iOS"]
platform: ["iOS"]

steps:
- uses: actions/[email protected]

- name: Get build artifact
uses: actions/[email protected]
with:
pattern: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
pattern: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.platform }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
path: dist
merge-multiple: true

Expand All @@ -195,13 +195,13 @@ jobs:

- name: Unpack support package
run: |
mkdir support
cd support
tar zxvf ../dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
mkdir -p support/${{ needs.config.outputs.PYTHON_VER }}/${{ matrix.platform }}
cd support/${{ needs.config.outputs.PYTHON_VER }}/${{ matrix.platform }}
tar zxvf ../../../dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.platform }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz

- name: Run CPython testbed
timeout-minutes: 10
working-directory: support
working-directory: support/${{ needs.config.outputs.PYTHON_VER }}/${{ matrix.platform }}
run: |
# Run a representative subset of CPython core tests:
# - test_builtin as a test of core language tools
Expand All @@ -210,3 +210,66 @@ jobs:
# - test_bz2 as a simple test of third party libraries
# - test_ctypes as a test of FFI
python -m testbed run -- test --single-process --rerun -W test_builtin test_grammar test_os test_bz2 test_ctypes

crossenv-test:
name: Cross-platform env test (${{ matrix.multiarch }})
runs-on: macOS-latest
needs: [ config, build ]
strategy:
fail-fast: false
matrix:
include:
- platform: iOS
slice: ios-arm64_x86_64-simulator
multiarch: arm64-iphonesimulator
- platform: iOS
slice: ios-arm64_x86_64-simulator
multiarch: x86_64-iphonesimulator
- platform: iOS
slice: ios-arm64
multiarch: arm64-iphoneos

steps:
- uses: actions/[email protected]

- name: Get build artifact
uses: actions/[email protected]
with:
pattern: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.platform }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
path: dist
merge-multiple: true

- name: Set up Python
uses: actions/[email protected]
with:
# Appending -dev ensures that we can always build the dev release.
# It's a no-op for versions that have been published.
python-version: ${{ needs.config.outputs.PYTHON_VER }}-dev
# Ensure that we *always* use the latest build, not a cached version.
# It's an edge case, but when a new alpha is released, we need to use it ASAP.
check-latest: true

- name: Unpack support package
run: |
mkdir -p support/${{ needs.config.outputs.PYTHON_VER }}/${{ matrix.platform }}
cd support/${{ needs.config.outputs.PYTHON_VER }}/${{ matrix.platform }}
tar zxvf ../../../dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.platform }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz

- name: Run cross-platform environment test
env:
PYTHON_CROSS_PLATFORM: ${{ matrix.platform }}
PYTHON_CROSS_SLICE: ${{ matrix.slice }}
PYTHON_CROSS_MULTIARCH: ${{ matrix.multiarch }}
run: |
# Create and activate a native virtual environment
python${{ needs.config.outputs.PYTHON_VER }} -m venv cross-venv
source cross-venv/bin/activate

# Install pytest
python -m pip install pytest

# Convert venv into cross-venv
python support/${{ needs.config.outputs.PYTHON_VER }}/${{ matrix.platform }}/Python.xcframework/${{ matrix.slice }}/platform-config/${{ matrix.multiarch }}/make_cross_venv.py cross-venv

# Run the test suite
python -m pytest tests
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
merge-multiple: true

- name: Create Release
uses: ncipollo/release-action@v1.16.0
uses: ncipollo/release-action@v1.18.0
with:
name: ${{ needs.ci.outputs.PYTHON_VER }}-${{ needs.config.outputs.BUILD_NUMBER }}
tag: ${{ needs.ci.outputs.PYTHON_VER }}-${{ needs.config.outputs.BUILD_NUMBER }}
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ tests/testbed/iOS
*.log
*.gz
*.DS_Store
cross-venv/
temp
7 changes: 3 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
# - iOS - build everything for iOS
# - tvOS - build everything for tvOS
# - watchOS - build everything for watchOS
# - visionOS - build everything for visionOS

# Current directory
PROJECT_DIR=$(shell pwd)
Expand Down Expand Up @@ -34,7 +33,7 @@ OPENSSL_VERSION=3.0.16-2
XZ_VERSION=5.6.4-2

# Supported OS
OS_LIST=macOS iOS tvOS watchOS visionOS
OS_LIST=macOS iOS tvOS watchOS

CURL_FLAGS=--disable --fail --location --create-dirs --progress-bar

Expand Down Expand Up @@ -89,7 +88,7 @@ update-patch:
# comparing between the current state of the 3.X branch against the v3.X.Y
# tag associated with the release being built. This allows you to
# maintain a branch that contains custom patches against the default Python.
# The patch archived in this respository is based on github.com/freakboy3742/cpython
# The patch archived in this repository is based on github.com/freakboy3742/cpython
# Requires patchutils (installable via `brew install patchutils`); this
# also means we need to re-introduce homebrew to the path for the filterdiff
# call
Expand Down Expand Up @@ -333,7 +332,7 @@ $$(PYTHON_LIB-$(target)): $$(PYTHON_SRCDIR-$(target))/python.exe


$$(PYTHON_PLATFORM_SITECUSTOMIZE-$(target)):
@echo ">>> Create cross-plaform config for $(target)"
@echo ">>> Create cross-platform config for $(target)"
mkdir -p $$(PYTHON_PLATFORM_CONFIG-$(target))
# Create the cross-platform site definition
echo "import _cross_$$(ARCH-$(target))_$$(SDK-$(target)); import _cross_venv;" \
Expand Down
163 changes: 163 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Python Apple Support

This is a meta-package for building a version of Python that can be
embedded into a macOS, iOS, tvOS, or watchOS project.

**This branch builds a packaged version of Python 3.13**. Other Python
versions are available by cloning other branches of the main repository:

- [Python 3.9](https://github.com/beeware/Python-Apple-support/tree/3.9)
- [Python
3.10](https://github.com/beeware/Python-Apple-support/tree/3.10)
- [Python
3.11](https://github.com/beeware/Python-Apple-support/tree/3.11)
- [Python
3.12](https://github.com/beeware/Python-Apple-support/tree/3.12)
- [Python
3.14](https://github.com/beeware/Python-Apple-support/tree/3.14)

It works by downloading, patching, and building a fat binary of Python
and selected pre-requisites, and packaging them as frameworks that can
be incorporated into an Xcode project. The binary modules in the Python
standard library are distributed as binaries that can be dynamically
loaded at runtime.

The macOS package is a re-bundling of the official macOS binary,
modified so that it is relocatable, with the IDLE, Tkinter and turtle
packages removed, and the App Store compliance patch applied.

The iOS, tvOS, and watchOS packages compiled by this project
use the official [PEP 730](https://peps.python.org/pep-0730/) code that
is part of Python 3.13 to provide iOS support; the relevant patches have
been backported to 3.9-3.12. Additional patches have been applied to add
tvOS, and watchOS support.

The binaries support x86_64 and arm64 for macOS; arm64 for iOS and
appleTV devices; and arm64_32 for watchOS devices.
It also supports device simulators on both x86_64 and M1
hardware. This should enable the code to run on:

- macOS 11 (Big Sur) or later, on:
- MacBook (including MacBooks using Apple Silicon)
- iMac (including iMacs using Apple Silicon)
- Mac Mini (including Apple Silicon Mac minis)
- Mac Studio (all models)
- Mac Pro (all models)

- iOS 13.0 or later, on:
- iPhone (6s or later)
- iPad (5th gen or later)
- iPad Air (all models)
- iPad Mini (2 or later)
- iPad Pro (all models)
- iPod Touch (7th gen or later)

- tvOS 12.0 or later, on:
- Apple TV (4th gen or later)

- watchOS 4.0 or later, on:
- Apple Watch (4th gen or later)

## Quickstart

The easist way to use these packages is by creating a project with
[Briefcase](https://github.com/beeware/briefcase). Briefcase will
download pre-compiled versions of these support packages, and add them
to an Xcode project (or pre-build stub application, in the case of
macOS).

Pre-built versions of the frameworks can be downloaded from the [Github
releases page](https://github.com/beeware/Python-Apple-support/releases)
and added to your project.

Alternatively, to build the frameworks on your own, download/clone this
repository, and then in the root directory, and run:

- `make` (or `make all`) to build everything.
- `make macOS` to build everything for macOS.
- `make iOS` to build everything for iOS.
- `make tvOS` to build everything for tvOS.
- `make watchOS` to build everything for watchOS.

This should:

1. Download the original source packages
2. Patch them as required for compatibility with the selected OS
3. Build the packages as Xcode-compatible XCFrameworks.

The resulting support packages will be packaged as `.tar.gz` files in
the `dist` folder.

Each support package contains:

- `VERSIONS`, a text file describing the specific versions of code used
to build the support package;
- `Python.xcframework`, a multi-architecture build of the Python runtime
library.

On iOS/tvOS/watchOS, the `Python.xcframework` contains a slice
for each supported ABI (device and simulator). The folder containing the
slice can also be used as a `PYTHONHOME`, as it contains a `bin`,
`include` and `lib` directory.

The `bin` folder does not contain Python executables (as they can't be
invoked). However, it *does* contain shell aliases for the compilers
that are needed to build packages. This is required because Xcode uses
the `xcrun` alias to dynamically generate the name of binaries, but a
lot of C tooling expects that `CC` will not contain spaces.

Each slice of an iOS/tvOS/watchOS XCframework also contains a
`platform-config` folder with a subfolder for each supported
architecture in that slice. These subfolders can be used to make a macOS
Python environment behave as if it were on an iOS/tvOS/watchOS
device. This works in one of two ways:

1. **A sitecustomize.py script**. If the `platform-config` subfolder is
on your `PYTHONPATH` when a Python interpreter is started, a site
customization will be applied that patches methods in `sys`,
`sysconfig` and `platform` that are used to identify the system.
2. **A make_cross_venv.py script**. If you call `make_cross_venv.py`,
providing the location of a virtual environment, the script will add
some files to the `site-packages` folder of that environment that
will automatically apply the same set of patches as the
`sitecustomize.py` script whenever the environment is activated,
without any need to modify `PYTHONPATH`. If you use `build` to
create an isolated PEP 517 environment to build a wheel, these
patches will also be applied to the isolated build environment that
is created.

iOS distributions also contain a copy of the iOS
`testbed` project - an Xcode project that can be used to run
test suites of Python code. See the [CPython documentation on testing
packages](https://docs.python.org/3/using/ios.html#testing-a-python-package)
for details on how to use this testbed.

For a detailed instructions on using the support package in your own
project, see the [usage guide](./USAGE.md)

## Building binary wheels

This project packages the Python standard library, but does not address
building binary wheels. Binary wheels for macOS can be obtained from
PyPI. [Mobile Forge](https://github.com/beeware/mobile-forge) is a
project that provides the tooling to build build binary wheels for iOS
(and potentially for tvOS, and watchOS, although that hasn't
been tested).

## Historical support

The following versions were supported in the past, but are no longer
maintained:

- [Python 2.7](https://github.com/beeware/Python-Apple-support/tree/2.7)
(EOL January 2020)
- [Python 3.4](https://github.com/beeware/Python-Apple-support/tree/3.4)
(EOL March 2019)
- [Python 3.5](https://github.com/beeware/Python-Apple-support/tree/3.5)
(EOL February 2021)
- [Python 3.6](https://github.com/beeware/Python-Apple-support/tree/3.6)
(EOL December 2021)
- [Python 3.7](https://github.com/beeware/Python-Apple-support/tree/3.7)
(EOL September 2022)
- [Python 3.8](https://github.com/beeware/Python-Apple-support/tree/3.8)
(EOL October 2024)
Loading
Loading