Skip to content

Commit b674292

Browse files
authored
Update to PyO3 0.23 (#75)
* Update to PyO3 0.23 - xyz_bound methods have been renamed to xyz - Use IntoPyObject for conversion to Python * Use c_str! instead of CStr literals * Add CHANGELOG entry * Cargo format
1 parent 8f76041 commit b674292

7 files changed

+150
-123
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## Unreleased
2+
3+
### Packaging
4+
- Update to PyO3 0.23
5+
16
## 0.22.0 - 2024-08-10
27

38
### Packaging

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ documentation = "https://docs.rs/crate/pythonize/"
1313

1414
[dependencies]
1515
serde = { version = "1.0", default-features = false, features = ["std"] }
16-
pyo3 = { version = "0.22.2", default-features = false }
16+
pyo3 = { version = "0.23.1", default-features = false }
1717

1818
[dev-dependencies]
1919
serde = { version = "1.0", default-features = false, features = ["derive"] }
20-
pyo3 = { version = "0.22.2", default-features = false, features = ["auto-initialize", "macros", "py-clone"] }
20+
pyo3 = { version = "0.23.1", default-features = false, features = ["auto-initialize", "macros", "py-clone"] }
2121
serde_json = "1.0"
2222
serde_bytes = "0.11"
2323
maplit = "1.0.2"

src/de.rs

+67-67
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ where
1414

1515
/// Attempt to convert a Python object to an instance of `T`
1616
#[deprecated(since = "0.22.0", note = "use `depythonize` instead")]
17-
pub fn depythonize_bound<'py, T>(obj: Bound<'py, PyAny>) -> Result<T>
17+
pub fn depythonize_bound<T>(obj: Bound<PyAny>) -> Result<T>
1818
where
1919
T: DeserializeOwned,
2020
{
@@ -46,10 +46,10 @@ impl<'a, 'py> Depythonizer<'a, 'py> {
4646

4747
fn set_access(&self) -> Result<PySetAsSequence<'py>> {
4848
match self.input.downcast::<PySet>() {
49-
Ok(set) => Ok(PySetAsSequence::from_set(&set)),
49+
Ok(set) => Ok(PySetAsSequence::from_set(set)),
5050
Err(e) => {
5151
if let Ok(f) = self.input.downcast::<PyFrozenSet>() {
52-
Ok(PySetAsSequence::from_frozenset(&f))
52+
Ok(PySetAsSequence::from_frozenset(f))
5353
} else {
5454
Err(e.into())
5555
}
@@ -387,13 +387,13 @@ struct PySetAsSequence<'py> {
387387
impl<'py> PySetAsSequence<'py> {
388388
fn from_set(set: &Bound<'py, PySet>) -> Self {
389389
Self {
390-
iter: PyIterator::from_bound_object(&set).expect("set is always iterable"),
390+
iter: PyIterator::from_object(set).expect("set is always iterable"),
391391
}
392392
}
393393

394394
fn from_frozenset(set: &Bound<'py, PyFrozenSet>) -> Self {
395395
Self {
396-
iter: PyIterator::from_bound_object(&set).expect("frozenset is always iterable"),
396+
iter: PyIterator::from_object(set).expect("frozenset is always iterable"),
397397
}
398398
}
399399
}
@@ -415,8 +415,8 @@ impl<'de> de::SeqAccess<'de> for PySetAsSequence<'_> {
415415
}
416416

417417
struct PyMappingAccess<'py> {
418-
keys: Bound<'py, PySequence>,
419-
values: Bound<'py, PySequence>,
418+
keys: Bound<'py, PyList>,
419+
values: Bound<'py, PyList>,
420420
key_idx: usize,
421421
val_idx: usize,
422422
len: usize,
@@ -524,18 +524,21 @@ impl<'de> de::VariantAccess<'de> for PyEnumAccess<'_, '_> {
524524

525525
#[cfg(test)]
526526
mod test {
527+
use std::ffi::CStr;
528+
527529
use super::*;
528530
use crate::error::ErrorImpl;
529531
use maplit::hashmap;
530-
use pyo3::{IntoPy, Python};
532+
use pyo3::ffi::c_str;
533+
use pyo3::{IntoPyObject, Python};
531534
use serde_json::{json, Value as JsonValue};
532535

533-
fn test_de<T>(code: &str, expected: &T, expected_json: &JsonValue)
536+
fn test_de<T>(code: &CStr, expected: &T, expected_json: &JsonValue)
534537
where
535538
T: de::DeserializeOwned + PartialEq + std::fmt::Debug,
536539
{
537540
Python::with_gil(|py| {
538-
let obj = py.eval_bound(code, None, None).unwrap();
541+
let obj = py.eval(code, None, None).unwrap();
539542
let actual: T = depythonize(&obj).unwrap();
540543
assert_eq!(&actual, expected);
541544
let actual_json: JsonValue = depythonize(&obj).unwrap();
@@ -554,7 +557,7 @@ mod test {
554557

555558
let expected = Empty;
556559
let expected_json = json!(null);
557-
let code = "None";
560+
let code = c_str!("None");
558561
test_de(code, &expected, &expected_json);
559562
}
560563

@@ -580,7 +583,7 @@ mod test {
580583
"baz": 45.23,
581584
"qux": true
582585
});
583-
let code = "{'foo': 'Foo', 'bar': 8, 'baz': 45.23, 'qux': True}";
586+
let code = c_str!("{'foo': 'Foo', 'bar': 8, 'baz': 45.23, 'qux': True}");
584587
test_de(code, &expected, &expected_json);
585588
}
586589

@@ -592,13 +595,11 @@ mod test {
592595
bar: usize,
593596
}
594597

595-
let code = "{'foo': 'Foo'}";
598+
let code = c_str!("{'foo': 'Foo'}");
596599

597600
Python::with_gil(|py| {
598-
let locals = PyDict::new_bound(py);
599-
py.run_bound(&format!("obj = {}", code), None, Some(&locals))
600-
.unwrap();
601-
let obj = locals.get_item("obj").unwrap().unwrap();
601+
let locals = PyDict::new(py);
602+
let obj = py.eval(code, None, Some(&locals)).unwrap();
602603
assert!(matches!(
603604
*depythonize::<Struct>(&obj).unwrap_err().inner,
604605
ErrorImpl::Message(msg) if msg == "missing field `bar`"
@@ -613,7 +614,7 @@ mod test {
613614

614615
let expected = TupleStruct("cat".to_string(), -10.05);
615616
let expected_json = json!(["cat", -10.05]);
616-
let code = "('cat', -10.05)";
617+
let code = c_str!("('cat', -10.05)");
617618
test_de(code, &expected, &expected_json);
618619
}
619620

@@ -622,13 +623,11 @@ mod test {
622623
#[derive(Debug, Deserialize, PartialEq)]
623624
struct TupleStruct(String, f64);
624625

625-
let code = "('cat', -10.05, 'foo')";
626+
let code = c_str!("('cat', -10.05, 'foo')");
626627

627628
Python::with_gil(|py| {
628-
let locals = PyDict::new_bound(py);
629-
py.run_bound(&format!("obj = {}", code), None, Some(&locals))
630-
.unwrap();
631-
let obj = locals.get_item("obj").unwrap().unwrap();
629+
let locals = PyDict::new(py);
630+
let obj = py.eval(code, None, Some(&locals)).unwrap();
632631
assert!(matches!(
633632
*depythonize::<TupleStruct>(&obj).unwrap_err().inner,
634633
ErrorImpl::IncorrectSequenceLength { expected, got } if expected == 2 && got == 3
@@ -643,63 +642,63 @@ mod test {
643642

644643
let expected = TupleStruct("cat".to_string(), -10.05);
645644
let expected_json = json!(["cat", -10.05]);
646-
let code = "['cat', -10.05]";
645+
let code = c_str!("['cat', -10.05]");
647646
test_de(code, &expected, &expected_json);
648647
}
649648

650649
#[test]
651650
fn test_tuple() {
652651
let expected = ("foo".to_string(), 5);
653652
let expected_json = json!(["foo", 5]);
654-
let code = "('foo', 5)";
653+
let code = c_str!("('foo', 5)");
655654
test_de(code, &expected, &expected_json);
656655
}
657656

658657
#[test]
659658
fn test_tuple_from_pylist() {
660659
let expected = ("foo".to_string(), 5);
661660
let expected_json = json!(["foo", 5]);
662-
let code = "['foo', 5]";
661+
let code = c_str!("['foo', 5]");
663662
test_de(code, &expected, &expected_json);
664663
}
665664

666665
#[test]
667666
fn test_vec_from_pyset() {
668667
let expected = vec!["foo".to_string()];
669668
let expected_json = json!(["foo"]);
670-
let code = "{'foo'}";
669+
let code = c_str!("{'foo'}");
671670
test_de(code, &expected, &expected_json);
672671
}
673672

674673
#[test]
675674
fn test_vec_from_pyfrozenset() {
676675
let expected = vec!["foo".to_string()];
677676
let expected_json = json!(["foo"]);
678-
let code = "frozenset({'foo'})";
677+
let code = c_str!("frozenset({'foo'})");
679678
test_de(code, &expected, &expected_json);
680679
}
681680

682681
#[test]
683682
fn test_vec() {
684683
let expected = vec![3, 2, 1];
685684
let expected_json = json!([3, 2, 1]);
686-
let code = "[3, 2, 1]";
685+
let code = c_str!("[3, 2, 1]");
687686
test_de(code, &expected, &expected_json);
688687
}
689688

690689
#[test]
691690
fn test_vec_from_tuple() {
692691
let expected = vec![3, 2, 1];
693692
let expected_json = json!([3, 2, 1]);
694-
let code = "(3, 2, 1)";
693+
let code = c_str!("(3, 2, 1)");
695694
test_de(code, &expected, &expected_json);
696695
}
697696

698697
#[test]
699698
fn test_hashmap() {
700699
let expected = hashmap! {"foo".to_string() => 4};
701700
let expected_json = json!({"foo": 4 });
702-
let code = "{'foo': 4}";
701+
let code = c_str!("{'foo': 4}");
703702
test_de(code, &expected, &expected_json);
704703
}
705704

@@ -712,7 +711,7 @@ mod test {
712711

713712
let expected = Foo::Variant;
714713
let expected_json = json!("Variant");
715-
let code = "'Variant'";
714+
let code = c_str!("'Variant'");
716715
test_de(code, &expected, &expected_json);
717716
}
718717

@@ -725,7 +724,7 @@ mod test {
725724

726725
let expected = Foo::Tuple(12, "cat".to_string());
727726
let expected_json = json!({"Tuple": [12, "cat"]});
728-
let code = "{'Tuple': [12, 'cat']}";
727+
let code = c_str!("{'Tuple': [12, 'cat']}");
729728
test_de(code, &expected, &expected_json);
730729
}
731730

@@ -738,7 +737,7 @@ mod test {
738737

739738
let expected = Foo::NewType("cat".to_string());
740739
let expected_json = json!({"NewType": "cat" });
741-
let code = "{'NewType': 'cat'}";
740+
let code = c_str!("{'NewType': 'cat'}");
742741
test_de(code, &expected, &expected_json);
743742
}
744743

@@ -754,7 +753,7 @@ mod test {
754753
bar: 25,
755754
};
756755
let expected_json = json!({"Struct": {"foo": "cat", "bar": 25 }});
757-
let code = "{'Struct': {'foo': 'cat', 'bar': 25}}";
756+
let code = c_str!("{'Struct': {'foo': 'cat', 'bar': 25}}");
758757
test_de(code, &expected, &expected_json);
759758
}
760759
#[test]
@@ -767,7 +766,7 @@ mod test {
767766

768767
let expected = Foo::Tuple(12.0, 'c');
769768
let expected_json = json!([12.0, 'c']);
770-
let code = "[12.0, 'c']";
769+
let code = c_str!("[12.0, 'c']");
771770
test_de(code, &expected, &expected_json);
772771
}
773772

@@ -781,7 +780,7 @@ mod test {
781780

782781
let expected = Foo::NewType("cat".to_string());
783782
let expected_json = json!("cat");
784-
let code = "'cat'";
783+
let code = c_str!("'cat'");
785784
test_de(code, &expected, &expected_json);
786785
}
787786

@@ -798,7 +797,7 @@ mod test {
798797
bar: [2, 5, 3, 1],
799798
};
800799
let expected_json = json!({"foo": ["a", "b", "c"], "bar": [2, 5, 3, 1]});
801-
let code = "{'foo': ['a', 'b', 'c'], 'bar': [2, 5, 3, 1]}";
800+
let code = c_str!("{'foo': ['a', 'b', 'c'], 'bar': [2, 5, 3, 1]}");
802801
test_de(code, &expected, &expected_json);
803802
}
804803

@@ -831,46 +830,47 @@ mod test {
831830
};
832831
let expected_json =
833832
json!({"name": "SomeFoo", "bar": { "value": 13, "variant": { "Tuple": [-1.5, 8]}}});
834-
let code = "{'name': 'SomeFoo', 'bar': {'value': 13, 'variant': {'Tuple': [-1.5, 8]}}}";
833+
let code =
834+
c_str!("{'name': 'SomeFoo', 'bar': {'value': 13, 'variant': {'Tuple': [-1.5, 8]}}}");
835835
test_de(code, &expected, &expected_json);
836836
}
837837

838838
#[test]
839839
fn test_int_limits() {
840840
Python::with_gil(|py| {
841841
// serde_json::Value supports u64 and i64 as maxiumum sizes
842-
let _: serde_json::Value = depythonize(&u8::MAX.into_py(py).into_bound(py)).unwrap();
843-
let _: serde_json::Value = depythonize(&u8::MIN.into_py(py).into_bound(py)).unwrap();
844-
let _: serde_json::Value = depythonize(&i8::MAX.into_py(py).into_bound(py)).unwrap();
845-
let _: serde_json::Value = depythonize(&i8::MIN.into_py(py).into_bound(py)).unwrap();
846-
847-
let _: serde_json::Value = depythonize(&u16::MAX.into_py(py).into_bound(py)).unwrap();
848-
let _: serde_json::Value = depythonize(&u16::MIN.into_py(py).into_bound(py)).unwrap();
849-
let _: serde_json::Value = depythonize(&i16::MAX.into_py(py).into_bound(py)).unwrap();
850-
let _: serde_json::Value = depythonize(&i16::MIN.into_py(py).into_bound(py)).unwrap();
851-
852-
let _: serde_json::Value = depythonize(&u32::MAX.into_py(py).into_bound(py)).unwrap();
853-
let _: serde_json::Value = depythonize(&u32::MIN.into_py(py).into_bound(py)).unwrap();
854-
let _: serde_json::Value = depythonize(&i32::MAX.into_py(py).into_bound(py)).unwrap();
855-
let _: serde_json::Value = depythonize(&i32::MIN.into_py(py).into_bound(py)).unwrap();
856-
857-
let _: serde_json::Value = depythonize(&u64::MAX.into_py(py).into_bound(py)).unwrap();
858-
let _: serde_json::Value = depythonize(&u64::MIN.into_py(py).into_bound(py)).unwrap();
859-
let _: serde_json::Value = depythonize(&i64::MAX.into_py(py).into_bound(py)).unwrap();
860-
let _: serde_json::Value = depythonize(&i64::MIN.into_py(py).into_bound(py)).unwrap();
861-
862-
let _: u128 = depythonize(&u128::MAX.into_py(py).into_bound(py)).unwrap();
863-
let _: i128 = depythonize(&u128::MIN.into_py(py).into_bound(py)).unwrap();
864-
865-
let _: i128 = depythonize(&i128::MAX.into_py(py).into_bound(py)).unwrap();
866-
let _: i128 = depythonize(&i128::MIN.into_py(py).into_bound(py)).unwrap();
842+
let _: serde_json::Value = depythonize(&u8::MAX.into_pyobject(py).unwrap()).unwrap();
843+
let _: serde_json::Value = depythonize(&u8::MIN.into_pyobject(py).unwrap()).unwrap();
844+
let _: serde_json::Value = depythonize(&i8::MAX.into_pyobject(py).unwrap()).unwrap();
845+
let _: serde_json::Value = depythonize(&i8::MIN.into_pyobject(py).unwrap()).unwrap();
846+
847+
let _: serde_json::Value = depythonize(&u16::MAX.into_pyobject(py).unwrap()).unwrap();
848+
let _: serde_json::Value = depythonize(&u16::MIN.into_pyobject(py).unwrap()).unwrap();
849+
let _: serde_json::Value = depythonize(&i16::MAX.into_pyobject(py).unwrap()).unwrap();
850+
let _: serde_json::Value = depythonize(&i16::MIN.into_pyobject(py).unwrap()).unwrap();
851+
852+
let _: serde_json::Value = depythonize(&u32::MAX.into_pyobject(py).unwrap()).unwrap();
853+
let _: serde_json::Value = depythonize(&u32::MIN.into_pyobject(py).unwrap()).unwrap();
854+
let _: serde_json::Value = depythonize(&i32::MAX.into_pyobject(py).unwrap()).unwrap();
855+
let _: serde_json::Value = depythonize(&i32::MIN.into_pyobject(py).unwrap()).unwrap();
856+
857+
let _: serde_json::Value = depythonize(&u64::MAX.into_pyobject(py).unwrap()).unwrap();
858+
let _: serde_json::Value = depythonize(&u64::MIN.into_pyobject(py).unwrap()).unwrap();
859+
let _: serde_json::Value = depythonize(&i64::MAX.into_pyobject(py).unwrap()).unwrap();
860+
let _: serde_json::Value = depythonize(&i64::MIN.into_pyobject(py).unwrap()).unwrap();
861+
862+
let _: u128 = depythonize(&u128::MAX.into_pyobject(py).unwrap()).unwrap();
863+
let _: i128 = depythonize(&u128::MIN.into_pyobject(py).unwrap()).unwrap();
864+
865+
let _: i128 = depythonize(&i128::MAX.into_pyobject(py).unwrap()).unwrap();
866+
let _: i128 = depythonize(&i128::MIN.into_pyobject(py).unwrap()).unwrap();
867867
});
868868
}
869869

870870
#[test]
871871
fn test_deserialize_bytes() {
872872
Python::with_gil(|py| {
873-
let obj = PyBytes::new_bound(py, "hello".as_bytes());
873+
let obj = PyBytes::new(py, "hello".as_bytes());
874874
let actual: Vec<u8> = depythonize(&obj).unwrap();
875875
assert_eq!(actual, b"hello");
876876
})
@@ -880,15 +880,15 @@ mod test {
880880
fn test_char() {
881881
let expected = 'a';
882882
let expected_json = json!("a");
883-
let code = "'a'";
883+
let code = c_str!("'a'");
884884
test_de(code, &expected, &expected_json);
885885
}
886886

887887
#[test]
888888
fn test_unknown_type() {
889889
Python::with_gil(|py| {
890890
let obj = py
891-
.import_bound("decimal")
891+
.import("decimal")
892892
.unwrap()
893893
.getattr("Decimal")
894894
.unwrap()

0 commit comments

Comments
 (0)