MCPcopy Index your code
hub / github.com/PyO3/pyo3

github.com/PyO3/pyo3 @pyo3-derive-backend-0.6.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release pyo3-derive-backend-0.6.0 ↗ · + Follow
1,975 symbols 4,660 edges 201 files 300 documented · 15% updated 1d agov0.29.0 · 2026-06-11★ 15,886282 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

PyO3

Build Status Build Status codecov crates.io Join the dev chat

Rust bindings for Python. This includes running and interacting with python code from a rust binaries as well as writing native python modules.

A comparison with rust-cpython can be found in the guide.

Usage

PyO3 supports python 2.7 as well as python 3.5 and up. The minimum required rust version is 1.34.0-nightly 2019-02-06.

You can either write a native python module in rust or use python from a rust binary.

On some OSs, you need some additional packages.

E.g. if you are on Ubuntu18.04, please run

sudo apt install python3-dev python-dev

Using rust from python

PyO3 can be used to generate a native python module.

Cargo.toml

[package]
name = "string-sum"
version = "0.1.0"
edition = "2018"

[lib]
name = "string_sum"
crate-type = ["cdylib"]

[dependencies.pyo3]
version = "0.6.0-alpha.4"
features = ["extension-module"]

src/lib.rs

// Not required when using Rust 2018
extern crate pyo3;

use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

#[pyfunction]
/// Formats the sum of two numbers as string
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
    Ok((a + b).to_string())
}

/// This module is a python module implemented in Rust.
#[pymodule]
fn string_sum(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_wrapped(wrap_pyfunction!(sum_as_string))?;

    Ok(())
}

On windows and linux, you can build normally with cargo build --release. On macOS, you need to set additional linker arguments. One option is to compile with cargo rustc --release -- -C link-arg=-undefined -C link-arg=dynamic_lookup, the other is to create a .cargo/config with the following content:

[target.x86_64-apple-darwin]
rustflags = [
  "-C", "link-arg=-undefined",
  "-C", "link-arg=dynamic_lookup",
]

For developing, you can copy and rename the shared library from the target folder: On macOS, rename libstring_sum.dylib to string_sum.so, on windows libstring_sum.dll to string_sum.pyd and on linux libstring_sum.so to string_sum.so. Then open a python shell in the same folder and you'll be able to import string_sum.

To build, test and publish your crate as python module, you can use pyo3-pack or setuptools-rust. You can find an example for setuptools-rust in examples/word-count, while pyo3-pack should work on your crate without any configuration.

Using python from rust

Add pyo3 this to your Cargo.toml:

[dependencies]
pyo3 = "0.6.0-alpha.4"

Example program displaying the value of sys.version:

// Not required when using Rust 2018
extern crate pyo3;

use pyo3::prelude::*;
use pyo3::types::IntoPyDict;

fn main() -> PyResult<()> {
    let gil = Python::acquire_gil();
    let py = gil.python();
    let sys = py.import("sys")?;
    let version: String = sys.get("version")?.extract()?;
    let locals = [("os", py.import("os")?)].into_py_dict(py);
    let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
    let user: String = py.eval(code, None, Some(&locals))?.extract()?;
    println!("Hello {}, I'm Python {}", user, version);
    Ok(())
}

Examples and tooling

License

PyO3 is licensed under the Apache-2.0 license. Python is licensed under the Python License.

Extension points exported contracts — how you extend this code

AsPyPointer (Interface)
This trait represents that, **we can do zero-cost conversion from the object to FFI pointer**. This trait is implemente [6 …
src/conversion.rs
CallbackConverter (Interface)
(no doc) [7 implementers]
src/callback.rs
PyObjectProtocol (Interface)
(no doc) [6 implementers]
src/class/basic.rs
AsPyRef (Interface)
Trait implements object reference extraction from python managed pointer. [2 implementers]
src/instance.rs
PyErrArguments (Interface)
Helper conversion trait that allows to use custom arguments for exception constructor. [2 implementers]
src/err.rs
IntoPyResult (Interface)
This trait wraps a T: IntoPyObject into PyResult while PyResult remains PyResult . This is necessary because pr [2 implementers]
src/derive_utils.rs
PyDictItem (Interface)
Represents a tuple which can be used as a PyDict item. [2 implementers]
src/types/dict.rs
ObjectProtocol (Interface)
Python object model helper methods [1 implementers]
src/objectprotocol.rs

Core symbols most depended-on inside this repo

python
called by 232
src/gil.rs
as_ptr
called by 211
src/buffer.rs
py
called by 119
src/instance.rs
as_ref
called by 79
src/object.rs
into
called by 79
src/err.rs
Py_TYPE
called by 69
src/ffi2/object.rs
iter
called by 57
src/types/dict.rs
to_object
called by 51
src/types/set.rs

Shape

Method 818
Function 673
Interface 244
Class 216
Enum 24

Languages

Rust98%
Python2%

Modules by API surface

src/class/number.rs241 symbols
src/class/basic.rs67 symbols
src/class/sequence.rs54 symbols
tests/test_dunder.rs50 symbols
src/types/dict.rs50 symbols
src/types/sequence.rs49 symbols
src/instance.rs47 symbols
src/buffer.rs44 symbols
src/class/mapping.rs41 symbols
src/objectprotocol.rs38 symbols
src/ffi/datetime.rs36 symbols
src/types/list.rs33 symbols

For agents

$ claude mcp add pyo3 \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page