Commit 7e8a923
fix(android): make PEP 734 subinterpreters work (
* fix(android): make subinterpreters able to import relocated native modules
PEP 734 subinterpreters (Python 3.14 concurrent.interpreters /
InterpreterPoolExecutor) were unusable in Android apps: the main
interpreter works, but every subinterpreter failed to import any C
extension (ModuleNotFoundError: _struct / _interpqueues / ...), which
breaks the whole feature (its cross-interpreter transport pickles ->
_struct, and its queues need _interpqueues). iOS and desktop are
unaffected.
Root cause: Android relocates C extensions (native-mmap packaging) and
resolves them through the custom _SorefFinder installed 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 and could import no relocated .so. Verified
on-device: main meta_path has _SorefFinder, a subinterpreter's does not.
Fix: teach every new subinterpreter to install the finder. Split the
finder insertion into _install_finder(), and make install() also call a
new _patch_subinterpreters() that wraps concurrent.interpreters.create()
so each new interpreter runs `import _sp_bootstrap; _sp_bootstrap.install()`.
The setup runs via Interpreter.exec() -- a source string, which is
pickle-free (unlike Interpreter.call()), so it works BEFORE _struct is
importable in the child. (A fresh subinterpreter inherits the
process-wide sys.path, so no sys.path seeding is needed --
verified on-device.)
Notes:
- No dart-bridge / C change: the existing Android bootstrap already calls
install(), which now triggers the patch. The wrapper is tagged
`_sp_patched` for idempotency.
- create() is the factory InterpreterPoolExecutor uses
(WorkerContext.initialize -> interpreters.create()), so patching it
fixes the pool transparently -- with no user code change.
- A user-supplied InterpreterPoolExecutor(initializer=...) can NOT fix
this: the initializer is delivered over the same broken pickle path, so
the finder must be installed at interpreter-creation time.
- No-op before 3.14 (module absent) and on iOS/desktop (this file is
Android-only). Idempotent; supports nested subinterpreters.
Verified end-to-end on an Android 15 / arm64-v8a emulator (Python
3.14.6): the clean probe app -- with no app-level workaround -- runs a
low-level create+queue round-trip, an InterpreterPoolExecutor across 4
interpreters in one process, and imports a C extension inside a
subinterpreter.
* docs: note the Android subinterpreter fix under 4.3.6
Fold the subinterpreter fix into the existing 4.3.6 section (main jumped
4.3.4 -> 4.3.6 with the Windows UTF-8 release; our 4.3.5 draft was
rebased away): a detailed bullet in serious_python_android and a
summary bullet in serious_python (umbrella). The Apple/Windows/Linux/
interface packages already carry their 4.3.6 entries from the Windows
release and are unaffected by this Android-only change. No pubspec bump
needed — this rides in the same 4.3.6 that main is already on.
* docs+debug: note create()-attribute assumption; stderr breadcrumb on child finder-install failure
---------
Co-authored-by: Feodor Fitsner <feodor@appveyor.com>concurrent.interpreters / InterpreterPoolExecutor) (#239)1 parent daada1a commit 7e8a923
3 files changed
Lines changed: 64 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
136 | 136 | | |
137 | 137 | | |
138 | 138 | | |
139 | | - | |
| 139 | + | |
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
| |||
158 | 158 | | |
159 | 159 | | |
160 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
0 commit comments