@@ -2479,6 +2479,60 @@ def run_flutter(self):
24792479
24802480 self ._run_flutter_command ()
24812481
2482+ def _serious_python_build_env (self ) -> dict :
2483+ """
2484+ serious_python environment for the platform NATIVE build (the Gradle /
2485+ CMake / podspec steps run by `flutter build`).
2486+
2487+ These tell the native build where the `package` step staged the app and
2488+ site-packages and which embedded Python runtime to bundle. `flet build`
2489+ applies them via `_run_flutter_command`; `flet test` applies the SAME set
2490+ to the `flutter test` it spawns (see test.py `_flutter_path_env`) so both
2491+ bundle an identical app. In particular, without `SERIOUS_PYTHON_APP` the
2492+ Android `packageApp` Gradle task early-returns and a stale `app.zip` (e.g.
2493+ an old-Python `main.pyc`) survives in the APK — `ImportError: bad magic
2494+ number`. Built defensively so it is safe to call before the full build
2495+ pipeline has populated every attribute.
2496+ """
2497+
2498+ env : dict = {}
2499+ python_release = getattr (self , "python_release" , None )
2500+ if python_release is not None :
2501+ # Only the short version is passed; serious_python derives the rest
2502+ # from its committed manifest snapshot.
2503+ env ["SERIOUS_PYTHON_VERSION" ] = python_release .short
2504+
2505+ build_dir = getattr (self , "build_dir" , None )
2506+ package_platform = getattr (self , "package_platform" , None )
2507+ if build_dir is not None and package_platform != "Emscripten" :
2508+ env ["SERIOUS_PYTHON_SITE_PACKAGES" ] = str (build_dir / "site-packages" )
2509+ # app staging dir: read by the platform native build (CMake / podspec
2510+ # / Android Gradle) at `flutter build` time to place the unpacked app
2511+ # into the bundle.
2512+ env ["SERIOUS_PYTHON_APP" ] = str (build_dir / "python-app" )
2513+
2514+ # Swift Package Manager (darwin): export the cache-bust key the package
2515+ # step computed so the plugin's Package.swift re-resolves when the staged
2516+ # native set changes (SwiftPM caches its graph on manifest text + env).
2517+ if (
2518+ build_dir is not None
2519+ and package_platform in ("iOS" , "Darwin" )
2520+ and self ._darwin_spm_active ()
2521+ ):
2522+ spm_key_file = build_dir / ".serious_python_spm_key"
2523+ if spm_key_file .exists ():
2524+ env ["SP_NATIVE_SET" ] = spm_key_file .read_text ().strip ()
2525+
2526+ # Path-hungry packages to ship extracted to disk: consumed by the
2527+ # serious_python_android Gradle split during `flutter build`.
2528+ if package_platform == "Android" and getattr (
2529+ self , "android_extract_packages" , None
2530+ ):
2531+ env ["SERIOUS_PYTHON_ANDROID_EXTRACT_PACKAGES" ] = "," .join (
2532+ self .android_extract_packages
2533+ )
2534+ return env
2535+
24822536 def _run_flutter_command (self ):
24832537 """
24842538 Build final Flutter CLI command, configure environment, and run it.
@@ -2500,36 +2554,10 @@ def _run_flutter_command(self):
25002554 ]
25012555 )
25022556
2503- # Only the short version is passed; serious_python derives the rest
2504- # from its committed manifest snapshot.
2505- build_env = {
2506- "SERIOUS_PYTHON_VERSION" : self .python_release .short ,
2507- }
2508-
2509- # site-packages variable
2510- if self .package_platform != "Emscripten" :
2511- build_env ["SERIOUS_PYTHON_SITE_PACKAGES" ] = str (
2512- self .build_dir / "site-packages"
2513- )
2514- # app staging dir: read by the platform native build (CMake /
2515- # podspec / Android Gradle) at `flutter build` time to place the
2516- # unpacked app into the bundle.
2517- build_env ["SERIOUS_PYTHON_APP" ] = str (self .build_dir / "python-app" )
2518-
2519- # Swift Package Manager (darwin): export the cache-bust key the package
2520- # step computed so the plugin's Package.swift re-resolves when the staged
2521- # native set changes (SwiftPM caches its graph on manifest text + env).
2522- if self ._darwin_spm_active ():
2523- spm_key_file = self .build_dir / ".serious_python_spm_key"
2524- if spm_key_file .exists ():
2525- build_env ["SP_NATIVE_SET" ] = spm_key_file .read_text ().strip ()
2526-
2527- # Path-hungry packages to ship extracted to disk: consumed by the
2528- # serious_python_android Gradle split during `flutter build`.
2529- if self .package_platform == "Android" and self .android_extract_packages :
2530- build_env ["SERIOUS_PYTHON_ANDROID_EXTRACT_PACKAGES" ] = "," .join (
2531- self .android_extract_packages
2532- )
2557+ # serious_python env for the native build, shared verbatim with `flet
2558+ # test` (which spawns its own `flutter test`) so both bundle an identical
2559+ # app — see `_serious_python_build_env`.
2560+ build_env = self ._serious_python_build_env ()
25332561
25342562 if self .package_platform == "Emscripten" and not self .template_data ["no_wasm" ]:
25352563 build_args .append ("--wasm" )
0 commit comments