From 561f1a806846dc685c2c2a4c95b900c2e6c6e7fd Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 29 Oct 2026 00:07:19 +0100 Subject: [PATCH 01/11] Load the release CPython in Windows Debug builds Debug Windows builds (flutter test, flutter run) bundled a debug build of CPython (python3XY_d.dll, loaded through dart_bridge_d.dll). A debug CPython only imports extension modules named *_d.pyd, which PyPI wheels don't ship, so every compiled package (pydantic-core, numpy, ...) failed with ModuleNotFoundError although its .pyd was installed. The debug variant dates from when the plugin itself compiled against Python.h. Since 3.0.0 only dart_bridge touches Python, through FFI, so every build configuration now bundles python3XY.dll, python3.dll and dart_bridge.dll, and the Dart side always opens dart_bridge.dll. --- .../lib/src/dart_bridge_ffi.dart | 7 ++-- .../lib/serious_python_windows.dart | 7 ++-- .../windows/CMakeLists.txt | 33 +++++++++---------- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart b/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart index d4d99a5c..7fa3353a 100644 --- a/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart +++ b/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart @@ -2,7 +2,6 @@ import 'dart:ffi'; import 'dart:io' show Platform; import 'package:ffi/ffi.dart'; -import 'package:flutter/foundation.dart' show kDebugMode; /// FFI bindings for the `dart_bridge` C library published by /// [flet-dev/dart-bridge](https://github.com/flet-dev/dart-bridge). @@ -15,8 +14,7 @@ import 'package:flutter/foundation.dart' show kDebugMode; /// `dart_bridge.xcframework` — looked up through [DynamicLibrary.process]. /// - Android: bundled as `libdart_bridge.so` in jniLibs — opened by name. /// - Linux: bundled next to the executable — opened by name. -/// - Windows: bundled next to the .exe, with a separate Debug-CRT variant -/// `dart_bridge_d.dll` for `fvm flutter run`. +/// - Windows: bundled next to the .exe as `dart_bridge.dll`, in Debug builds too. /// /// Mirrors the C surface declared in /// [dart-bridge/src/dart_bridge.c](https://github.com/flet-dev/dart-bridge/blob/main/src/dart_bridge.c) @@ -159,8 +157,7 @@ class DartBridge { return DynamicLibrary.open('libdart_bridge.so'); } if (Platform.isWindows) { - return DynamicLibrary.open( - kDebugMode ? 'dart_bridge_d.dll' : 'dart_bridge.dll'); + return DynamicLibrary.open('dart_bridge.dll'); } throw UnsupportedError( 'serious_python: dart_bridge has no binary for this platform'); diff --git a/src/serious_python_windows/lib/serious_python_windows.dart b/src/serious_python_windows/lib/serious_python_windows.dart index 5c6861ba..dcce7ebd 100644 --- a/src/serious_python_windows/lib/serious_python_windows.dart +++ b/src/serious_python_windows/lib/serious_python_windows.dart @@ -6,10 +6,9 @@ import 'package:serious_python_platform_interface/serious_python_platform_interf /// Windows implementation of [SeriousPythonPlatform]. /// /// Python lifecycle (env, sys.path, Py_Initialize, run, finalize, sync/async) -/// lives in `serious_python_run`, packaged as `dart_bridge.dll` (Release CRT) -/// or `dart_bridge_d.dll` (Debug CRT) and bundled next to the .exe by this -/// plugin's CMakeLists.txt. The correct DLL is picked at runtime based on -/// [kDebugMode]. +/// lives in `serious_python_run`, packaged as `dart_bridge.dll` and bundled +/// next to the .exe by this plugin's CMakeLists.txt, with the release CPython +/// in every build configuration. /// /// This class derives PYTHONHOME from `Platform.resolvedExecutable` (the /// runner .exe directory, where the bundled CPython lives) and dispatches a diff --git a/src/serious_python_windows/windows/CMakeLists.txt b/src/serious_python_windows/windows/CMakeLists.txt index 97eb4eeb..6acde2d5 100644 --- a/src/serious_python_windows/windows/CMakeLists.txt +++ b/src/serious_python_windows/windows/CMakeLists.txt @@ -124,33 +124,30 @@ if(_py_extract) file(WRITE "${_py_marker}" "${_py_build_id}") endif() -# ---- dart_bridge prebuilt DLLs -------------------------------------------- -# Release CRT (.dll) is what Release Flutter builds consume; Debug CRT -# (_d.dll) is what `fvm flutter run` / Debug builds consume. Both ship in -# every release of flet-dev/dart-bridge; we bundle both and let Flutter's -# CONFIG-aware copy machinery pick the right one at app launch time. +# ---- dart_bridge prebuilt DLL --------------------------------------------- +# Every build configuration, Debug included, bundles the release +# `dart_bridge.dll` and the release CPython it links (python3.dll -> +# python3XY.dll). A Debug CPython would only import extension modules named +# `*_d.pyd`, which PyPI wheels don't ship, so no compiled package +# (pydantic-core, numpy, ...) could be imported in Debug builds such as +# `flutter test` and `flutter run`. Nothing in the plugin links Python, so a +# Debug runner loads the release DLLs as they are. # -# Cached under the upstream arch-qualified filenames so multiple flet-dev/ -# dart-bridge versions can coexist in $FLET_CACHE_DIR. Copied to stable -# unqualified names in the build tree because Flutter's bundled_libraries +# Cached under the upstream arch-qualified filename so multiple flet-dev/ +# dart-bridge versions can coexist in $FLET_CACHE_DIR. Copied to a stable +# unqualified name in the build tree because Flutter's bundled_libraries # machinery preserves filenames as-is, and the Dart side opens the DLL by -# `dart_bridge[_d].dll` (no arch suffix). +# `dart_bridge.dll` (no arch suffix). set(DART_BRIDGE_RELEASE_CACHED "${DB_CACHE}/dart_bridge-windows-x86_64.dll") -set(DART_BRIDGE_DEBUG_CACHED "${DB_CACHE}/dart_bridge_d-windows-x86_64.dll") _sp_download( "https://github.com/flet-dev/dart-bridge/releases/download/v${DART_BRIDGE_VERSION}/dart_bridge-windows-x86_64.dll" "${DART_BRIDGE_RELEASE_CACHED}") -_sp_download( - "https://github.com/flet-dev/dart-bridge/releases/download/v${DART_BRIDGE_VERSION}/dart_bridge_d-windows-x86_64.dll" - "${DART_BRIDGE_DEBUG_CACHED}") set(DART_BRIDGE_DIR "${CMAKE_BINARY_DIR}/dart_bridge") set(DART_BRIDGE_RELEASE_DLL "${DART_BRIDGE_DIR}/dart_bridge.dll") -set(DART_BRIDGE_DEBUG_DLL "${DART_BRIDGE_DIR}/dart_bridge_d.dll") file(MAKE_DIRECTORY "${DART_BRIDGE_DIR}") configure_file("${DART_BRIDGE_RELEASE_CACHED}" "${DART_BRIDGE_RELEASE_DLL}" COPYONLY) -configure_file("${DART_BRIDGE_DEBUG_CACHED}" "${DART_BRIDGE_DEBUG_DLL}" COPYONLY) # Any new source files that you add to the plugin should be added here. list(APPEND PLUGIN_SOURCES @@ -217,9 +214,9 @@ if(EXISTS "${SERIOUS_PYTHON_WINDIR}/Sysnative") endif() set(serious_python_windows_bundled_libraries - "${PYTHON_PACKAGE}/python${PYTHON_VERSION_NODOT}$<$:_d>.dll" - "${PYTHON_PACKAGE}/python3$<$:_d>.dll" - "$,${DART_BRIDGE_DEBUG_DLL},${DART_BRIDGE_RELEASE_DLL}>" + "${PYTHON_PACKAGE}/python${PYTHON_VERSION_NODOT}.dll" + "${PYTHON_PACKAGE}/python3.dll" + "${DART_BRIDGE_RELEASE_DLL}" "${_sp_crt_dir}/msvcp140.dll" "${_sp_crt_dir}/vcruntime140.dll" "${_sp_crt_dir}/vcruntime140_1.dll" From ea673adac84c07c202711f96cffb7827923c9ced Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 29 Oct 2026 00:07:19 +0100 Subject: [PATCH 02/11] Drop CPython's debug modules from Windows Debug builds too Every build configuration loads the release CPython now, so nothing imports the *_d.pyd, *_d.dll and *_d.pdb files in DLLs/. Remove them from Debug builds as well, not only from Release and Profile builds. --- src/serious_python_windows/windows/CMakeLists.txt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/serious_python_windows/windows/CMakeLists.txt b/src/serious_python_windows/windows/CMakeLists.txt index 6acde2d5..68062718 100644 --- a/src/serious_python_windows/windows/CMakeLists.txt +++ b/src/serious_python_windows/windows/CMakeLists.txt @@ -242,12 +242,9 @@ add_custom_command(TARGET CopyPythonDLLs POST_BUILD "${SP_RUNNER_OUT}/DLLs/tk86t.dll" COMMAND ${CMAKE_COMMAND} -DDIR=${SP_RUNNER_OUT}/DLLs -DGLOBS=*.ico\;*.cat -P "${CMAKE_CURRENT_SOURCE_DIR}/rm_globs.cmake" - # Debug-only modules (*_d.pyd, *_d.dll, *_d.pdb) ship in Debug builds only: - # Release and Profile builds load the release ones. (The 3.0.0 move from - # cmd.exe DEL to rm_globs.cmake dropped this, so Release apps carried - # every module twice.) "__none__" matches nothing in Debug builds. - COMMAND ${CMAKE_COMMAND} -DDIR=${SP_RUNNER_OUT}/DLLs - -DGLOBS=$,__none__,*_d.*> + # Debug CPython's modules (*_d.pyd, *_d.dll, *_d.pdb): every build loads + # the release CPython, so nothing imports them. + COMMAND ${CMAKE_COMMAND} -DDIR=${SP_RUNNER_OUT}/DLLs -DGLOBS=*_d.* -P "${CMAKE_CURRENT_SOURCE_DIR}/rm_globs.cmake" ) From 0ecb8654da84e18a0788cf4f87c6d445fd963290 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 29 Oct 2026 00:07:19 +0100 Subject: [PATCH 03/11] Add 6.1.2 changelog entries for the Windows Debug build fix --- src/serious_python/CHANGELOG.md | 4 ++++ src/serious_python_platform_interface/CHANGELOG.md | 4 ++++ src/serious_python_windows/CHANGELOG.md | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/serious_python/CHANGELOG.md b/src/serious_python/CHANGELOG.md index 99556fd5..ce73abe3 100644 --- a/src/serious_python/CHANGELOG.md +++ b/src/serious_python/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.1.2 + +* Windows Debug builds (`flutter test`, `flutter run`) use the release CPython, so compiled packages such as `pydantic-core` or `numpy` import there ([flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). + ## 6.1.1 * Release Windows apps no longer ship Python's debug modules (`*_d.pyd`), about 10 MB each ([#260](https://github.com/flet-dev/serious-python/pull/260)). diff --git a/src/serious_python_platform_interface/CHANGELOG.md b/src/serious_python_platform_interface/CHANGELOG.md index aea44fd8..0920974a 100644 --- a/src/serious_python_platform_interface/CHANGELOG.md +++ b/src/serious_python_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.1.2 + +* On Windows, open `dart_bridge.dll` in Debug builds too, instead of `dart_bridge_d.dll` ([flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). + ## 6.1.1 * Align with the serious_python **6.1.1** release ([#260](https://github.com/flet-dev/serious-python/pull/260)). diff --git a/src/serious_python_windows/CHANGELOG.md b/src/serious_python_windows/CHANGELOG.md index f3ad5b96..ddc35a57 100644 --- a/src/serious_python_windows/CHANGELOG.md +++ b/src/serious_python_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.1.2 + +* **Compiled Python packages import in Debug Windows builds.** Debug builds, such as `flutter test`, `flutter run` and Flet's `flet test`, bundled a debug build of CPython (`python3XY_d.dll` with `dart_bridge_d.dll`), which only imports extension modules named `*_d.pyd`. Wheels from PyPI don't ship those, so packages like `pydantic-core` or `numpy` failed with `ModuleNotFoundError` (e.g. `No module named 'pydantic_core._pydantic_core'`). Every build configuration now bundles the release CPython and `dart_bridge.dll`, and no build ships CPython's `*_d` modules ([flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). + ## 6.1.1 * **Release Windows apps no longer ship Python's debug modules.** The 3.0.0 rewrite of the `DLLs` copy step lost the removal of `*_d.*` from Release builds, so every app carried each extension module twice (`_ctypes.pyd` and `_ctypes_d.pyd`, …): about 10 MB and two dozen files more than needed, and as many extra signatures when the app is code-signed. Release and Profile builds now drop them again; Debug builds keep them ([#260](https://github.com/flet-dev/serious-python/pull/260)). From ed45d2c0732490d195966c2df4d28d84459be7fb Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 29 Oct 2026 00:07:59 +0100 Subject: [PATCH 04/11] Link the PR in the changelogs --- src/serious_python/CHANGELOG.md | 2 +- src/serious_python_platform_interface/CHANGELOG.md | 2 +- src/serious_python_windows/CHANGELOG.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/serious_python/CHANGELOG.md b/src/serious_python/CHANGELOG.md index ce73abe3..aef440e0 100644 --- a/src/serious_python/CHANGELOG.md +++ b/src/serious_python/CHANGELOG.md @@ -1,6 +1,6 @@ ## 6.1.2 -* Windows Debug builds (`flutter test`, `flutter run`) use the release CPython, so compiled packages such as `pydantic-core` or `numpy` import there ([flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). +* Windows Debug builds (`flutter test`, `flutter run`) use the release CPython, so compiled packages such as `pydantic-core` or `numpy` import there ([#261](https://github.com/flet-dev/serious-python/pull/261), [flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). ## 6.1.1 diff --git a/src/serious_python_platform_interface/CHANGELOG.md b/src/serious_python_platform_interface/CHANGELOG.md index 0920974a..af3575a6 100644 --- a/src/serious_python_platform_interface/CHANGELOG.md +++ b/src/serious_python_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## 6.1.2 -* On Windows, open `dart_bridge.dll` in Debug builds too, instead of `dart_bridge_d.dll` ([flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). +* On Windows, open `dart_bridge.dll` in Debug builds too, instead of `dart_bridge_d.dll` ([#261](https://github.com/flet-dev/serious-python/pull/261), [flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). ## 6.1.1 diff --git a/src/serious_python_windows/CHANGELOG.md b/src/serious_python_windows/CHANGELOG.md index ddc35a57..1873b665 100644 --- a/src/serious_python_windows/CHANGELOG.md +++ b/src/serious_python_windows/CHANGELOG.md @@ -1,6 +1,6 @@ ## 6.1.2 -* **Compiled Python packages import in Debug Windows builds.** Debug builds, such as `flutter test`, `flutter run` and Flet's `flet test`, bundled a debug build of CPython (`python3XY_d.dll` with `dart_bridge_d.dll`), which only imports extension modules named `*_d.pyd`. Wheels from PyPI don't ship those, so packages like `pydantic-core` or `numpy` failed with `ModuleNotFoundError` (e.g. `No module named 'pydantic_core._pydantic_core'`). Every build configuration now bundles the release CPython and `dart_bridge.dll`, and no build ships CPython's `*_d` modules ([flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). +* **Compiled Python packages import in Debug Windows builds.** Debug builds, such as `flutter test`, `flutter run` and Flet's `flet test`, bundled a debug build of CPython (`python3XY_d.dll` with `dart_bridge_d.dll`), which only imports extension modules named `*_d.pyd`. Wheels from PyPI don't ship those, so packages like `pydantic-core` or `numpy` failed with `ModuleNotFoundError` (e.g. `No module named 'pydantic_core._pydantic_core'`). Every build configuration now bundles the release CPython and `dart_bridge.dll`, and no build ships CPython's `*_d` modules ([#261](https://github.com/flet-dev/serious-python/pull/261), [flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). ## 6.1.1 From 6798a0aa174f50a2bbd065ca4574a022fcc844d8 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 28 Oct 2026 17:44:05 -0700 Subject: [PATCH 05/11] Test Pydantic native wheels in desktop CI --- .github/workflows/ci.yml | 10 +++++++--- .../example/bridge_example/app/src/main.py | 11 +++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e3a676c..b2f85668 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,6 +82,7 @@ jobs: build_system: ['cocoapods', 'spm'] env: SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }} + BRIDGE_EXAMPLE_TEST_PYDANTIC: "1" steps: - name: Checkout repository uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 @@ -124,7 +125,7 @@ jobs: if [ "${{ matrix.build_system }}" = "cocoapods" ]; then export SERIOUS_PYTHON_DARWIN_SPM=false fi - dart run serious_python:main package app/src --platform Darwin --python-version ${{ matrix.python_version }} + dart run serious_python:main package app/src --platform Darwin --python-version ${{ matrix.python_version }} --requirements "pydantic>=2,<3" if [ "${{ matrix.build_system }}" = "spm" ]; then export SP_NATIVE_SET="$(cat build/.serious_python_spm_key)" fi @@ -370,6 +371,7 @@ jobs: python_version: ['3.12', '3.13', '3.14'] env: SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }} + BRIDGE_EXAMPLE_TEST_PYDANTIC: "1" steps: - name: Checkout repository uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 @@ -397,7 +399,7 @@ jobs: working-directory: "src/serious_python/example/bridge_example" shell: bash run: | - dart run serious_python:main package app/src --platform Windows --python-version ${{ matrix.python_version }} + dart run serious_python:main package app/src --platform Windows --python-version ${{ matrix.python_version }} --requirements "pydantic>=2,<3" # bash + pipefail so the test step actually fails when flutter fails # (default PowerShell shell on windows runners eats the failure when # piping into tail). @@ -446,6 +448,7 @@ jobs: title: ARM64 env: SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }} + BRIDGE_EXAMPLE_TEST_PYDANTIC: "1" steps: - name: Checkout repository uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 @@ -498,7 +501,8 @@ jobs: flutter pub get dart run serious_python:main package app/src \ --platform Linux \ - --python-version ${{ matrix.python_version }} + --python-version ${{ matrix.python_version }} \ + --requirements "pydantic>=2,<3" set -o pipefail # Three back-to-back `xvfb-run` invocations race for display diff --git a/src/serious_python/example/bridge_example/app/src/main.py b/src/serious_python/example/bridge_example/app/src/main.py index 1b10d4fb..0ef9e4cd 100644 --- a/src/serious_python/example/bridge_example/app/src/main.py +++ b/src/serious_python/example/bridge_example/app/src/main.py @@ -27,6 +27,17 @@ import dart_bridge +# Desktop CI packages Pydantic v2 to exercise its native pydantic-core wheel. +# Validate before registering handlers so a failure prevents test readiness. +if os.environ.get("BRIDGE_EXAMPLE_TEST_PYDANTIC") == "1": + from pydantic import BaseModel + + class DependencyProbe(BaseModel): + value: int + + assert DependencyProbe.model_validate({"value": "42"}).value == 42 + print("[bridge_example] Pydantic native extension validation passed", flush=True) + CONTROL_PORT_ENV = "BRIDGE_EXAMPLE_CONTROL_PORT" ECHO_PORT_ENV = "BRIDGE_EXAMPLE_ECHO_PORT" From b46ef2c26cc5fdcd02a288cec661485864d3232c Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 28 Oct 2026 18:16:43 -0700 Subject: [PATCH 06/11] Preserve Linux integration test startup errors --- .github/workflows/ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b2f85668..f3674b95 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -522,9 +522,11 @@ jobs: # Per-file: `flutter test integration_test` (whole dir) reuses one # VM session and the second file fails to start the app. See # bridge_example_macos for the discovery. - flutter test integration_test/interactivity_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v 2>&1 | tail -300 - flutter test integration_test/throughput_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v 2>&1 | tail -300 - flutter test integration_test/memory_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v 2>&1 | tail -300 + # Keep startup tracebacks: verbose CMake install output can push them + # out of a tail filter before the readiness timeout is reported. + flutter test integration_test/interactivity_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v + flutter test integration_test/throughput_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v + flutter test integration_test/memory_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v - name: Diagnostics on failure if: failure() From d365513a79907dd6bc99c0b5d0f4e68a6f9a22ed Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 28 Oct 2026 18:22:05 -0700 Subject: [PATCH 07/11] Report Python startup failures through the test bridge --- .../example/bridge_example/app/src/main.py | 30 ++++++++++++------- .../integration_test/_helpers.dart | 3 ++ .../example/bridge_example/lib/main.dart | 5 ++++ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/serious_python/example/bridge_example/app/src/main.py b/src/serious_python/example/bridge_example/app/src/main.py index 0ef9e4cd..c0068719 100644 --- a/src/serious_python/example/bridge_example/app/src/main.py +++ b/src/serious_python/example/bridge_example/app/src/main.py @@ -27,17 +27,6 @@ import dart_bridge -# Desktop CI packages Pydantic v2 to exercise its native pydantic-core wheel. -# Validate before registering handlers so a failure prevents test readiness. -if os.environ.get("BRIDGE_EXAMPLE_TEST_PYDANTIC") == "1": - from pydantic import BaseModel - - class DependencyProbe(BaseModel): - value: int - - assert DependencyProbe.model_validate({"value": "42"}).value == 42 - print("[bridge_example] Pydantic native extension validation passed", flush=True) - CONTROL_PORT_ENV = "BRIDGE_EXAMPLE_CONTROL_PORT" ECHO_PORT_ENV = "BRIDGE_EXAMPLE_ECHO_PORT" @@ -96,6 +85,25 @@ def _emit(event: dict) -> None: dart_bridge.send_bytes(control_port, json.dumps(event).encode("utf-8")) +# Desktop CI packages Pydantic v2 to exercise its native pydantic-core wheel. +# Validate before registering handlers so a failure prevents test readiness. +if os.environ.get("BRIDGE_EXAMPLE_TEST_PYDANTIC") == "1": + try: + from pydantic import BaseModel + + class DependencyProbe(BaseModel): + value: int + + assert DependencyProbe.model_validate({"value": "42"}).value == 42 + print("[bridge_example] Pydantic native extension validation passed", flush=True) + except Exception: + import traceback + + # Native stderr is not forwarded by every integration-test runner. + _emit({"event": "startup_error", "message": traceback.format_exc()}) + raise + + def on_control(payload: bytes) -> None: global counter if not payload: diff --git a/src/serious_python/example/bridge_example/integration_test/_helpers.dart b/src/serious_python/example/bridge_example/integration_test/_helpers.dart index a0dc7f5e..2c5bc2b5 100644 --- a/src/serious_python/example/bridge_example/integration_test/_helpers.dart +++ b/src/serious_python/example/bridge_example/integration_test/_helpers.dart @@ -23,6 +23,9 @@ Future bootAndAwaitReady(WidgetTester tester) async { // readiness signal for the control channel. final deadline = DateTime.now().add(const Duration(seconds: 30)); while (handle.pythonVersion.value == null) { + if (handle.startupError != null) { + throw StateError('Python startup failed:\n${handle.startupError}'); + } if (DateTime.now().isAfter(deadline)) { throw TimeoutException( 'Python control handler never responded with version event'); diff --git a/src/serious_python/example/bridge_example/lib/main.dart b/src/serious_python/example/bridge_example/lib/main.dart index 5db835f3..12b9b1f9 100644 --- a/src/serious_python/example/bridge_example/lib/main.dart +++ b/src/serious_python/example/bridge_example/lib/main.dart @@ -38,6 +38,9 @@ class BridgeExampleHandle { /// event arrives. final ValueNotifier pythonVersion = ValueNotifier(null); + /// Startup traceback sent over the bridge when a dependency check fails. + String? startupError; + /// Send a JSON control op (Dart → Python) on the control channel. void sendControl(Map op) { final bytes = Uint8List.fromList(utf8.encode(jsonEncode(op))); @@ -123,6 +126,8 @@ class _BridgeExampleAppState extends State { handle.counter.value = msg['value'] as int; } else if (event == 'version') { handle.pythonVersion.value = msg['value'] as String; + } else if (event == 'startup_error') { + handle.startupError = msg['message'] as String; } // 'mem' events are consumed by the memory test directly via its own // listener — no widget-visible state for them. From 2b45904880de5cdb29bd2b5a4bb886955086964a Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 28 Oct 2026 18:27:32 -0700 Subject: [PATCH 08/11] Capture Linux dependency failures outside the Flutter runner --- .github/scripts/probe_linux_python.dart | 40 +++++++++++++++++++ .github/workflows/ci.yml | 4 ++ .../example/bridge_example/lib/main.dart | 18 ++++----- 3 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 .github/scripts/probe_linux_python.dart diff --git a/.github/scripts/probe_linux_python.dart b/.github/scripts/probe_linux_python.dart new file mode 100644 index 00000000..73ca8752 --- /dev/null +++ b/.github/scripts/probe_linux_python.dart @@ -0,0 +1,40 @@ +import 'dart:io'; + +import 'package:path/path.dart' as p; +import 'package:serious_python_platform_interface/src/dart_bridge_ffi.dart'; + +// Run against the installed bundle without Flutter's handling of native stderr. +// Like the app, this loads CPython through dart:ffi, rather than starting a +// Python executable (which would expose its symbols globally). +void main(List args) { + final bundle = p.absolute(args.single); + final stdlib = Directory(bundle) + .listSync() + .whereType() + .singleWhere((d) => RegExp(r'^python3\.\d+$').hasMatch(p.basename(d.path))) + .path; + final paths = [p.join(bundle, 'site-packages'), stdlib]; + final bridge = DartBridge.open(p.join(bundle, 'lib', 'libdart_bridge.so')); + final result = runPython( + bridge: bridge, + script: ''' +import sys +print("Bundled Python:", sys.version, flush=True) +print("Module paths:", sys.path, flush=True) +from pydantic import BaseModel +class Probe(BaseModel): + value: int +assert Probe.model_validate({"value": "42"}).value == 42 +print("Pydantic validation passed", flush=True) +''', + modulePaths: paths, + environmentVariables: { + 'PYTHONHOME': bundle, + 'PYTHONPATH': paths.join(':'), + 'PYTHONUNBUFFERED': '1', + 'PYTHONNOUSERSITE': '1', + }, + sync: true, + ); + exit(result); +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3674b95..46293e47 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -548,6 +548,10 @@ jobs: echo echo "=== Python stdlib dir ===" ls -d $DBG_DIR/python3.* 2>/dev/null | head -5 + echo "=== Bundled Python dependency probe ===" + LD_LIBRARY_PATH="$PWD/$DBG_DIR/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" \ + dart --packages=.dart_tool/package_config.json \ + "$SCRIPTS/probe_linux_python.dart" "$DBG_DIR" publish: name: Publish to pub.dev needs: diff --git a/src/serious_python/example/bridge_example/lib/main.dart b/src/serious_python/example/bridge_example/lib/main.dart index 12b9b1f9..a9849725 100644 --- a/src/serious_python/example/bridge_example/lib/main.dart +++ b/src/serious_python/example/bridge_example/lib/main.dart @@ -75,15 +75,6 @@ void main() { BridgeExampleHandle._instance = BridgeExampleHandle._(control, echo); - // Fire-and-forget: Python's main.py blocks forever waiting for messages. - // Awaiting SeriousPython.run() would deadlock the UI. - unawaited(SeriousPython.run( - environmentVariables: { - _controlPortEnv: '${control.port}', - _echoPortEnv: '${echo.port}', - }, - )); - runApp(const BridgeExampleApp()); } @@ -104,6 +95,15 @@ class _BridgeExampleAppState extends State { final handle = BridgeExampleHandle.instance; _controlSub = handle.controlBridge.messages.listen(_onControl); + // Subscribe before starting Python so even an immediate startup failure + // reaches the test harness. main.py blocks forever, so don't await it. + unawaited(SeriousPython.run( + environmentVariables: { + _controlPortEnv: '${handle.controlBridge.port}', + _echoPortEnv: '${handle.echoBridge.port}', + }, + )); + // Request the Python version once Python has had a moment to register // its handler. sendControl() retries internally if the handler isn't // ready yet, so we can fire immediately. From 402b17f08df80615b2ff01b6a47ade61c7d81ee9 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 28 Oct 2026 18:31:56 -0700 Subject: [PATCH 09/11] Expose embedded CPython symbols to Linux extension wheels --- .../lib/src/dart_bridge_ffi.dart | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart b/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart index 7fa3353a..d44053de 100644 --- a/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart +++ b/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart @@ -13,7 +13,8 @@ import 'package:ffi/ffi.dart'; /// - Apple (macOS/iOS): statically linked into the host app via /// `dart_bridge.xcframework` — looked up through [DynamicLibrary.process]. /// - Android: bundled as `libdart_bridge.so` in jniLibs — opened by name. -/// - Linux: bundled next to the executable — opened by name. +/// - Linux: bundled next to the executable — opened with global symbols so +/// Python extension wheels can resolve the CPython API. /// - Windows: bundled next to the .exe as `dart_bridge.dll`, in Debug builds too. /// /// Mirrors the C surface declared in @@ -142,19 +143,51 @@ class DartBridge { /// Test/override entry point: open a specific library path. Replaces the /// cached instance. static DartBridge open(String path) => - _instance = DartBridge._(DynamicLibrary.open(path)); + _instance = DartBridge._(_openLibrary(path)); /// Test/override entry point: resolve from the host process (Apple). /// Replaces the cached instance. static DartBridge process() => _instance = DartBridge._(DynamicLibrary.process()); + static DynamicLibrary _openLibrary(String path) { + if (!Platform.isLinux) return DynamicLibrary.open(path); + + // dart:ffi uses RTLD_LOCAL on Linux. Extension wheels generally leave + // their CPython symbols unresolved, expecting the embedding interpreter + // to provide them globally. RTLD_GLOBAL also exposes the bridge's + // libpython dependencies, including the version-specific CPython library. + final process = DynamicLibrary.process(); + final dlopen = process.lookupFunction< + Pointer Function(Pointer, Int32), + Pointer Function(Pointer, int)>('dlopen'); + final dlclose = process.lookupFunction), + int Function(Pointer)>('dlclose'); + const rtldLazy = 0x1; + const rtldGlobal = 0x100; + final handle = using((arena) => dlopen( + path.toNativeUtf8(allocator: arena), rtldLazy | rtldGlobal)); + if (handle == nullptr) { + final dlerror = process.lookupFunction Function(), + Pointer Function()>('dlerror'); + final error = dlerror(); + throw ArgumentError('Failed to load $path: ' + '${error == nullptr ? "unknown dlopen error" : error.toDartString()}'); + } + try { + return DynamicLibrary.open(path); + } finally { + // DynamicLibrary.open retains its own reference to the global library. + dlclose(handle); + } + } + static DynamicLibrary _loadDefault() { if (Platform.isMacOS || Platform.isIOS) { return DynamicLibrary.process(); } if (Platform.isAndroid || Platform.isLinux) { - return DynamicLibrary.open('libdart_bridge.so'); + return _openLibrary('libdart_bridge.so'); } if (Platform.isWindows) { return DynamicLibrary.open('dart_bridge.dll'); From 9a9295b8c4e51237e0b81c511ce2569eb9691fd2 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 28 Oct 2026 19:17:36 -0700 Subject: [PATCH 10/11] Finalize desktop import fixes and remove temporary diagnostics --- .github/scripts/probe_linux_python.dart | 40 ------------------- .github/workflows/ci.yml | 12 ++---- src/serious_python/CHANGELOG.md | 1 + src/serious_python_linux/CHANGELOG.md | 4 ++ .../CHANGELOG.md | 1 + .../lib/src/dart_bridge_ffi.dart | 10 ++++- 6 files changed, 18 insertions(+), 50 deletions(-) delete mode 100644 .github/scripts/probe_linux_python.dart diff --git a/.github/scripts/probe_linux_python.dart b/.github/scripts/probe_linux_python.dart deleted file mode 100644 index 73ca8752..00000000 --- a/.github/scripts/probe_linux_python.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:serious_python_platform_interface/src/dart_bridge_ffi.dart'; - -// Run against the installed bundle without Flutter's handling of native stderr. -// Like the app, this loads CPython through dart:ffi, rather than starting a -// Python executable (which would expose its symbols globally). -void main(List args) { - final bundle = p.absolute(args.single); - final stdlib = Directory(bundle) - .listSync() - .whereType() - .singleWhere((d) => RegExp(r'^python3\.\d+$').hasMatch(p.basename(d.path))) - .path; - final paths = [p.join(bundle, 'site-packages'), stdlib]; - final bridge = DartBridge.open(p.join(bundle, 'lib', 'libdart_bridge.so')); - final result = runPython( - bridge: bridge, - script: ''' -import sys -print("Bundled Python:", sys.version, flush=True) -print("Module paths:", sys.path, flush=True) -from pydantic import BaseModel -class Probe(BaseModel): - value: int -assert Probe.model_validate({"value": "42"}).value == 42 -print("Pydantic validation passed", flush=True) -''', - modulePaths: paths, - environmentVariables: { - 'PYTHONHOME': bundle, - 'PYTHONPATH': paths.join(':'), - 'PYTHONUNBUFFERED': '1', - 'PYTHONNOUSERSITE': '1', - }, - sync: true, - ); - exit(result); -} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 46293e47..b2f85668 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -522,11 +522,9 @@ jobs: # Per-file: `flutter test integration_test` (whole dir) reuses one # VM session and the second file fails to start the app. See # bridge_example_macos for the discovery. - # Keep startup tracebacks: verbose CMake install output can push them - # out of a tail filter before the readiness timeout is reported. - flutter test integration_test/interactivity_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v - flutter test integration_test/throughput_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v - flutter test integration_test/memory_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v + flutter test integration_test/interactivity_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v 2>&1 | tail -300 + flutter test integration_test/throughput_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v 2>&1 | tail -300 + flutter test integration_test/memory_test.dart -d linux --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} -v 2>&1 | tail -300 - name: Diagnostics on failure if: failure() @@ -548,10 +546,6 @@ jobs: echo echo "=== Python stdlib dir ===" ls -d $DBG_DIR/python3.* 2>/dev/null | head -5 - echo "=== Bundled Python dependency probe ===" - LD_LIBRARY_PATH="$PWD/$DBG_DIR/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" \ - dart --packages=.dart_tool/package_config.json \ - "$SCRIPTS/probe_linux_python.dart" "$DBG_DIR" publish: name: Publish to pub.dev needs: diff --git a/src/serious_python/CHANGELOG.md b/src/serious_python/CHANGELOG.md index aef440e0..1bef7fd3 100644 --- a/src/serious_python/CHANGELOG.md +++ b/src/serious_python/CHANGELOG.md @@ -1,6 +1,7 @@ ## 6.1.2 * Windows Debug builds (`flutter test`, `flutter run`) use the release CPython, so compiled packages such as `pydantic-core` or `numpy` import there ([#261](https://github.com/flet-dev/serious-python/pull/261), [flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). +* Fix native Python extension imports on Linux, including `pydantic-core`, which failed with unresolved CPython symbols such as `PyExc_RecursionError` ([#261](https://github.com/flet-dev/serious-python/pull/261)). ## 6.1.1 diff --git a/src/serious_python_linux/CHANGELOG.md b/src/serious_python_linux/CHANGELOG.md index 6427ce9e..c71fe8c1 100644 --- a/src/serious_python_linux/CHANGELOG.md +++ b/src/serious_python_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.1.2 + +* Fix native Python extension imports, including `pydantic-core`, which failed with unresolved CPython symbols such as `PyExc_RecursionError` ([#261](https://github.com/flet-dev/serious-python/pull/261)). + ## 6.1.1 * Align with the serious_python **6.1.1** release ([#260](https://github.com/flet-dev/serious-python/pull/260)). diff --git a/src/serious_python_platform_interface/CHANGELOG.md b/src/serious_python_platform_interface/CHANGELOG.md index af3575a6..45269547 100644 --- a/src/serious_python_platform_interface/CHANGELOG.md +++ b/src/serious_python_platform_interface/CHANGELOG.md @@ -1,6 +1,7 @@ ## 6.1.2 * On Windows, open `dart_bridge.dll` in Debug builds too, instead of `dart_bridge_d.dll` ([#261](https://github.com/flet-dev/serious-python/pull/261), [flet-dev/flet#7020](https://github.com/flet-dev/flet/discussions/7020)). +* On Linux, load the bridge and its CPython dependencies with global symbol visibility so native Python extension wheels can resolve the CPython API ([#261](https://github.com/flet-dev/serious-python/pull/261)). ## 6.1.1 diff --git a/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart b/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart index d44053de..1b3aad46 100644 --- a/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart +++ b/src/serious_python_platform_interface/lib/src/dart_bridge_ffi.dart @@ -2,6 +2,7 @@ import 'dart:ffi'; import 'dart:io' show Platform; import 'package:ffi/ffi.dart'; +import 'package:flutter/foundation.dart' show kDebugMode; /// FFI bindings for the `dart_bridge` C library published by /// [flet-dev/dart-bridge](https://github.com/flet-dev/dart-bridge). @@ -190,7 +191,14 @@ class DartBridge { return _openLibrary('libdart_bridge.so'); } if (Platform.isWindows) { - return DynamicLibrary.open('dart_bridge.dll'); + try { + return DynamicLibrary.open('dart_bridge.dll'); + } on ArgumentError { + // Older serious_python_windows 6.x versions only bundle the debug + // DLL in Debug builds, and allow newer platform-interface versions. + if (!kDebugMode) rethrow; + return DynamicLibrary.open('dart_bridge_d.dll'); + } } throw UnsupportedError( 'serious_python: dart_bridge has no binary for this platform'); From 7e7c3277da51218bf3f2b69ef1d3156bfb304ccd Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Thu, 29 Oct 2026 09:39:34 -0700 Subject: [PATCH 11/11] Bump all packages to 6.1.2 --- .../example/flask_example/pubspec.lock | 12 ++++++------ src/serious_python/example/run_example/pubspec.lock | 12 ++++++------ src/serious_python/pubspec.yaml | 2 +- src/serious_python_android/CHANGELOG.md | 4 ++++ src/serious_python_android/android/build.gradle.kts | 2 +- src/serious_python_android/pubspec.yaml | 2 +- src/serious_python_darwin/CHANGELOG.md | 4 ++++ .../darwin/serious_python_darwin.podspec | 2 +- src/serious_python_darwin/pubspec.yaml | 2 +- src/serious_python_linux/pubspec.yaml | 2 +- src/serious_python_platform_interface/pubspec.yaml | 2 +- src/serious_python_windows/pubspec.yaml | 2 +- 12 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/serious_python/example/flask_example/pubspec.lock b/src/serious_python/example/flask_example/pubspec.lock index ee2c371a..fa02eea7 100644 --- a/src/serious_python/example/flask_example/pubspec.lock +++ b/src/serious_python/example/flask_example/pubspec.lock @@ -361,42 +361,42 @@ packages: path: "../.." relative: true source: path - version: "6.1.1" + version: "6.1.2" serious_python_android: dependency: transitive description: path: "../../../serious_python_android" relative: true source: path - version: "6.1.1" + version: "6.1.2" serious_python_darwin: dependency: transitive description: path: "../../../serious_python_darwin" relative: true source: path - version: "6.1.1" + version: "6.1.2" serious_python_linux: dependency: transitive description: path: "../../../serious_python_linux" relative: true source: path - version: "6.1.1" + version: "6.1.2" serious_python_platform_interface: dependency: transitive description: path: "../../../serious_python_platform_interface" relative: true source: path - version: "6.1.1" + version: "6.1.2" serious_python_windows: dependency: transitive description: path: "../../../serious_python_windows" relative: true source: path - version: "6.1.1" + version: "6.1.2" shelf: dependency: transitive description: diff --git a/src/serious_python/example/run_example/pubspec.lock b/src/serious_python/example/run_example/pubspec.lock index bf721fe5..08f3bae4 100644 --- a/src/serious_python/example/run_example/pubspec.lock +++ b/src/serious_python/example/run_example/pubspec.lock @@ -384,42 +384,42 @@ packages: path: "../.." relative: true source: path - version: "6.1.1" + version: "6.1.2" serious_python_android: dependency: transitive description: path: "../../../serious_python_android" relative: true source: path - version: "6.1.1" + version: "6.1.2" serious_python_darwin: dependency: transitive description: path: "../../../serious_python_darwin" relative: true source: path - version: "6.1.1" + version: "6.1.2" serious_python_linux: dependency: transitive description: path: "../../../serious_python_linux" relative: true source: path - version: "6.1.1" + version: "6.1.2" serious_python_platform_interface: dependency: transitive description: path: "../../../serious_python_platform_interface" relative: true source: path - version: "6.1.1" + version: "6.1.2" serious_python_windows: dependency: transitive description: path: "../../../serious_python_windows" relative: true source: path - version: "6.1.1" + version: "6.1.2" shelf: dependency: transitive description: diff --git a/src/serious_python/pubspec.yaml b/src/serious_python/pubspec.yaml index 32ac0699..42695975 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: 6.1.1 +version: 6.1.2 platforms: ios: diff --git a/src/serious_python_android/CHANGELOG.md b/src/serious_python_android/CHANGELOG.md index 8007f5c8..d0409168 100644 --- a/src/serious_python_android/CHANGELOG.md +++ b/src/serious_python_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.1.2 + +* Align with the serious_python **6.1.2** release ([#261](https://github.com/flet-dev/serious-python/pull/261)). + ## 6.1.1 * Align with the serious_python **6.1.1** release ([#260](https://github.com/flet-dev/serious-python/pull/260)). diff --git a/src/serious_python_android/android/build.gradle.kts b/src/serious_python_android/android/build.gradle.kts index b6c3d48e..2dd352bf 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 = "6.1.1" +version = "6.1.2" rootProject.allprojects { repositories { diff --git a/src/serious_python_android/pubspec.yaml b/src/serious_python_android/pubspec.yaml index 52bfbbf7..d53fcd00 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: 6.1.1 +version: 6.1.2 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 3cffc859..4c1a2889 100644 --- a/src/serious_python_darwin/CHANGELOG.md +++ b/src/serious_python_darwin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.1.2 + +* Align with the serious_python **6.1.2** release ([#261](https://github.com/flet-dev/serious-python/pull/261)). + ## 6.1.1 * Align with the serious_python **6.1.1** release ([#260](https://github.com/flet-dev/serious-python/pull/260)). diff --git a/src/serious_python_darwin/darwin/serious_python_darwin.podspec b/src/serious_python_darwin/darwin/serious_python_darwin.podspec index 732cf5ec..bd4b0861 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 = '6.1.1' + s.version = '6.1.2' 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. diff --git a/src/serious_python_darwin/pubspec.yaml b/src/serious_python_darwin/pubspec.yaml index 779bd10c..ffd0b2e9 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: 6.1.1 +version: 6.1.2 environment: # The Swift Package Manager build path needs Flutter 3.44 / Dart 3.11 (the diff --git a/src/serious_python_linux/pubspec.yaml b/src/serious_python_linux/pubspec.yaml index fad83f0e..d1797f8e 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: 6.1.1 +version: 6.1.2 environment: sdk: '>=3.1.3 <4.0.0' diff --git a/src/serious_python_platform_interface/pubspec.yaml b/src/serious_python_platform_interface/pubspec.yaml index 383e555f..002556c8 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: 6.1.1 +version: 6.1.2 environment: sdk: ">=3.0.0 <4.0.0" diff --git a/src/serious_python_windows/pubspec.yaml b/src/serious_python_windows/pubspec.yaml index ceb2221a..2479c26b 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: 6.1.1 +version: 6.1.2 environment: sdk: '>=3.1.3 <4.0.0'