pyo3-extension-modules

Diagnose and fix PyO3 extension-module feature wiring that breaks cargo test and maturin builds.

3|1|Updated Nov 30, 2025
One-click install
npx skills add https://github.com/PALabs-v1/AI_friend --skill pyo3-extension-modules-palabs-v1
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: pyo3-extension-modules
Source: https://github.com/PALabs-v1/AI_friend/tree/main/.claude/skills/pyo3-extension-modules
Command: npx skills add https://github.com/PALabs-v1/AI_friend --skill pyo3-extension-modules-palabs-v1

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? PyO3's extension-module feature silently breaks cargo test and cargo check when enabled in a shared workspace dependency spec, producing confusing linker errors about missing Python C-API symbols. This Skill explains the root cause, the correct feature wiring between Cargo.toml and pyproject.toml, and how to make a Rust accelerator optional in Python. ## Core Features & Use Cases - Linker Error Diagnosis: Identifies ld symbol-not-found errors (Py_IsInitialized, Py_NoneStruct, etc.) as the extension-module feature being enabled where it should not be, not a missing dependency. - Feature Wiring Fix: Keeps extension-module out of the workspace dependency spec, exposes it as an opt-in crate feature, and tells maturin to request it via [tool.maturin] in pyproject.toml. - Maturin Config Gotcha: Explains that maturin reads pyproject.toml from the invoking working directory, not from --manifest-path, so config placement matters. - Optional Accelerator Pattern: Implements try/except import with a pure-Python fallback, plus a test proving both paths produce identical results. - Use Case: Your workspace cargo test fails with undefined Python symbols after adding a pyo3 crate; apply this Skill to restructure the feature flags and verify both cargo test and maturin build succeed. ## Quick Start Ask the assistant to diagnose why cargo test fails with undefined Py_NoneStruct linker errors in a pyo3 workspace and fix the extension-module feature wiring.

Frequently Asked Questions about pyo3-extension-modules

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
Why does cargo test fail with undefined Py_NoneStruct or Py_IsInitialized linker errors?

These linker errors mean pyo3's extension-module feature is enabled during cargo test, which tells the linker not to link libpython. Standalone test binaries are not loaded into a Python process, so the symbols are unresolved. Remove extension-module from the shared dependency spec.

How do I configure pyo3 extension-module feature with maturin?

Keep extension-module out of the workspace dependency spec, add it as an opt-in feature on the extension crate, then enable it via [tool.maturin] features in pyproject.toml or maturin build --features extension-module. Maturin reads pyproject.toml from the invoking directory, not from --manifest-path.

How do I make a Rust pyo3 extension optional in Python?

Wrap the import in try/except ImportError and fall back to a pure-Python implementation of the same function. Add a dedicated test asserting the Rust and Python paths produce identical output so the fallback never silently returns different results.

Does cargo test passing mean the pyo3 wheel is installed correctly?

No. cargo test proves the source links, but building and installing the wheel are separate steps, often on separate machines. Verify with pip show and an import check on each deployment target, and build wheels on the target architecture.

Can I copy a maturin-built wheel between Mac and Linux machines?

No. Wheels are architecture-specific; a Mac build targets arm64 while Linux servers are usually x86_64. Always build the wheel on the target host rather than copying artifacts across architectures.