Multi-version Python support (3.12 / 3.13 / 3.14)#207
Open
FeodorFitsner wants to merge 9 commits into
Open
Conversation
`package_command.dart` gains a `--python-version` option (with `SERIOUS_PYTHON_VERSION` env-var fallback) driving a new `_pythonReleases` table that maps each short version to its CPython-standalone build, Pyodide release, and Pyodide wheel platform tag. The Emscripten `pip install --platform` tag is now resolved from the chosen release rather than the static `platforms` map. Each platform plugin (`android/build.gradle`, `darwin/*.podspec`, `linux/CMakeLists.txt` + plugin `.cc`, `windows/CMakeLists.txt`) reads `SERIOUS_PYTHON_VERSION` (default `3.14`) so `flet-dev/python-build` downloads, library filenames, and runtime module paths track the selected version. The Android Dart runtime now scans `nativeLibraryDir` for `libpython3.*.so` instead of hardcoding `libpython3.12.so`, removing version coupling from the Dart side entirely. CI: each platform job (macOS / iOS / Android / Windows / Linux) now runs across the full `[3.12, 3.13, 3.14]` Python matrix with `fail-fast: false`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n test
Two regressions surfaced by the wider Python matrix on the newer
python-build-standalone (20260602) and the newer pip vendored packaging
that ships with it:
* Windows: astral-sh dropped the explicit `-shared` MSVC build; only the
combined `x86_64-pc-windows-msvc-install_only_stripped` variant remains
(which is itself shared). Drop the `-shared` suffix from the constructed
archive name.
* Android: packaging.tags.android_platforms now calls
`platform.android_ver().api_level` (3.13+ API, returns 0 on non-Android
hosts even where present), and derives the wheel ABI from
`sysconfig.get_platform().split("-")[-1]`. Shim `platform.android_ver` in
sitecustomize.py to return a namedtuple with the api_level encoded in the
custom tag, and switch the Android platform tags from
`android-24-arm64-v8a` to `android-24-arm64_v8a` so the split-by-dash gives
the full ABI string. The wheel tag emitted by both old and new packaging
remains `android_24_arm64_v8a`, matching the wheels on pypi.flet.dev.
The example app now prints/displays the runtime CPython version, and the
integration test verifies it matches `--dart-define=EXPECTED_PYTHON_VERSION`
(passed per matrix entry from CI). The assertion is skipped when the define
is empty, so local runs are unaffected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`flet-dev/python-build` stopped publishing the 32-bit `python-android-dart-<ver>-armeabi-v7a.tar.gz` tarball for Python 3.13+ (64-bit only), so the gradle download task that's driven by abiFilters fails for those versions. Keep all three ABIs on 3.12, restrict to arm64-v8a + x86_64 from 3.13 onward. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
python-build dropped 32-bit Android (armeabi-v7a, x86) in 3.13 (PEP 738), and the serious_python_android plugin already restricts abiFilters accordingly. Without a matching guard in the package command, the pip install loop still iterates the 32-bit ABIs and produces site-packages trees that the Flutter build then ignores — pure wasted work. Skip those arches when --python-version is anything other than 3.12. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the strict numpy==1.26.4 pin with an unpinned 'numpy' in run_example requirements to allow flexible numpy versions. Also update the flet_example app.zip.hash to the new checksum matching the updated packaged app.
The default Python version bumped from 3.12 to 3.14 (latest stable) — a breaking change for any caller of `dart run serious_python:main package` that omits `--python-version`. Bump all six pub packages to 2.0.0 and call this out in the CHANGELOGs alongside the other breaking surfaces (Android `sysconfig.get_platform()` separator, Windows arch identifier). `_pythonReleases` entries gain a required `prerelease` field. The Dart side keeps the version-print line honest by appending " — pre-release" when applicable; the Flet CLI mirrors the field in its `PythonRelease` dataclass and gates `requires-python` resolution: stable rows win, prereleases are a fallback so explicit specifiers like `==3.15.*` (and `>=3.15` when no stable matches) still opt in without exposing a CLI flag or making the default jump to a beta line. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1.0.1 was prepared on `release-1.0.1` but never published, so the PIP_REQUIRE_VIRTUALENV=false fix should ship as part of 2.0.0 rather than as its own release header. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Conflict resolution: * All six pubspec.yaml files: keep multi-python's 2.0.0 bump (supersedes main's 1.0.1 prep). build.gradle and podspec version labels follow suit. * All six CHANGELOG.md files: keep multi-python's 2.0.0 entry, then restore main's 1.0.1 entry as its own released section between 2.0.0 and 1.0.0 (1.0.1 has now actually been cut on main, so the prior "fold into 2.0.0" rationale no longer applies). Dropped the duplicated PIP_REQUIRE_VIRTUALENV bullet from each 2.0.0 entry since 1.0.1 below records it under "Bug fixes". * serious_python_android/android/build.gradle: auto-merged cleanly — keeps multi-python's `python_version` parameterization and conditional `abiFilters`, picks up main's persistent Python tarball cache (`onlyIfModified`, `useETag`, `tempAndMove`) and the `pythonCacheDir` path now using the resolved `python_version`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Targeted documentation pass after the 1.0.0 (Pyodide -> Emscripten) and
2.0.0 (multi-version Python) releases:
* Fix `environmnent` typo and iOS Podfile target (`12.0` -> `13.0` to
match the podspec).
* Platform list under `-p {platform}`: `macOS` -> `Darwin` to match the
`allowed:` constant in `package_command.dart`.
* Rewrite both `--requirements` examples to the modern
`-r DEP_1 -r DEP_2` / `-r -r -r requirements.txt` syntax with a
callout that the comma-separated form was removed in 0.9.2 (so
specifiers like `pandas>=2.2,<3` work).
* New `Selecting a Python version` subsection covering
`--python-version`, `SERIOUS_PYTHON_VERSION`, and the fact that a
single env-var export covers both the package phase and the later
`flutter build` phase.
* Expand the Python versions section with the default-3.14 rule and
document how a future pre-release CPython line (e.g. 3.15) is
expressed via `prerelease: true` without becoming the auto-resolved
default.
* Document the previously-undocumented `sync: true` parameter on
`SeriousPython.run`.
* Brief `flet build` pointer at the top of the Packaging section
(https://flet.dev/docs/publish/) — direct CLI usage remains the
canonical documentation below it.
* Fix all three example links at the bottom (drop the stale
`src/serious_python/` prefix so they resolve on pub.dev and GitHub).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_pythonReleasesregistry mapping each supported short Python version to its CPython-standalone build, Pyodide release, Pyodide wheel platform tag, and aprereleaseflag. Defaults to the latest supported stable (3.14).packagecommand gains--python-version X.Y(also readsSERIOUS_PYTHON_VERSIONenv var). The Emscripten wheel platform tag is now derived per release instead of hardcoded.android/build.gradle,darwin/*.podspec,linux/CMakeLists.txt+ plugin.cc,windows/CMakeLists.txt) readsSERIOUS_PYTHON_VERSIONso theflet-dev/python-builddownload URL, bundled library filenames, and runtime module path all track the selected version.serious_python_android.dartreplaces the hardcodedlibpython3.12.soconstant with a runtime scan ofnativeLibraryDirforlibpython3.*.so, removing Dart-side version coupling.sitecustomize.pyadds anandroid_vershim so newer pip / packaging can compute Android wheel tags on any host (Python 3.13+ added the API; Python 3.12 didn't have it; even on 3.13+ hosts it returns 0 forapi_leveloff-device).abiFiltersand the per-arch pip-install loop droparmeabi-v7a/x86on Python 3.13+ (PEP 738 — no 32-bit Android builds inpython-buildv3.13+ releases).Breaking changes (2.0.0)
--python-versionandSERIOUS_PYTHON_VERSIONare both omitted (was implicitly 3.12). Pin with--python-version 3.12to preserve the old behavior.sysconfig.get_platform()tag changes fromandroid-24-arm64-v8atoandroid-24-arm64_v8a(and similarly forarmeabi-v7a). The wheel tag emitted by pip (android_24_arm64_v8a) is unchanged.-sharedsuffix to match what astral-sh/python-build-standalone still publishes (which is already the shared build).CI
ci.ymlnow runs the full matrix: each platform job (macOS / iOS / Android / Windows / Linux) acrosspython_version: [3.12, 3.13, 3.14]withfail-fast: false. Linux keeps its existingarch: [arm64, amd64]matrix as an orthogonal dimension. The example app prints the bundled runtime version (Python version: X.Y.Z), and the integration test asserts it matchesEXPECTED_PYTHON_VERSION(passed via--dart-defineper matrix entry).Adjacent
Test plan
multi-python(see linked CI run).dart run serious_python:main package app/src --platform Android --python-version 3.14 -r flet==0.28.3installs onlyarm64-v8a+x86_64site-packages.--python-version 3.12installs all four ABIs.serious_python2.0.0 to pub.dev before the matching flet branch lands (flet's build template pinsserious_python: 2.0.0).🤖 Generated with Claude Code