fix(pyo3-ffi): fix _Py_NoneStruct dlopen failure on Android/Termux fo…#6189
fix(pyo3-ffi): fix _Py_NoneStruct dlopen failure on Android/Termux fo…#6189vickXs wants to merge 2 commits into
Conversation
Merging this PR will degrade performance by 12.96%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing |
bschoenmaeckers
left a comment
There was a problem hiding this comment.
Did you verify this works? The changes look AI generated without any real behaviour changes.
| // `_Py_NoneStruct` is excluded only when the abi3 build floor is 3.13+ | ||
| // AND the limited API is enabled (i.e. `abi3-py313` or higher), because | ||
| // in that case `Py_GetConstantBorrowed` is guaranteed to exist and | ||
| // CPython intentionally does not export `_Py_NoneStruct` to the dynamic | ||
| // symbol table. | ||
| // | ||
| // For builds with a *lower* floor (e.g. `abi3-py312`), `Py_3_13` is NOT | ||
| // set even when running on a 3.13+ interpreter -- it tracks the build | ||
| // floor, not the runtime version. We keep `_Py_NoneStruct` declared here | ||
| // for those builds, matching the PyO3 0.28 behaviour, so that the symbol | ||
| // is resolved at dlopen() time against the interpreter that is actually | ||
| // running (which does export it if it is genuinely pre-3.13, and on | ||
| // platforms where it is absent -- e.g. Android/Bionic builds of CPython | ||
| // under Termux -- the correct fix is to use `abi3-py313` or higher so | ||
| // that the `Py_GetConstantBorrowed` path below is taken instead). |
There was a problem hiding this comment.
This is only a comment change. So what are you actually fixing?
|
|
||
| #[inline] | ||
| #[cfg(not(all(Py_LIMITED_API, Py_3_14)))] | ||
| #[cfg(not(Py_3_14))] |
There was a problem hiding this comment.
This is unrelated and should not change.
|
I am highly suspicious of reverting the pyo3-ffi change here. As per my comment on #6165, I believe something is going wrong, but I don't think this is necessarily the right fix. |
|
As per #6165 (comment) this is not the solution. |
On Android/Termux (aarch64, Bionic libc), importing any extension built with PyO3 0.29 and abi3-py312 (e.g django-bolt) fails with:
ImportError: dlopen failed: cannot locate symbol "_Py_NoneStruct"
CPython loads extensions with RTLD_NOW, so all symbols are resolved eagerly at dlopen() time. Termux's Python build does not export _Py_NoneStruct in its dynamic symbol table.
Root cause
PyO3 0.29 added a safe Py_GetConstantBorrowed path in Py_None(), but gated it on Py_3_13 cfg which tracks the build floor, not the running interpreter. So an abi3-py312 build always falls through to _Py_NoneStruct even when running on Python 3.13+.
The Fix
Restore the 0.28 two-branch form of Py_None() — _Py_NoneStruct is only excluded when the build floor is actually 3.13+ (abi3-py313 or higher).
Tested on
Termux aarch64, Python 3.14, abi3-py312 — module imports cleanly after this fix.
Fixes #6165