Skip to content

fix(pyo3-ffi): fix _Py_NoneStruct dlopen failure on Android/Termux fo…#6189

Closed
vickXs wants to merge 2 commits into
PyO3:mainfrom
vickXs:fix-py-none-abi3-android
Closed

fix(pyo3-ffi): fix _Py_NoneStruct dlopen failure on Android/Termux fo…#6189
vickXs wants to merge 2 commits into
PyO3:mainfrom
vickXs:fix-py-none-abi3-android

Conversation

@vickXs

@vickXs vickXs commented Jul 5, 2026

Copy link
Copy Markdown

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

@codspeed-hq

codspeed-hq Bot commented Jul 5, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 12.96%

❌ 10 regressed benchmarks
✅ 130 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
extract_i128_small_pos 1 µs 1.2 µs -15.09%
extract_i128_zero 1.1 µs 1.3 µs -14.74%
extract_i128_small_neg 1.1 µs 1.3 µs -14.03%
extract_u128_small 1 µs 1.2 µs -13.35%
extract_u128_zero 1 µs 1.2 µs -13.02%
extract_i128_pos_max 1.3 µs 1.5 µs -12.57%
extract_i128_neg_min 1.3 µs 1.5 µs -12.55%
extract_u128_u32_max 1.1 µs 1.3 µs -12.28%
extract_u128_u64_max 1.3 µs 1.4 µs -11.05%
extract_u128_max 1.3 µs 1.4 µs -10.81%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing vickXs:fix-py-none-abi3-android (1d28c1d) with main (0ef7321)

Open in CodSpeed

@bschoenmaeckers bschoenmaeckers left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you verify this works? The changes look AI generated without any real behaviour changes.

Comment thread pyo3-ffi/src/object.rs
Comment on lines +649 to +663
// `_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).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only a comment change. So what are you actually fixing?

Comment thread pyo3-ffi/src/object.rs

#[inline]
#[cfg(not(all(Py_LIMITED_API, Py_3_14)))]
#[cfg(not(Py_3_14))]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated and should not change.

@davidhewitt

Copy link
Copy Markdown
Member

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.

@davidhewitt

Copy link
Copy Markdown
Member

As per #6165 (comment) this is not the solution.

@davidhewitt davidhewitt closed this Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] PyO3 0.29 abi3 modules on android linked against libpython3 fail to load

3 participants