Skip to content

A uv Environment Is Not Compatible With pyo3 Out Of The Box #11006

@mcmah309

Description

@mcmah309

Summary

It seems a uv environment is not compatible with pyo3 as libpython is not found for the active environment, nor is the python codec.

PyO3/pyo3#4813 (comment)

Additionally the .cargo/config.toml needs to include

[env]
PYO3_PYTHON = { value = ".venv/bin/python", relative = true, force = true }

Example

Setup:

uv venv .venv --python 3.12
. .venv/bin/activate

src/lib.rs

use std::path::PathBuf;

use pyo3::prelude::*;

use serde::{Deserialize, Serialize};

#[pyclass]
#[derive(Debug, Serialize, Deserialize)]
struct Group {
    name: String,
}

#[pyclass]
#[derive(Debug, Serialize, Deserialize)]
struct User {
    username: String,
    group: Option<Py<Group>>,
    friends: Vec<Py<User>>,
}

#[test]
fn test_serialize() {
    let friend1 = User {
        username: "friend 1".into(),
        group: None,
        friends: vec![],
    };
    let friend2 = User {
        username: "friend 2".into(),
        group: None,
        friends: vec![],
    };

    let user = Python::with_gil(|py| {
        let py_friend1 = Py::new(py, friend1).expect("failed to create friend 1");
        let py_friend2 = Py::new(py, friend2).expect("failed to create friend 2");

        let friends = vec![py_friend1, py_friend2];
        let py_group = Py::new(py, Group {
            name: "group name".into(),
        })
        .unwrap();

        User {
            username: "danya".into(),
            group: Some(py_group),
            friends,
        }
    });

    let serialized = serde_json::to_string(&user).expect("failed to serialize");
    assert_eq!(
        serialized,
        r#"{"username":"danya","group":{"name":"group name"},"friends":[{"username":"friend 1","group":null,"friends":[]},{"username":"friend 2","group":null,"friends":[]}]}"#
    );
}

#[test]
fn test_deserialize() {
    let serialized = r#"{"username": "danya", "friends":
        [{"username": "friend", "group": {"name": "danya's friends"}, "friends": []}]}"#;
    let user: User = serde_json::from_str(serialized).expect("failed to deserialize");

    assert_eq!(user.username, "danya");
    assert!(user.group.is_none());
    assert_eq!(user.friends.len(), 1usize);
    let friend = user.friends.first().unwrap();

    Python::with_gil(|py| {
        assert_eq!(friend.borrow(py).username, "friend");
        assert_eq!(
            friend.borrow(py).group.as_ref().unwrap().borrow(py).name,
            "danya's friends"
        )
    });
}

Cargo.toml

[package]
name = "example"
version = "0.1.0"
edition = "2024"

[dependencies]
pyo3 = { version = "0.23", features = ["auto-initialize", "serde"] }
serde = { version = "1", features = ["serde_derive"] }
serde_json = "1"

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingexternalThe problem is with another package or dependency (not uv)

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions