-
Notifications
You must be signed in to change notification settings - Fork 38
Fixed app restart on Android 10, Python output redirect to logcat #187
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
Conversation
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
Refactored the setenv function to return a Future<void> and updated all calls to setenv to use await. This ensures environment variables are set in the correct order before proceeding.
Introduces a guard to prevent repeated initialization and finalization of the CPython interpreter, addressing crashes on second launch with CPython 3.12. Also ensures the current native thread is registered with the GIL when running Python code, improving stability when re-entering Python from new Dart isolates or threads.
Updated the debugPrint statement to remove the 'Warning:' prefix when unable to load libpyjni.so. This change streamlines log output for consistency.
This reverts commit 3f4adc0.
Replaces direct debugPrint calls with a private _debug function for consistent logging. Adds a check to only initialize the Python runtime if it is not already active, and removes unconditional Py_Finalize call to avoid finalizing an already active runtime.
Introduces a Python initialization script that redirects stdout and stderr to Android logcat using a custom writer and logging handler. Adds a Dart function to inject this script into the Python interpreter, ensuring Python logs are visible in Android logcat. Also adds debug messages to trace script execution.
Introduced a _withGIL helper to wrap all calls to the Python C API with GIL acquisition and release. This change improves thread safety and correctness when interacting with the Python interpreter from Dart, especially in isolate contexts.
Moved _withGIL calls to wrap larger code blocks instead of individual function calls in runPythonProgramInIsolate and getPythonError. This simplifies the code and reduces redundant GIL management, improving readability and maintainability.
Replaces flutter/foundation.dart with flutter/widgets.dart and adds an AppLifecycleListener to call Py_FinalizeEx when the app detaches. This ensures proper cleanup of the Python interpreter when the app lifecycle ends.
Removed AppLifecycleListener-based finalization and now explicitly call cpython.Py_FinalizeEx() at the end of runPythonProgramInIsolate. This ensures Python finalization occurs after the program finishes, improving resource management.
The calls to cpython.Py_FinalizeEx() and its debug log have been commented out in runPythonProgramInIsolate. This may be to prevent issues related to finalizing the Python interpreter in this context.
Refactored runPythonProgramInIsolate to always finalize the Python interpreter in a finally block, ensuring proper cleanup and GIL management after script or module execution.
Introduced the _finalizeInterpreter function to safely finalize the CPython interpreter without releasing the GIL after Py_FinalizeEx, preventing fatal errors. Updated runPythonProgramInIsolate to use this new function for proper cleanup.
Replaced incorrect use of Py_DecRef with malloc.free for freeing native UTF-8 strings allocated with toNativeUtf8. This ensures proper memory management and prevents potential memory leaks.
Refactored _finalizeInterpreter to remove unnecessary GIL release after Py_FinalizeEx. Interpreter is no longer finalized in runPythonProgramInIsolate to prevent crashes when re-initializing extension modules on Android.
The GIL acquisition and release logic in _withGIL has been commented out, and the function now directly executes the action. Interpreter finalization code in runPythonProgramInIsolate remains commented out, with updated comments explaining the rationale.
Uncommented code to properly acquire and release the Python GIL in _withGIL, and to finalize the interpreter after running a Python program in an isolate. This ensures thread safety and clean interpreter state between runs.
Ensures logcat forwarding is idempotent across Dart isolate restarts and avoids finalizing the CPython interpreter between runs to prevent native crashes. Also refines isolate management to prevent killing isolates that may leave the interpreter in a bad state, and improves error handling for logcat forwarding setup.
Each Python invocation now runs in a fresh sub-interpreter to reduce cross-run leakage and prevent GIL deadlocks. The logcat initialization script is now idempotent and only runs once per process. The unused _finalizeInterpreter function was removed.
Introduces a 'terminate' method to the Android plugin and Dart interface, allowing the app to kill its process for a clean restart. Also disables GIL management in _withGIL due to potential issues with embedded CPython state after Dart isolate restarts.
Uncommented and restored the logic to acquire and release the Python GIL in the _withGIL function, ensuring thread safety when interacting with the Python interpreter.
Simplifies the CPython FFI execution flow by removing sub-interpreter usage and the custom GIL management helper. Updates error handling, logging, and resource management to use debugPrint and proper finalization. Also improves asynchronous execution and logcat forwarding setup.
Introduced a new spDebug function in src/log.dart to standardize debug logging with a '[serious_python]' prefix. Updated all debugPrint calls in serious_python_android.dart and cpython.dart to use spDebug for consistent log output.
Added debug statements to log when CPython is loaded and when Python is already initialized, aiding in troubleshooting and execution flow visibility.
Adds a debugPrint statement to log when the asset hash file is not found during asset extraction, aiding in debugging missing hash issues.
Added debugPrint statements to log asset hash extraction, hash file writing, and conditional hash file operations in extractAssetOrFile. This improves traceability and debugging of asset handling.
Moved asset hash reading outside of the checkHash block to ensure it is always attempted. Removed redundant debug prints and simplified hash file writing logic.
Eliminated the handling of the 'terminate' method call, including the delayed process termination logic, from the AndroidPlugin class.
Deleted unused imports for Handler, Looper, and Process to clean up the code and improve maintainability.
The terminate() override and its related comments were removed from SeriousPythonAndroid. This simplifies the class and removes the process termination logic previously handled via methodChannel.
Release 0.9.7 for all serious_python packages. This update fixes app restart on Android 10 and redirects Python output to logcat. All relevant pubspec, build, and podspec files have been updated to reflect the new version.
Creeper19472
pushed a commit
to cfms-dev/serious-python
that referenced
this pull request
Dec 22, 2025
…et-dev#187) * Make setenv calls awaitable in Python init Refactored the setenv function to return a Future<void> and updated all calls to setenv to use await. This ensures environment variables are set in the correct order before proceeding. * Ensure single CPython interpreter per process Introduces a guard to prevent repeated initialization and finalization of the CPython interpreter, addressing crashes on second launch with CPython 3.12. Also ensures the current native thread is registered with the GIL when running Python code, improving stability when re-entering Python from new Dart isolates or threads. * Remove 'Warning:' prefix from debug message Updated the debugPrint statement to remove the 'Warning:' prefix when unable to load libpyjni.so. This change streamlines log output for consistency. * Revert "Ensure single CPython interpreter per process" This reverts commit 3f4adc0. * Refactor debug logging and Python runtime init Replaces direct debugPrint calls with a private _debug function for consistent logging. Adds a check to only initialize the Python runtime if it is not already active, and removes unconditional Py_Finalize call to avoid finalizing an already active runtime. * Add logcat forwarding for Python stdout/stderr Introduces a Python initialization script that redirects stdout and stderr to Android logcat using a custom writer and logging handler. Adds a Dart function to inject this script into the Python interpreter, ensuring Python logs are visible in Android logcat. Also adds debug messages to trace script execution. * Ensure GIL is held for all Python C API calls Introduced a _withGIL helper to wrap all calls to the Python C API with GIL acquisition and release. This change improves thread safety and correctness when interacting with the Python interpreter from Dart, especially in isolate contexts. * Refactor GIL usage in Python execution and error handling Moved _withGIL calls to wrap larger code blocks instead of individual function calls in runPythonProgramInIsolate and getPythonError. This simplifies the code and reduces redundant GIL management, improving readability and maintainability. * Add AppLifecycleListener to finalize Python on detach Replaces flutter/foundation.dart with flutter/widgets.dart and adds an AppLifecycleListener to call Py_FinalizeEx when the app detaches. This ensures proper cleanup of the Python interpreter when the app lifecycle ends. * Move Py_FinalizeEx call to end of isolate function Removed AppLifecycleListener-based finalization and now explicitly call cpython.Py_FinalizeEx() at the end of runPythonProgramInIsolate. This ensures Python finalization occurs after the program finishes, improving resource management. * Comment out Py_FinalizeEx call in runPythonProgramInIsolate The calls to cpython.Py_FinalizeEx() and its debug log have been commented out in runPythonProgramInIsolate. This may be to prevent issues related to finalizing the Python interpreter in this context. * Ensure Python interpreter finalization after execution Refactored runPythonProgramInIsolate to always finalize the Python interpreter in a finally block, ensuring proper cleanup and GIL management after script or module execution. * Add safe interpreter finalization for CPython Introduced the _finalizeInterpreter function to safely finalize the CPython interpreter without releasing the GIL after Py_FinalizeEx, preventing fatal errors. Updated runPythonProgramInIsolate to use this new function for proper cleanup. * Fix memory deallocation for native UTF-8 strings Replaced incorrect use of Py_DecRef with malloc.free for freeing native UTF-8 strings allocated with toNativeUtf8. This ensures proper memory management and prevents potential memory leaks. * Update interpreter finalization logic for Android Refactored _finalizeInterpreter to remove unnecessary GIL release after Py_FinalizeEx. Interpreter is no longer finalized in runPythonProgramInIsolate to prevent crashes when re-initializing extension modules on Android. * Comment out GIL management in _withGIL function The GIL acquisition and release logic in _withGIL has been commented out, and the function now directly executes the action. Interpreter finalization code in runPythonProgramInIsolate remains commented out, with updated comments explaining the rationale. * Enable GIL management and interpreter finalization Uncommented code to properly acquire and release the Python GIL in _withGIL, and to finalize the interpreter after running a Python program in an isolate. This ensures thread safety and clean interpreter state between runs. * Improve CPython isolate handling and logcat setup Ensures logcat forwarding is idempotent across Dart isolate restarts and avoids finalizing the CPython interpreter between runs to prevent native crashes. Also refines isolate management to prevent killing isolates that may leave the interpreter in a bad state, and improves error handling for logcat forwarding setup. * Refactor Python execution to use sub-interpreters Each Python invocation now runs in a fresh sub-interpreter to reduce cross-run leakage and prevent GIL deadlocks. The logcat initialization script is now idempotent and only runs once per process. The unused _finalizeInterpreter function was removed. * Add process termination support for Android plugin Introduces a 'terminate' method to the Android plugin and Dart interface, allowing the app to kill its process for a clean restart. Also disables GIL management in _withGIL due to potential issues with embedded CPython state after Dart isolate restarts. * Enable GIL management in _withGIL function Uncommented and restored the logic to acquire and release the Python GIL in the _withGIL function, ensuring thread safety when interacting with the Python interpreter. * Refactor CPython FFI execution and error handling Simplifies the CPython FFI execution flow by removing sub-interpreter usage and the custom GIL management helper. Updates error handling, logging, and resource management to use debugPrint and proper finalization. Also improves asynchronous execution and logcat forwarding setup. * Replace debugPrint with spDebug and add log utility Introduced a new spDebug function in src/log.dart to standardize debug logging with a '[serious_python]' prefix. Updated all debugPrint calls in serious_python_android.dart and cpython.dart to use spDebug for consistent log output. * Add debug logs for CPython loading and initialization Added debug statements to log when CPython is loaded and when Python is already initialized, aiding in troubleshooting and execution flow visibility. * Add debug print for missing asset hash file Adds a debugPrint statement to log when the asset hash file is not found during asset extraction, aiding in debugging missing hash issues. * Add debug prints for asset hash extraction and writing Added debugPrint statements to log asset hash extraction, hash file writing, and conditional hash file operations in extractAssetOrFile. This improves traceability and debugging of asset handling. * Refactor asset hash reading in extractAssetOrFile Moved asset hash reading outside of the checkHash block to ensure it is always attempted. Removed redundant debug prints and simplified hash file writing logic. * Remove terminate method from AndroidPlugin Eliminated the handling of the 'terminate' method call, including the delayed process termination logic, from the AndroidPlugin class. * Remove unused imports from AndroidPlugin.java Deleted unused imports for Handler, Looper, and Process to clean up the code and improve maintainability. * Remove terminate method from SeriousPythonAndroid The terminate() override and its related comments were removed from SeriousPythonAndroid. This simplifies the class and removes the process termination logic previously handled via methodChannel. * Bump version to 0.9.7 and update changelogs Release 0.9.7 for all serious_python packages. This update fixes app restart on Android 10 and redirects Python output to logcat. All relevant pubspec, build, and podspec files have been updated to reflect the new version.
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.
No description provided.