1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
From c3201cd144c332a3672e11dd0a4ee0f1e40ea552 Mon Sep 17 00:00:00 2001
From: Florian Sesser <florian@leastauthority.com>
Date: Fri, 3 Oct 2025 11:29:01 +0000
Subject: Adapt library to pyo3 0.23 API
Replace deprecated into_py with into_pyobject and unbind.
This is slop, and it doesn't seem very elegant, but it passes
the tests so I guess it's better than nothing.
refactor: migrate from PyO3 0.22 to 0.25 API
fix: replace deprecated into_py with into_pyobject and unbind
fix: convert Py<T> to Py<PyAny> in deserialize functions
fix: clone borrowed PyBool before unbinding to prevent move error
fix: convert borrowed PyBool to owned Bound before unbinding
fix: import BoundObject trait to resolve into_bound method
refactor: use idiomatic PyO3 0.25 conversion pattern with into_any().unbind()
Co-authored-by: aider (anthropic/claude-sonnet-4-5-20250929) <aider@aider.chat>
---
src/deserialize.rs | 26 +++++++++++++-------------
src/lib.rs | 6 +++---
2 files changed, 16 insertions(+), 16 deletions(-)
--- a/src/deserialize.rs
+++ b/src/deserialize.rs
@@ -1,32 +1,32 @@
//! Deserialize CBOR to Python objects.
use ciborium::value::Value;
-use pyo3::{prelude::*, types::{PyNone, PyList, PyDict, PyBytes, PySet}, exceptions::PyValueError};
+use pyo3::{prelude::*, types::{PyList, PyDict, PyBytes, PySet}, exceptions::PyValueError, BoundObject};
/// Convert a CBOR value into an equivalent tree of Python objects.
pub fn deserialize(py: Python<'_>, value: &Value) -> PyResult<PyObject> {
match value {
- Value::Integer(int) => Ok(i128::from(*int).to_object(py)),
- Value::Bytes(vec) => Ok(PyBytes::new_bound(py, vec).to_object(py)),
- Value::Float(float) => Ok(float.to_object(py)),
- Value::Text(string) => Ok(string.to_object(py)),
- Value::Bool(boolean) => Ok(boolean.to_object(py)),
- Value::Null => Ok(PyNone::get_bound(py).to_object(py)),
+ Value::Integer(int) => Ok(i128::from(*int).into_pyobject(py)?.into_any().unbind()),
+ Value::Bytes(vec) => Ok(PyBytes::new(py, vec).into_any().unbind()),
+ Value::Float(float) => Ok(float.into_pyobject(py)?.into_any().unbind()),
+ Value::Text(string) => Ok(string.into_pyobject(py)?.into_any().unbind()),
+ Value::Bool(boolean) => Ok(boolean.into_pyobject(py)?.into_any().unbind()),
+ Value::Null => Ok(py.None()),
Value::Array(array_values) => {
- let result = PyList::empty_bound(py);
+ let result = PyList::empty(py);
for array_value in array_values {
result.append(deserialize(py, array_value)?)?;
}
- Ok(result.to_object(py))
+ Ok(result.into_any().unbind())
},
Value::Map(map_pairs) => {
- let result = PyDict::new_bound(py);
+ let result = PyDict::new(py);
for (key, value) in map_pairs {
let key = deserialize(py, key)?;
let value = deserialize(py, value)?;
result.set_item(key, value)?;
}
- Ok(result.to_object(py))
+ Ok(result.into_any().unbind())
},
Value::Tag(tag, tagged_value) => deserialize_tagged(py, *tag, tagged_value),
_ => Err(PyValueError::new_err("Unsupported CBOR type"))
@@ -37,11 +37,11 @@
fn deserialize_tagged(py: Python<'_>, tag: u64, value: &Value) -> PyResult<PyObject> {
match (tag, value) {
(258, Value::Array(array_values)) => {
- let result = PySet::empty_bound(py)?;
+ let result = PySet::empty(py)?;
for array_value in array_values {
result.add(deserialize(py, array_value)?)?;
}
- Ok(result.to_object(py))
+ Ok(result.into_any().unbind())
},
_ => Err(PyValueError::new_err(format!("Tag {tag} not yet supported, please file an issue at https://gitlab.com/tahoe-lafs/pycddl"))),
}
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -51,7 +51,7 @@
/// will be deserialized to Python objects and returned.
#[pyo3(signature = (cbor, deserialize=false))]
fn validate_cbor(&self, py: Python<'_>, cbor: &Bound<'_, PyAny>, deserialize: bool) -> PyResult<PyObject> {
- let buffer = PyBuffer::<u8>::get_bound(cbor)?;
+ let buffer = PyBuffer::<u8>::get(cbor)?;
// PyPy has weird issues with this flag.
if !cfg!(PyPy) && !buffer.readonly() {
return Err(PyValueError::new_err("Must be a read-only byte buffer (and you should never mutate it during validation)"));
@@ -108,7 +108,7 @@
.expect("This should never error since this is the second time we're parsing...");
crate::deserialize::deserialize(py, &parsed_cbor)
} else {
- Ok(None::<()>.to_object(py))
+ Ok(py.None())
}
}
}
@@ -117,7 +117,7 @@
#[pymodule]
fn pycddl(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
- m.add("ValidationError", py.get_type_bound::<ValidationError>())?;
+ m.add("ValidationError", py.get_type::<ValidationError>())?;
m.add_class::<Schema>()?;
Ok(())
}
|