Skip to content

Commit

Permalink
Merge pull request #142 from projectsyn/renovate/pyo3-0.x
Browse files Browse the repository at this point in the history
Update Rust crate pyo3 to v0.23.1
  • Loading branch information
simu authored Nov 19, 2024
2 parents f342afa + 9dc569d commit 6ad2488
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 65 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ anyhow = "1.0.82"
chrono = "0.4.38"
indexmap = "2.2.6"
nom = "7.1.3"
pyo3 = { version = "=0.22.6", features = ["chrono"] }
pyo3 = { version = "=0.23.1", features = ["chrono"] }
rayon = "1.10.0"
regex = "1.10.4"
serde = { version = "1.0.200", features = ["derive"] }
Expand Down
12 changes: 6 additions & 6 deletions src/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,17 @@ impl Inventory {
///
/// The structure of the returned dict should match Python reclass the structure of the dict
/// returned by Python reclass's `inventory()` method.
fn as_dict(&self, py: Python<'_>) -> PyResult<Py<PyDict>> {
let dict = PyDict::new_bound(py);
dict.set_item("applications", self.applications.clone().into_py(py))?;
dict.set_item("classes", self.classes.clone().into_py(py))?;
let nodes_dict = PyDict::new_bound(py);
fn as_dict<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyDict>> {
let dict = PyDict::new(py);
dict.set_item("applications", self.applications.clone().into_pyobject(py)?)?;
dict.set_item("classes", self.classes.clone().into_pyobject(py)?)?;
let nodes_dict = PyDict::new(py);
for (name, info) in &self.nodes {
nodes_dict.set_item(name, info.as_dict(py)?)?;
}
dict.set_item("nodes", nodes_dict)?;

let reclass_dict = PyDict::new_bound(py);
let reclass_dict = PyDict::new(py);
let ts = Local::now();
reclass_dict.set_item("timestamp", ts.format("%c").to_string())?;
dict.set_item("__reclass__", reclass_dict)?;
Expand Down
32 changes: 19 additions & 13 deletions src/node/nodeinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,13 @@ impl NodeInfo {

/// Returns the NodeInfo `parameters` field as a PyDict
#[getter]
fn parameters(&self, py: Python<'_>) -> PyResult<Py<PyDict>> {
fn parameters<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyDict>> {
self.parameters.as_py_dict(py)
}

/// Returns the NodeInfo `exports` field as a PyDict
#[getter]
fn exports(&self, py: Python<'_>) -> PyResult<Py<PyDict>> {
fn exports<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyDict>> {
#[cfg(debug_assertions)]
eprintln!("reclass_rs doesn't support exports yet!");
self.exports.as_py_dict(py)
Expand All @@ -176,24 +176,30 @@ impl NodeInfo {
///
/// This method generates a PyDict which should be structured identically to Python Reclass's
/// `nodeinfo` return value.
pub(crate) fn as_dict(&self, py: Python<'_>) -> PyResult<Py<PyDict>> {
let dict = PyDict::new_bound(py);
pub(crate) fn as_dict<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyDict>> {
let dict = PyDict::new(py);
dict.set_item("__reclass__", self.reclass_as_dict(py)?)?;
dict.set_item("applications", self.applications.clone().into_py(py))?;
dict.set_item("classes", self.classes.clone().into_py(py))?;
dict.set_item("environment", self.reclass.environment.clone().into_py(py))?;
dict.set_item("applications", self.applications.clone().into_pyobject(py)?)?;
dict.set_item("applications", self.applications.clone().into_pyobject(py)?)?;
dict.set_item(
"environment",
self.reclass.environment.clone().into_pyobject(py)?,
)?;
dict.set_item("exports", self.exports(py)?)?;
dict.set_item("parameters", self.parameters(py)?)?;
Ok(dict.into())

Check warning on line 190 in src/node/nodeinfo.rs

View workflow job for this annotation

GitHub Actions / clippy

useless conversion to the same type: `pyo3::Bound<'_, pyo3::types::PyDict>`

warning: useless conversion to the same type: `pyo3::Bound<'_, pyo3::types::PyDict>` --> src/node/nodeinfo.rs:190:12 | 190 | Ok(dict.into()) | ^^^^^^^^^^^ help: consider removing `.into()`: `dict` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
}

/// Returns the NodeInfo `meta` field as a PyDict
fn reclass_as_dict(&self, py: Python<'_>) -> PyResult<Py<PyDict>> {
let dict = PyDict::new_bound(py);
dict.set_item("node", self.reclass.node.clone().into_py(py))?;
dict.set_item("name", self.reclass.name.clone().into_py(py))?;
dict.set_item("uri", self.reclass.uri.clone().into_py(py))?;
dict.set_item("environment", self.reclass.environment.clone().into_py(py))?;
fn reclass_as_dict<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyDict>> {
let dict = PyDict::new(py);
dict.set_item("node", self.reclass.node.clone().into_pyobject(py)?)?;
dict.set_item("name", self.reclass.name.clone().into_pyobject(py)?)?;
dict.set_item("uri", self.reclass.uri.clone().into_pyobject(py)?)?;
dict.set_item(
"environment",
self.reclass.environment.clone().into_pyobject(py)?,
)?;
// Format time as strftime %c for Python compatibility
dict.set_item(
"timestamp",
Expand Down
2 changes: 1 addition & 1 deletion src/types/from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl TryFrom<Bound<'_, PyAny>> for Value {
"list" => {
let v = value.downcast::<PySequence>()?;
let mut items: Vec<Value> = vec![];
for it in v.iter()? {
for it in v.try_iter()? {
items.push(TryInto::try_into(it?)?);
}
Ok(Self::Sequence(items))
Expand Down
15 changes: 5 additions & 10 deletions src/types/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,16 +355,16 @@ impl Mapping {
}

/// Converts the `Mapping` into a `PyDict`.
pub fn as_py_dict(&self, py: Python<'_>) -> PyResult<Py<PyDict>> {
let dict = PyDict::new_bound(py);
pub fn as_py_dict<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyDict>> {
let dict = PyDict::new(py);

for (k, v) in self {
let pyk = k.as_py_obj(py)?;
let pyv = v.as_py_obj(py)?;
dict.set_item(pyk, pyv)?;
}

Ok(dict.into())
Ok(dict.into_pyobject(py)?)
}

/// Checks if the provided key is marked as constant.
Expand Down Expand Up @@ -740,17 +740,12 @@ mod mapping_tests {
);
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let pym = m.as_py_dict(py).unwrap();
let m = pym.bind(py);
let m = m.as_py_dict(py).unwrap();
assert_eq!(m.len(), 6);
assert_eq!(format!("{:?}", m.keys()), "['a', 'b', 'c', 'd', 'e', 'f']");
let a = m.get_item(&"a").unwrap().unwrap();
assert!(a.is_instance_of::<pyo3::types::PyInt>());
assert!(a
.downcast_exact::<pyo3::types::PyInt>()
.unwrap()
.eq(1.into_py(py))
.unwrap());
assert!(a.downcast_exact::<pyo3::types::PyInt>().unwrap().eq(&1));
let f = m.get_item(&"f").unwrap().unwrap();
assert!(f.is_instance_of::<PyDict>());
let f = f.downcast_exact::<PyDict>().unwrap();
Expand Down
20 changes: 10 additions & 10 deletions src/types/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,32 +426,32 @@ impl Value {

/// Converts the `Value` into a `PyObject`.
#[allow(clippy::missing_panics_doc)]
pub fn as_py_obj(&self, py: Python<'_>) -> PyResult<PyObject> {
pub fn as_py_obj<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
let obj = match self {
Value::Literal(s) | Value::String(s) => s.into_py(py),
Value::Bool(b) => b.into_py(py),
Value::Literal(s) | Value::String(s) => s.into_pyobject(py)?.into_any(),
Value::Bool(b) => pyo3::types::PyBool::new(py, *b).to_owned().into_any(),
Value::Number(n) => {
if n.is_i64() {
// NOTE(sg): We allow the missing panics doc because we already checked that
// `as_i64()` can't panic here.
n.as_i64().unwrap().into_py(py)
n.as_i64().unwrap().into_pyobject(py)?.into_any()
} else if n.is_u64() {
n.as_u64().unwrap().into_py(py)
n.as_u64().unwrap().into_pyobject(py)?.into_any()
} else if n.is_f64() {
n.as_f64().unwrap().into_py(py)
n.as_f64().unwrap().into_pyobject(py)?.into_any()
} else {
Option::<()>::None.into_py(py)
Option::<()>::None.into_pyobject(py)?.into_any()
}
}
Value::Sequence(s) => {
let mut pyseq = vec![];
for v in s {
pyseq.push(v.as_py_obj(py)?);
}
pyseq.into_py(py)
pyseq.into_pyobject(py)?.into_any()
}
Value::Mapping(m) => m.as_py_dict(py)?.into(),
Value::Null => Option::<()>::None.into_py(py),
Value::Mapping(m) => m.as_py_dict(py)?.into_any(),
Value::Null => Option::<()>::None.into_pyobject(py)?.into_any(),
// ValueList should never get emitted to Python
Value::ValueList(_) => unreachable!(),
};
Expand Down
30 changes: 10 additions & 20 deletions src/types/value/value_as_py_obj_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use super::*;
fn test_as_py_obj_null() {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let pyv = Value::Null.as_py_obj(py).unwrap();
let v = pyv.bind(py);
let v = Value::Null.as_py_obj(py).unwrap();
assert!(v.is_none());
});
}
Expand All @@ -13,8 +12,7 @@ fn test_as_py_obj_null() {
fn test_as_py_obj_bool() {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let pyb = Value::Bool(true).as_py_obj(py).unwrap();
let b = pyb.bind(py);
let b = Value::Bool(true).as_py_obj(py).unwrap();
assert!(b.is_instance_of::<pyo3::types::PyBool>());
assert!(b.downcast_exact::<pyo3::types::PyBool>().unwrap().is_true());
});
Expand All @@ -27,13 +25,9 @@ fn test_as_py_obj_int() {
let nums: Vec<Value> = vec![5.into(), (-2i64).into()];
for n in nums {
let pyn = n.as_py_obj(py).unwrap();
let n = pyn.bind(py);
assert!(n.is_instance_of::<pyo3::types::PyInt>());
assert!(n
.downcast_exact::<pyo3::types::PyInt>()
.unwrap()
.eq(n.into_py(py))
.unwrap());
let n = n.as_i64().unwrap();
assert!(pyn.is_instance_of::<pyo3::types::PyInt>());
assert!(pyn.downcast_exact::<pyo3::types::PyInt>().unwrap().eq(&n));
}
});
}
Expand All @@ -43,14 +37,12 @@ fn test_as_py_obj_float() {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let n: Value = 3.14.into();
let pyn = n.as_py_obj(py).unwrap();
let n = pyn.bind(py);
let n = n.as_py_obj(py).unwrap();
assert!(n.is_instance_of::<pyo3::types::PyFloat>());
assert!(n
.downcast_exact::<pyo3::types::PyFloat>()
.unwrap()
.eq(3.14.into_py(py))
.unwrap());
.eq(&3.14));
});
}

Expand All @@ -59,13 +51,12 @@ fn test_as_py_obj_sequence() {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let s: Value = vec![1, 2, 3].into();
let pys = s.as_py_obj(py).unwrap();
let s = pys.bind(py);
let s = s.as_py_obj(py).unwrap();
assert!(s.is_instance_of::<pyo3::types::PyList>());
assert!(s
.downcast_exact::<pyo3::types::PyList>()
.unwrap()
.eq(pyo3::types::PyList::new_bound(py, vec![1, 2, 3]))
.eq(&vec![1, 2, 3])
.unwrap());
});
}
Expand All @@ -74,10 +65,9 @@ fn test_as_py_obj_sequence() {
fn test_as_py_obj_string() {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let pys = std::convert::Into::<Value>::into("hello, world")
let s = std::convert::Into::<Value>::into("hello, world")
.as_py_obj(py)
.unwrap();
let s = pys.bind(py);
assert!(s.is_instance_of::<pyo3::types::PyString>());
assert_eq!(
s.downcast_exact::<pyo3::types::PyString>()
Expand Down
11 changes: 7 additions & 4 deletions tests/test_py.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::ffi::CString;

use pyo3::prelude::*;
use pyo3::types::PyDict;

Expand All @@ -9,11 +11,12 @@ fn test_reclass() {
Python::with_gil(|py| {
let r = Reclass::new("./tests/inventory", "nodes", "classes", false)
.unwrap()
.into_py(py);
let locals = PyDict::new_bound(py);
.into_pyobject(py)
.unwrap();
let locals = PyDict::new(py);
locals.set_item("r", r).unwrap();
py.run_bound(
r#"assert r and "Reclass" in str(type(r))"#,
py.run(
&CString::new(r#"assert r and "Reclass" in str(type(r))"#).unwrap(),
None,
Some(&locals),
)
Expand Down

0 comments on commit 6ad2488

Please sign in to comment.