diff --git a/.fvmrc b/.fvmrc index 5913bec0..4b28f0a5 100644 --- a/.fvmrc +++ b/.fvmrc @@ -1,3 +1,3 @@ { - "flutter": "3.44.4" + "flutter": "3.44.8" } \ No newline at end of file diff --git a/src/serious_python/CHANGELOG.md b/src/serious_python/CHANGELOG.md index 92538239..99229084 100644 --- a/src/serious_python/CHANGELOG.md +++ b/src/serious_python/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.4.0 + +* **iOS/macOS:** fix built iOS apps crashing at startup with `Failed to lookup symbol 'serious_python_run'`. `dart_bridge` now ships as a dynamic framework, so the FFI entry points Dart and Python resolve via `dlsym` stay exported; previously it was static-linked into the app executable, which exports nothing. Release/device builds only. See `serious_python_darwin` 4.4.0. +* Bundled python-build snapshot re-pinned to **20260725** (`dart_bridge` **1.5.1 → 1.6.1**, which carries the dynamic-framework change above; Pyodide 3.14 **314.0.2 → 314.0.3**). Python versions (**3.12.13 / 3.13.14 / 3.14.6**) are unchanged. + ## 4.3.6 * **Android:** PEP 734 subinterpreters (Python 3.14's `concurrent.interpreters` / `InterpreterPoolExecutor`) now work in built apps. Previously the main interpreter could import them, but every *subinterpreter* failed to import any relocated C extension (`ModuleNotFoundError: _struct` / `_interpqueues` / ...) — which broke the whole feature (its cross-interpreter transport pickles → `_struct`, and its queues need `_interpqueues`). The native-module finder lives on `sys.meta_path`, which is per-interpreter, and was installed only in the main interpreter. See `serious_python_android` 4.3.6. diff --git a/src/serious_python/lib/src/python_versions.dart b/src/serious_python/lib/src/python_versions.dart index e35cce2e..6aa21de5 100644 --- a/src/serious_python/lib/src/python_versions.dart +++ b/src/serious_python/lib/src/python_versions.dart @@ -1,5 +1,5 @@ // GENERATED by `dart run serious_python:gen_version_tables` from python-build's -// manifest.json (release 20260720). Do not edit by hand — edit python-build's +// manifest.json (release 20260725). Do not edit by hand — edit python-build's // manifest.json, cut a release, bump `pythonReleaseDate`, and regenerate. const pythonVersionEnvironmentVariable = "SERIOUS_PYTHON_VERSION"; @@ -10,8 +10,8 @@ const pyodideVersionEnvironmentVariable = "SERIOUS_PYTHON_PYODIDE_VERSION"; const dartBridgeVersionEnvironmentVariable = "DART_BRIDGE_VERSION"; /// python-build release the bundled runtimes come from (YYYYMMDD). -const pythonReleaseDate = "20260720"; -const dartBridgeVersion = "1.5.1"; +const pythonReleaseDate = "20260725"; +const dartBridgeVersion = "1.6.1"; const defaultPythonVersion = "3.14"; class PythonRelease { @@ -56,7 +56,7 @@ const pythonReleases = { "3.14": PythonRelease( standaloneVersion: "3.14.6", standaloneReleaseDate: "20260623", - pyodideVersion: "314.0.2", + pyodideVersion: "314.0.3", pyodidePlatformTag: "pyemscripten-2026.0-wasm32", androidAbis: ["arm64-v8a", "x86_64", "armeabi-v7a"], prerelease: false, diff --git a/src/serious_python/pubspec.yaml b/src/serious_python/pubspec.yaml index 572ca8d8..2db670c3 100644 --- a/src/serious_python/pubspec.yaml +++ b/src/serious_python/pubspec.yaml @@ -2,7 +2,7 @@ name: serious_python description: A cross-platform plugin for adding embedded Python runtime to your Flutter apps. homepage: https://flet.dev repository: https://github.com/flet-dev/serious-python -version: 4.3.6 +version: 4.4.0 platforms: ios: diff --git a/src/serious_python_android/CHANGELOG.md b/src/serious_python_android/CHANGELOG.md index e8760e7c..d9686c0f 100644 --- a/src/serious_python_android/CHANGELOG.md +++ b/src/serious_python_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.4.0 + +* Re-pins the bundled python-build snapshot to **20260725** (`dart_bridge` **1.5.1 → 1.6.1**). 1.6.1 changes only how `dart_bridge` is packaged for Apple platforms (static library → dynamic framework, see `serious_python_darwin` 4.4.0); the Android runtime is byte-identical to 20260720. + ## 4.3.6 * **PEP 734 subinterpreters now work** (Python 3.14 `concurrent.interpreters` / `InterpreterPoolExecutor`) — enabling true multi-core CPU parallelism inside a single process, which `multiprocessing` cannot provide on Android. Previously the main interpreter imported the machinery fine, but every subinterpreter raised `ModuleNotFoundError` for `_struct` / `_interpqueues` / any other C extension, so `InterpreterPoolExecutor` and the low-level API were unusable. Cause: Android relocates C extensions (native-mmap packaging) and resolves them through `_SorefFinder` on `sys.meta_path`; `sys.meta_path` is per-interpreter, and `install()` only ran in the main interpreter, so a freshly created subinterpreter had a `meta_path` without the finder. Fix: `_sp_bootstrap.install()` now also wraps `concurrent.interpreters.create()` so every new interpreter installs the finder before use. The install runs via `Interpreter.exec()` — a source string, which is pickle-free (unlike `Interpreter.call()`), so it works *before* `_struct` is importable in the child. Because `InterpreterPoolExecutor` builds its workers via `concurrent.interpreters.create()`, the pool is fixed transparently with no user-code change. A no-op before 3.14; iOS/desktop were unaffected. diff --git a/src/serious_python_android/android/build.gradle.kts b/src/serious_python_android/android/build.gradle.kts index 8f14855e..c2038256 100644 --- a/src/serious_python_android/android/build.gradle.kts +++ b/src/serious_python_android/android/build.gradle.kts @@ -21,7 +21,7 @@ buildscript { } group = "com.flet.serious_python_android" -version = "4.3.6" +version = "4.4.0" rootProject.allprojects { repositories { diff --git a/src/serious_python_android/android/python_versions.properties b/src/serious_python_android/android/python_versions.properties index 1816c017..e2f008ff 100644 --- a/src/serious_python_android/android/python_versions.properties +++ b/src/serious_python_android/android/python_versions.properties @@ -1,8 +1,8 @@ # GENERATED by `dart run serious_python:gen_version_tables` from -# python-build manifest.json (release 20260720). Do not edit by hand. +# python-build manifest.json (release 20260725). Do not edit by hand. default_python_version=3.14 -dart_bridge_version=1.5.1 -python_build_release_date=20260720 +dart_bridge_version=1.6.1 +python_build_release_date=20260725 3.12.full_version=3.12.13 3.12.android_abis=arm64-v8a,x86_64,armeabi-v7a 3.13.full_version=3.13.14 diff --git a/src/serious_python_android/pubspec.yaml b/src/serious_python_android/pubspec.yaml index ca194240..d88072ac 100644 --- a/src/serious_python_android/pubspec.yaml +++ b/src/serious_python_android/pubspec.yaml @@ -2,7 +2,7 @@ name: serious_python_android description: Android implementation of the serious_python plugin homepage: https://flet.dev repository: https://github.com/flet-dev/serious-python -version: 4.3.6 +version: 4.4.0 environment: sdk: ">=3.0.0 <4.0.0" diff --git a/src/serious_python_darwin/CHANGELOG.md b/src/serious_python_darwin/CHANGELOG.md index c34af698..c9da7a18 100644 --- a/src/serious_python_darwin/CHANGELOG.md +++ b/src/serious_python_darwin/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.4.0 + +* **iOS/macOS: `dart_bridge` now ships as a dynamic framework**, fixing built iOS apps crashing at startup with `Failed to lookup symbol 'serious_python_run': dlsym(RTLD_DEFAULT, serious_python_run): symbol not found`. `dart_bridge`'s FFI entry points (`serious_python_run`, `DartBridge_InitDartApiDL`, `DartBridge_EnqueueMessage`, `PyInit_dart_bridge`) are resolved at runtime via `dlsym` — from Dart through `DynamicLibrary.process()` and from Python through `import dart_bridge`. It previously shipped as a **static** archive linked into the host app *executable*, and an iOS executable exports nothing to the dynamic symbol table by default (the release build also strips local symbols), so those lookups failed. Only release/archive (device) builds were affected — debug/simulator builds don't dead-strip, so the failure did not reproduce there. Android was never affected: its `dart_bridge` is a dynamic `.so`, which exports its symbols. `dart_bridge` **1.6.1** now builds `dart_bridge.xcframework` as a dynamic framework (see flet-dev/dart-bridge#11 and #12), so it is embedded + signed into the app like `Python.xcframework` and its symbols stay exported. The SwiftPM `-all_load` / `-force_load` retention, the CocoaPods `-all_load`, and the plugin's dead-strip keep-alive references are all removed — a loaded image needs none of them. +* Re-pins the bundled python-build snapshot to **20260725** (`dart_bridge` **1.5.1 → 1.6.1**). Python versions (**3.12.13 / 3.13.14 / 3.14.6**) are unchanged and the iOS/macOS CPython runtimes are byte-identical to 20260720. + ## 4.3.6 * Re-pins the bundled python-build snapshot to **20260720** (`dart_bridge` **1.5.0 → 1.5.1**). 1.5.1 is a Windows-only UTF-8 startup fix (see `serious_python_windows` 4.3.6); the iOS/macOS runtimes are functionally unchanged from 20260719. diff --git a/src/serious_python_darwin/darwin/python_versions.properties b/src/serious_python_darwin/darwin/python_versions.properties index 1816c017..e2f008ff 100644 --- a/src/serious_python_darwin/darwin/python_versions.properties +++ b/src/serious_python_darwin/darwin/python_versions.properties @@ -1,8 +1,8 @@ # GENERATED by `dart run serious_python:gen_version_tables` from -# python-build manifest.json (release 20260720). Do not edit by hand. +# python-build manifest.json (release 20260725). Do not edit by hand. default_python_version=3.14 -dart_bridge_version=1.5.1 -python_build_release_date=20260720 +dart_bridge_version=1.6.1 +python_build_release_date=20260725 3.12.full_version=3.12.13 3.12.android_abis=arm64-v8a,x86_64,armeabi-v7a 3.13.full_version=3.13.14 diff --git a/src/serious_python_darwin/darwin/serious_python_darwin.podspec b/src/serious_python_darwin/darwin/serious_python_darwin.podspec index b7483634..06910f01 100644 --- a/src/serious_python_darwin/darwin/serious_python_darwin.podspec +++ b/src/serious_python_darwin/darwin/serious_python_darwin.podspec @@ -4,7 +4,7 @@ # Pod::Spec.new do |s| s.name = 'serious_python_darwin' - s.version = '4.3.6' + s.version = '4.4.0' s.summary = 'A cross-platform plugin for adding embedded Python runtime to your Flutter apps.' s.description = <<-DESC A cross-platform plugin for adding embedded Python runtime to your Flutter apps. @@ -13,11 +13,10 @@ Pod::Spec.new do |s| s.license = { :file => '../LICENSE' } s.author = { 'Appveyor Systems Inc.' => 'hello@flet.dev' } s.source = { :path => '.' } - # dart_bridge.xcframework (vendored below) contains static .a archives. - # CocoaPods 1.16+ refuses to install vendored xcframeworks with static - # libraries unless the consuming pod is itself declared as a static - # framework. Python.xcframework is also static, so this was always - # implicitly the case — just being explicit now. + # This pod's own Swift code links as a static framework. The vendored + # xcframeworks below (Python, dart_bridge) are dynamic frameworks — they are + # embedded and signed into the host app, and their symbols stay exported so + # the dlsym lookups Dart and Python perform at runtime resolve. s.static_framework = true s.source_files = ['serious_python_darwin/Sources/serious_python_darwin/**/*.swift'] s.ios.dependency 'Flutter' @@ -26,9 +25,12 @@ Pod::Spec.new do |s| s.osx.deployment_target = '11.0' # Flutter.framework does not contain a i386 slice. + # `-all_load` is no longer needed: it existed to retain the static + # libdart_bridge.a against -dead_strip, and dart_bridge now ships as a dynamic + # framework whose symbols are exported from its own loaded image. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', - 'OTHER_LDFLAGS' => '-ObjC -all_load -lc++' + 'OTHER_LDFLAGS' => '-ObjC -lc++' } s.swift_version = '5.0' diff --git a/src/serious_python_darwin/darwin/serious_python_darwin/Package.swift b/src/serious_python_darwin/darwin/serious_python_darwin/Package.swift index f6988e9a..1c0bfcf5 100644 --- a/src/serious_python_darwin/darwin/serious_python_darwin/Package.swift +++ b/src/serious_python_darwin/darwin/serious_python_darwin/Package.swift @@ -44,36 +44,20 @@ func staged(_ rel: String) -> Bool { var binaryTargets: [Target] = [] var deps: [Target.Dependency] = [.product(name: "FlutterFramework", package: "FlutterFramework")] -// dart_bridge: static archive, link-only. Its FFI exports are resolved at runtime -// via dlsym (Dart's `DynamicLibrary.process()` and Python's `import dart_bridge`), -// so the whole archive must be retained against the linker's -dead_strip. We -// force-load JUST this archive rather than using a global -all_load: SwiftPM -// applies a target's linkerSettings to the FINAL app executable link, so a global -// -all_load there would force-load EVERY static archive on the link line — -// including plugins that statically bundle the same third-party code (e.g. -// flet-video/media_kit and flet-rive both embed miniaudio), which then collide -// with thousands of duplicate symbols. -force_load on dart_bridge alone mirrors -// what the CocoaPods podspec did via `pod_target_xcconfig` (scoped to this pod's -// own inputs — only dart_bridge among them is a static archive). On macOS the -// xcframework has a single universal slice with a stable path, so we resolve it -// here. On iOS, plugin pods link as dynamic frameworks (no static-archive -// collision) and device/simulator use different slice paths, so the -// slice-agnostic -all_load is kept there (see linkerSettings below). -var macosDartBridgeForceLoad: [String] = [] +// dart_bridge: DYNAMIC framework -> embedded + auto-signed in the app. Its FFI +// entry points (serious_python_run, DartBridge_*, PyInit_dart_bridge) are +// EXPORTED from the loaded framework, so the dlsym lookups that Dart +// (`DynamicLibrary.process()`) and Python (`import dart_bridge`) perform resolve +// at runtime. A static library would instead be linked into the app executable, +// which does not export its symbols (and the release build strips them), so +// dlsym would fail with "Failed to lookup symbol 'serious_python_run'". Shipping +// it dynamic mirrors the Android `.so` (CMake SHARED) that already works — see +// flet-dev/dart-bridge apple/build_xcframework.sh. No -all_load/-force_load or +// keep-alive is needed anymore: the framework is a loaded image, not archive +// members that must be pulled in and kept against -dead_strip. if staged("dart_bridge.xcframework") { binaryTargets.append(.binaryTarget(name: "dart_bridge", path: "dart_bridge.xcframework")) deps.append("dart_bridge") - let xc = pkgDir.appendingPathComponent("dart_bridge.xcframework") - if let slices = try? FileManager.default.contentsOfDirectory( - at: xc, includingPropertiesForKeys: nil) { - for slice in slices.sorted(by: { $0.lastPathComponent < $1.lastPathComponent }) - where slice.lastPathComponent.hasPrefix("macos") { - let lib = slice.appendingPathComponent("libdart_bridge.a") - if FileManager.default.fileExists(atPath: lib.path) { - macosDartBridgeForceLoad = ["-force_load", lib.path] - } - } - } } // Python.framework: dynamic -> embedded + auto-signed. iOS and macOS ship separate // xcframeworks, so each is platform-conditional. @@ -119,15 +103,9 @@ let package = Package( .copy("Resources/app"), ], linkerSettings: [ + // dart_bridge is now a dynamic framework (embedded, symbols + // exported), so no -all_load / -force_load is needed to retain it. .unsafeFlags(["-ObjC"]), - // iOS: slice-agnostic -all_load. Plugin pods link as dynamic - // frameworks, so dart_bridge is the only static archive in scope — - // nothing else to double-load. (device/simulator slice paths differ, - // so a single -force_load path isn't possible here.) - .unsafeFlags(["-all_load"], .when(platforms: [.iOS])), - // macOS: force-load ONLY dart_bridge (resolved above), never a global - // -all_load — see the note where macosDartBridgeForceLoad is built. - .unsafeFlags(macosDartBridgeForceLoad, .when(platforms: [.macOS])), .linkedLibrary("c++"), ] ), diff --git a/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift b/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift index bc9ba68e..b24022ed 100644 --- a/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift +++ b/src/serious_python_darwin/darwin/serious_python_darwin/Sources/serious_python_darwin/SeriousPythonPlugin.swift @@ -5,27 +5,13 @@ import UIKit import FlutterMacOS #endif -// Keep-alive references to dart_bridge.xcframework's C entry points. Dart -// resolves them via `DynamicLibrary.process()` at runtime; without these -// static references the host app's linker `-dead_strip` pass could drop -// them even though `-all_load` pulled the archive members in. -@_silgen_name("serious_python_run") -private func _sp_run_keepalive(_ cfg: OpaquePointer?) -> Int32 -@_silgen_name("DartBridge_InitDartApiDL") -private func _sp_init_keepalive(_ data: UnsafeMutableRawPointer?) -> Int -@_silgen_name("DartBridge_EnqueueMessage") -private func _sp_enqueue_keepalive(_ data: UnsafePointer?, _ len: Int) - -// multiprocessing child-interception entry points, -// dlsym'd by the host app's main.swift before NSApplicationMain. -@_silgen_name("serious_python_is_mp_invocation") -private func _sp_is_mp_keepalive( - _ argc: Int32, _ argv: UnsafeMutablePointer?>? -) -> Int32 -@_silgen_name("serious_python_main") -private func _sp_main_keepalive( - _ argc: Int32, _ argv: UnsafeMutablePointer?>? -) -> Int32 +// dart_bridge's C entry points (serious_python_run, DartBridge_*, +// serious_python_{is_mp_invocation,main}) used to need keep-alive references +// here: it shipped as a static archive linked into the host app executable, +// which exports nothing, so the dlsym lookups Dart (`DynamicLibrary.process()`) +// and the macOS host's main.swift perform could fail. dart_bridge now ships as a +// dynamic framework (embedded + signed) whose symbols are exported from its own +// loaded image, so no keep-alive is required — see dart-bridge 1.6.0. /// Thin Flutter plugin: surfaces the python.bundle resource path to Dart. /// All Python lifecycle now lives in `serious_python_run` @@ -42,17 +28,6 @@ public class SeriousPythonPlugin: NSObject, FlutterPlugin { let channel = FlutterMethodChannel(name: "serious_python", binaryMessenger: messenger) let instance = SeriousPythonPlugin() registrar.addMethodCallDelegate(instance, channel: channel) - - // Static reference to dart_bridge symbols — see top-of-file note. - // The branch is unreachable at runtime (the registrar argument is - // always non-nil), but the linker only sees a live call site. - if unsafeBitCast(registrar, to: Int.self) == 0 { - _ = _sp_run_keepalive(nil) - _ = _sp_init_keepalive(nil) - _sp_enqueue_keepalive(nil, 0) - _ = _sp_is_mp_keepalive(0, nil) - _ = _sp_main_keepalive(0, nil) - } } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { diff --git a/src/serious_python_darwin/pubspec.yaml b/src/serious_python_darwin/pubspec.yaml index e7c7d4a8..8a0da963 100644 --- a/src/serious_python_darwin/pubspec.yaml +++ b/src/serious_python_darwin/pubspec.yaml @@ -2,7 +2,7 @@ name: serious_python_darwin description: iOS and macOS implementations of the serious_python plugin homepage: https://flet.dev repository: https://github.com/flet-dev/serious-python -version: 4.3.6 +version: 4.4.0 environment: # The Swift Package Manager build path needs Flutter 3.44 / Dart 3.11 (the diff --git a/src/serious_python_linux/CHANGELOG.md b/src/serious_python_linux/CHANGELOG.md index a79a2877..37103e59 100644 --- a/src/serious_python_linux/CHANGELOG.md +++ b/src/serious_python_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.4.0 + +* Re-pins the bundled python-build snapshot to **20260725** (`dart_bridge` **1.5.1 → 1.6.1**). 1.6.1 is an Apple-only packaging change (see `serious_python_darwin` 4.4.0); the Linux runtime is byte-identical to 20260720. + ## 4.3.6 * Re-pins the bundled python-build snapshot to **20260720** (`dart_bridge` **1.5.0 → 1.5.1**). 1.5.1 is a Windows-only UTF-8 startup fix (see `serious_python_windows` 4.3.6); the Linux runtime is functionally unchanged from 20260719. diff --git a/src/serious_python_linux/linux/python_versions.properties b/src/serious_python_linux/linux/python_versions.properties index 1816c017..e2f008ff 100644 --- a/src/serious_python_linux/linux/python_versions.properties +++ b/src/serious_python_linux/linux/python_versions.properties @@ -1,8 +1,8 @@ # GENERATED by `dart run serious_python:gen_version_tables` from -# python-build manifest.json (release 20260720). Do not edit by hand. +# python-build manifest.json (release 20260725). Do not edit by hand. default_python_version=3.14 -dart_bridge_version=1.5.1 -python_build_release_date=20260720 +dart_bridge_version=1.6.1 +python_build_release_date=20260725 3.12.full_version=3.12.13 3.12.android_abis=arm64-v8a,x86_64,armeabi-v7a 3.13.full_version=3.13.14 diff --git a/src/serious_python_linux/pubspec.yaml b/src/serious_python_linux/pubspec.yaml index e7545477..860c1811 100644 --- a/src/serious_python_linux/pubspec.yaml +++ b/src/serious_python_linux/pubspec.yaml @@ -2,7 +2,7 @@ name: serious_python_linux description: Linux implementations of the serious_python plugin homepage: https://flet.dev repository: https://github.com/flet-dev/serious-python -version: 4.3.6 +version: 4.4.0 environment: sdk: '>=3.1.3 <4.0.0' diff --git a/src/serious_python_platform_interface/CHANGELOG.md b/src/serious_python_platform_interface/CHANGELOG.md index 4b5b560f..7b585aba 100644 --- a/src/serious_python_platform_interface/CHANGELOG.md +++ b/src/serious_python_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.4.0 + +* Version bump aligning with the `serious_python_*` 4.4.0 release. + ## 4.3.6 * Version bump aligning with the `serious_python_*` 4.3.6 release (Windows UTF-8 startup fix via `dart_bridge` 1.5.1). No interface changes. diff --git a/src/serious_python_platform_interface/pubspec.yaml b/src/serious_python_platform_interface/pubspec.yaml index 22a7291a..75dd5a0e 100644 --- a/src/serious_python_platform_interface/pubspec.yaml +++ b/src/serious_python_platform_interface/pubspec.yaml @@ -2,7 +2,7 @@ name: serious_python_platform_interface description: A common platform interface for the serious_python plugin. homepage: https://flet.dev repository: https://github.com/flet-dev/serious-python -version: 4.3.6 +version: 4.4.0 environment: sdk: ">=3.0.0 <4.0.0" diff --git a/src/serious_python_windows/CHANGELOG.md b/src/serious_python_windows/CHANGELOG.md index 156a29b2..ab546ebf 100644 --- a/src/serious_python_windows/CHANGELOG.md +++ b/src/serious_python_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.4.0 + +* Re-pins the bundled python-build snapshot to **20260725** (`dart_bridge` **1.5.1 → 1.6.1**). 1.6.1 is an Apple-only packaging change (see `serious_python_darwin` 4.4.0); the Windows runtime is byte-identical to 20260720. + ## 4.3.6 * **Fix Windows startup when app paths or environment values contain non-ASCII characters.** Dart FFI strings arrive as UTF-8, but the Windows boundary passed them straight to the ANSI CRT (`_putenv_s`, `fopen`), corrupting paths/env values through the process code page. The runtime now converts UTF-8 → UTF-16 and uses the wide CRT APIs (`_wputenv_s`, `_wfopen_s`), enables Python UTF-8 mode before `Py_Initialize()`, sets `PYTHONUTF8=1` for multiprocessing helpers, and treats embedded env-setup failures as fatal. Delivered via `dart_bridge` **1.5.1** (bundled python-build snapshot re-pinned to **20260720**). ([flet-dev/flet#6641](https://github.com/flet-dev/flet/issues/6641)) diff --git a/src/serious_python_windows/pubspec.yaml b/src/serious_python_windows/pubspec.yaml index 8524b9f4..bd5f7b75 100644 --- a/src/serious_python_windows/pubspec.yaml +++ b/src/serious_python_windows/pubspec.yaml @@ -2,7 +2,7 @@ name: serious_python_windows description: Windows implementations of the serious_python plugin homepage: https://flet.dev repository: https://github.com/flet-dev/serious-python -version: 4.3.6 +version: 4.4.0 environment: sdk: '>=3.1.3 <4.0.0' diff --git a/src/serious_python_windows/windows/python_versions.properties b/src/serious_python_windows/windows/python_versions.properties index 1816c017..e2f008ff 100644 --- a/src/serious_python_windows/windows/python_versions.properties +++ b/src/serious_python_windows/windows/python_versions.properties @@ -1,8 +1,8 @@ # GENERATED by `dart run serious_python:gen_version_tables` from -# python-build manifest.json (release 20260720). Do not edit by hand. +# python-build manifest.json (release 20260725). Do not edit by hand. default_python_version=3.14 -dart_bridge_version=1.5.1 -python_build_release_date=20260720 +dart_bridge_version=1.6.1 +python_build_release_date=20260725 3.12.full_version=3.12.13 3.12.android_abis=arm64-v8a,x86_64,armeabi-v7a 3.13.full_version=3.13.14