deprecate `PyDict::new` constructor (#3823)
* deprecate `PyDict::new` * update benchmarks * convert `test_frompyobject`
This commit is contained in:
parent
c983dc9773
commit
c359f5ca1d
|
@ -86,7 +86,7 @@ struct RustyStruct {
|
|||
# use pyo3::types::PyDict;
|
||||
# fn main() -> PyResult<()> {
|
||||
# Python::with_gil(|py| -> PyResult<()> {
|
||||
# let dict = PyDict::new(py);
|
||||
# let dict = PyDict::new_bound(py);
|
||||
# dict.set_item("my_string", "test")?;
|
||||
#
|
||||
# let rustystruct: RustyStruct = dict.extract()?;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion};
|
||||
|
||||
use pyo3::{
|
||||
prelude::*,
|
||||
types::{
|
||||
PyBool, PyByteArray, PyBytes, PyDict, PyFloat, PyFrozenSet, PyInt, PyList, PyMapping,
|
||||
PySequence, PySet, PyString, PyTuple,
|
||||
},
|
||||
PyAny, PyResult, Python,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
|
@ -27,7 +27,7 @@ enum ObjectType {
|
|||
Unknown,
|
||||
}
|
||||
|
||||
fn find_object_type(obj: &PyAny) -> ObjectType {
|
||||
fn find_object_type(obj: &Bound<'_, PyAny>) -> ObjectType {
|
||||
if obj.is_none() {
|
||||
ObjectType::None
|
||||
} else if obj.is_instance_of::<PyBool>() {
|
||||
|
@ -63,17 +63,17 @@ fn find_object_type(obj: &PyAny) -> ObjectType {
|
|||
|
||||
fn bench_identify_object_type(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let obj = py.eval("object()", None, None).unwrap();
|
||||
let obj = py.eval_bound("object()", None, None).unwrap();
|
||||
|
||||
b.iter(|| find_object_type(obj));
|
||||
b.iter(|| find_object_type(&obj));
|
||||
|
||||
assert_eq!(find_object_type(obj), ObjectType::Unknown);
|
||||
assert_eq!(find_object_type(&obj), ObjectType::Unknown);
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_collect_generic_iterator(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let collection = py.eval("list(range(1 << 20))", None, None).unwrap();
|
||||
let collection = py.eval_bound("list(range(1 << 20))", None, None).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
collection
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion};
|
||||
|
||||
use pyo3::{types::PyDict, PyAny, Python};
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyDict;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
fn extract_bigint_extract_fail(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let d = PyDict::new(py) as &PyAny;
|
||||
let d = PyDict::new_bound(py).into_any();
|
||||
|
||||
bench.iter(|| match black_box(d).extract::<BigInt>() {
|
||||
bench.iter(|| match black_box(&d).extract::<BigInt>() {
|
||||
Ok(v) => panic!("should err {}", v),
|
||||
Err(e) => black_box(e),
|
||||
});
|
||||
|
@ -17,10 +18,10 @@ fn extract_bigint_extract_fail(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_bigint_small(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let int = py.eval("-42", None, None).unwrap();
|
||||
let int = py.eval_bound("-42", None, None).unwrap();
|
||||
|
||||
bench.iter(|| {
|
||||
let v = black_box(int).extract::<BigInt>().unwrap();
|
||||
let v = black_box(&int).extract::<BigInt>().unwrap();
|
||||
black_box(v);
|
||||
});
|
||||
});
|
||||
|
@ -28,10 +29,10 @@ fn extract_bigint_small(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_bigint_big_negative(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let int = py.eval("-10**300", None, None).unwrap();
|
||||
let int = py.eval_bound("-10**300", None, None).unwrap();
|
||||
|
||||
bench.iter(|| {
|
||||
let v = black_box(int).extract::<BigInt>().unwrap();
|
||||
let v = black_box(&int).extract::<BigInt>().unwrap();
|
||||
black_box(v);
|
||||
});
|
||||
});
|
||||
|
@ -39,10 +40,10 @@ fn extract_bigint_big_negative(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_bigint_big_positive(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let int = py.eval("10**300", None, None).unwrap();
|
||||
let int = py.eval_bound("10**300", None, None).unwrap();
|
||||
|
||||
bench.iter(|| {
|
||||
let v = black_box(int).extract::<BigInt>().unwrap();
|
||||
let v = black_box(&int).extract::<BigInt>().unwrap();
|
||||
black_box(v);
|
||||
});
|
||||
});
|
||||
|
@ -50,10 +51,10 @@ fn extract_bigint_big_positive(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_bigint_huge_negative(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let int = py.eval("-10**3000", None, None).unwrap();
|
||||
let int = py.eval_bound("-10**3000", None, None).unwrap();
|
||||
|
||||
bench.iter(|| {
|
||||
let v = black_box(int).extract::<BigInt>().unwrap();
|
||||
let v = black_box(&int).extract::<BigInt>().unwrap();
|
||||
black_box(v);
|
||||
});
|
||||
});
|
||||
|
@ -61,10 +62,10 @@ fn extract_bigint_huge_negative(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_bigint_huge_positive(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let int = py.eval("10**3000", None, None).unwrap();
|
||||
let int = py.eval_bound("10**3000", None, None).unwrap();
|
||||
|
||||
bench.iter(|| {
|
||||
let v = black_box(int).extract::<BigInt>().unwrap();
|
||||
let v = black_box(&int).extract::<BigInt>().unwrap();
|
||||
black_box(v);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,20 +6,20 @@ use rust_decimal::Decimal;
|
|||
|
||||
fn decimal_via_extract(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let locals = PyDict::new(py);
|
||||
py.run(
|
||||
let locals = PyDict::new_bound(py);
|
||||
py.run_bound(
|
||||
r#"
|
||||
import decimal
|
||||
py_dec = decimal.Decimal("0.0")
|
||||
"#,
|
||||
None,
|
||||
Some(locals),
|
||||
Some(&locals),
|
||||
)
|
||||
.unwrap();
|
||||
let py_dec = locals.get_item("py_dec").unwrap().unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
let _: Decimal = black_box(py_dec).extract().unwrap();
|
||||
let _: Decimal = black_box(&py_dec).extract().unwrap();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@ use std::hint::black_box;
|
|||
fn iter_dict(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
|
||||
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py);
|
||||
let mut sum = 0;
|
||||
b.iter(|| {
|
||||
for (k, _v) in dict {
|
||||
for (k, _v) in dict.iter() {
|
||||
let i: u64 = k.extract().unwrap();
|
||||
sum += i;
|
||||
}
|
||||
|
@ -22,14 +22,14 @@ fn iter_dict(b: &mut Bencher<'_>) {
|
|||
fn dict_new(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 50_000;
|
||||
b.iter(|| (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py));
|
||||
b.iter_with_large_drop(|| (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py));
|
||||
});
|
||||
}
|
||||
|
||||
fn dict_get_item(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 50_000;
|
||||
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
|
||||
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py);
|
||||
let mut sum = 0;
|
||||
b.iter(|| {
|
||||
for i in 0..LEN {
|
||||
|
@ -47,16 +47,16 @@ fn dict_get_item(b: &mut Bencher<'_>) {
|
|||
fn extract_hashmap(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
|
||||
b.iter(|| HashMap::<u64, u64>::extract(dict));
|
||||
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py);
|
||||
b.iter(|| HashMap::<u64, u64>::extract_bound(&dict));
|
||||
});
|
||||
}
|
||||
|
||||
fn extract_btreemap(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
|
||||
b.iter(|| BTreeMap::<u64, u64>::extract(dict));
|
||||
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py);
|
||||
b.iter(|| BTreeMap::<u64, u64>::extract_bound(&dict));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -64,19 +64,15 @@ fn extract_btreemap(b: &mut Bencher<'_>) {
|
|||
fn extract_hashbrown_map(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py);
|
||||
b.iter(|| hashbrown::HashMap::<u64, u64>::extract(dict));
|
||||
let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py);
|
||||
b.iter(|| hashbrown::HashMap::<u64, u64>::extract_bound(&dict));
|
||||
});
|
||||
}
|
||||
|
||||
fn mapping_from_dict(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let dict = &(0..LEN as u64)
|
||||
.map(|i| (i, i * 2))
|
||||
.into_py_dict(py)
|
||||
.to_object(py)
|
||||
.into_bound(py);
|
||||
let dict = &(0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py);
|
||||
b.iter(|| black_box(dict).downcast::<PyMapping>().unwrap());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Benc
|
|||
use pyo3::{
|
||||
prelude::*,
|
||||
types::{PyDict, PyFloat, PyInt, PyString},
|
||||
IntoPy, PyAny, PyObject, Python,
|
||||
};
|
||||
|
||||
fn extract_str_extract_success(bench: &mut Bencher<'_>) {
|
||||
|
@ -16,9 +15,9 @@ fn extract_str_extract_success(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_str_extract_fail(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let d = PyDict::new(py) as &PyAny;
|
||||
let d = PyDict::new_bound(py).into_any();
|
||||
|
||||
bench.iter(|| match black_box(d).extract::<&str>() {
|
||||
bench.iter(|| match black_box(&d).extract::<&str>() {
|
||||
Ok(v) => panic!("should err {}", v),
|
||||
Err(e) => black_box(e),
|
||||
});
|
||||
|
@ -39,9 +38,9 @@ fn extract_str_downcast_success(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_str_downcast_fail(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let d = PyDict::new(py) as &PyAny;
|
||||
let d = PyDict::new_bound(py).into_any();
|
||||
|
||||
bench.iter(|| match black_box(d).downcast::<PyString>() {
|
||||
bench.iter(|| match black_box(&d).downcast::<PyString>() {
|
||||
Ok(v) => panic!("should err {}", v),
|
||||
Err(e) => black_box(e),
|
||||
});
|
||||
|
@ -62,9 +61,9 @@ fn extract_int_extract_success(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_int_extract_fail(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let d = PyDict::new(py) as &PyAny;
|
||||
let d = PyDict::new_bound(py).into_any();
|
||||
|
||||
bench.iter(|| match black_box(d).extract::<i64>() {
|
||||
bench.iter(|| match black_box(&d).extract::<i64>() {
|
||||
Ok(v) => panic!("should err {}", v),
|
||||
Err(e) => black_box(e),
|
||||
});
|
||||
|
@ -86,9 +85,9 @@ fn extract_int_downcast_success(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_int_downcast_fail(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let d = PyDict::new(py) as &PyAny;
|
||||
let d = PyDict::new_bound(py).into_any();
|
||||
|
||||
bench.iter(|| match black_box(d).downcast::<PyInt>() {
|
||||
bench.iter(|| match black_box(&d).downcast::<PyInt>() {
|
||||
Ok(v) => panic!("should err {}", v),
|
||||
Err(e) => black_box(e),
|
||||
});
|
||||
|
@ -109,9 +108,9 @@ fn extract_float_extract_success(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_float_extract_fail(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let d = PyDict::new(py) as &PyAny;
|
||||
let d = PyDict::new_bound(py).into_any();
|
||||
|
||||
bench.iter(|| match black_box(d).extract::<f64>() {
|
||||
bench.iter(|| match black_box(&d).extract::<f64>() {
|
||||
Ok(v) => panic!("should err {}", v),
|
||||
Err(e) => black_box(e),
|
||||
});
|
||||
|
@ -133,9 +132,9 @@ fn extract_float_downcast_success(bench: &mut Bencher<'_>) {
|
|||
|
||||
fn extract_float_downcast_fail(bench: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let d = PyDict::new(py) as &PyAny;
|
||||
let d = PyDict::new_bound(py).into_any();
|
||||
|
||||
bench.iter(|| match black_box(d).downcast::<PyFloat>() {
|
||||
bench.iter(|| match black_box(&d).downcast::<PyFloat>() {
|
||||
Ok(v) => panic!("should err {}", v),
|
||||
Err(e) => black_box(e),
|
||||
});
|
||||
|
|
|
@ -85,14 +85,18 @@ macro_rules! bigint_conversion {
|
|||
let bytes = $to_bytes(self);
|
||||
let bytes_obj = PyBytes::new_bound(py, &bytes);
|
||||
let kwargs = if $is_signed > 0 {
|
||||
let kwargs = PyDict::new(py);
|
||||
let kwargs = PyDict::new_bound(py);
|
||||
kwargs.set_item(crate::intern!(py, "signed"), true).unwrap();
|
||||
Some(kwargs)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
py.get_type::<PyLong>()
|
||||
.call_method("from_bytes", (bytes_obj, "little"), kwargs)
|
||||
.call_method(
|
||||
"from_bytes",
|
||||
(bytes_obj, "little"),
|
||||
kwargs.as_ref().map(crate::Bound::as_gil_ref),
|
||||
)
|
||||
.expect("int.from_bytes() failed during to_object()") // FIXME: #1813 or similar
|
||||
.into()
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_smallvec_from_py_object_fails() {
|
||||
Python::with_gil(|py| {
|
||||
let dict = PyDict::new(py);
|
||||
let dict = PyDict::new_bound(py);
|
||||
let sv: PyResult<SmallVec<[u64; 8]>> = dict.extract();
|
||||
assert_eq!(
|
||||
sv.unwrap_err().to_string(),
|
||||
|
|
|
@ -337,9 +337,11 @@ mod tests {
|
|||
|
||||
fn max_datetime(py: Python<'_>) -> &PyAny {
|
||||
let naive_max = datetime_class(py).getattr("max").unwrap();
|
||||
let kargs = PyDict::new(py);
|
||||
let kargs = PyDict::new_bound(py);
|
||||
kargs.set_item("tzinfo", tz_utc(py)).unwrap();
|
||||
naive_max.call_method("replace", (), Some(kargs)).unwrap()
|
||||
naive_max
|
||||
.call_method("replace", (), Some(kargs.as_gil_ref()))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -681,7 +681,7 @@ impl<'py> VarkeywordsHandler<'py> for DictVarkeywords {
|
|||
_function_description: &FunctionDescription,
|
||||
) -> PyResult<()> {
|
||||
varkeywords
|
||||
.get_or_insert_with(|| PyDict::new(name.py()))
|
||||
.get_or_insert_with(|| PyDict::new_bound(name.py()).into_gil_ref())
|
||||
.set_item(name, value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -634,7 +634,7 @@ impl<T> IntoPy<PyObject> for Borrowed<'_, '_, T> {
|
|||
/// #[new]
|
||||
/// fn __new__() -> Foo {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let dict: Py<PyDict> = PyDict::new(py).into();
|
||||
/// let dict: Py<PyDict> = PyDict::new_bound(py).unbind();
|
||||
/// Foo { inner: dict }
|
||||
/// })
|
||||
/// }
|
||||
|
@ -706,7 +706,7 @@ impl<T> IntoPy<PyObject> for Borrowed<'_, '_, T> {
|
|||
///
|
||||
/// # fn main() {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let first: Py<PyDict> = PyDict::new(py).into();
|
||||
/// let first: Py<PyDict> = PyDict::new_bound(py).unbind();
|
||||
///
|
||||
/// // All of these are valid syntax
|
||||
/// let second = Py::clone_ref(&first, py);
|
||||
|
@ -1130,7 +1130,7 @@ impl<T> Py<T> {
|
|||
///
|
||||
/// # fn main() {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let first: Py<PyDict> = PyDict::new(py).into();
|
||||
/// let first: Py<PyDict> = PyDict::new_bound(py).unbind();
|
||||
/// let second = Py::clone_ref(&first, py);
|
||||
///
|
||||
/// // Both point to the same object
|
||||
|
@ -1683,7 +1683,7 @@ impl PyObject {
|
|||
/// use pyo3::types::{PyDict, PyList};
|
||||
///
|
||||
/// Python::with_gil(|py| {
|
||||
/// let any: PyObject = PyDict::new(py).into();
|
||||
/// let any: PyObject = PyDict::new_bound(py).into();
|
||||
///
|
||||
/// assert!(any.downcast::<PyDict>(py).is_ok());
|
||||
/// assert!(any.downcast::<PyList>(py).is_err());
|
||||
|
|
|
@ -38,14 +38,14 @@ pub fn dumps<'py>(
|
|||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use pyo3::{marshal, types::PyDict};
|
||||
/// # use pyo3::{marshal, types::PyDict, prelude::PyDictMethods};
|
||||
/// # pyo3::Python::with_gil(|py| {
|
||||
/// let dict = PyDict::new(py);
|
||||
/// let dict = PyDict::new_bound(py);
|
||||
/// dict.set_item("aap", "noot").unwrap();
|
||||
/// dict.set_item("mies", "wim").unwrap();
|
||||
/// dict.set_item("zus", "jet").unwrap();
|
||||
///
|
||||
/// let bytes = marshal::dumps_bound(py, dict, marshal::VERSION);
|
||||
/// let bytes = marshal::dumps_bound(py, &dict, marshal::VERSION);
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn dumps_bound<'py>(
|
||||
|
@ -90,20 +90,20 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::types::{bytes::PyBytesMethods, PyDict};
|
||||
use crate::types::{bytes::PyBytesMethods, dict::PyDictMethods, PyDict};
|
||||
|
||||
#[test]
|
||||
fn marshal_roundtrip() {
|
||||
Python::with_gil(|py| {
|
||||
let dict = PyDict::new(py);
|
||||
let dict = PyDict::new_bound(py);
|
||||
dict.set_item("aap", "noot").unwrap();
|
||||
dict.set_item("mies", "wim").unwrap();
|
||||
dict.set_item("zus", "jet").unwrap();
|
||||
|
||||
let pybytes = dumps_bound(py, dict, VERSION).expect("marshalling failed");
|
||||
let pybytes = dumps_bound(py, &dict, VERSION).expect("marshalling failed");
|
||||
let deserialized = loads_bound(py, pybytes.as_bytes()).expect("unmarshalling failed");
|
||||
|
||||
assert!(equal(py, dict, &deserialized));
|
||||
assert!(equal(py, &dict, &deserialized));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
14
src/sync.rs
14
src/sync.rs
|
@ -210,11 +210,11 @@ impl GILOnceCell<Py<PyType>> {
|
|||
///
|
||||
/// ```
|
||||
/// use pyo3::intern;
|
||||
/// # use pyo3::{pyfunction, types::PyDict, wrap_pyfunction, PyResult, Python};
|
||||
/// # use pyo3::{pyfunction, types::PyDict, wrap_pyfunction, PyResult, Python, prelude::PyDictMethods, Bound};
|
||||
///
|
||||
/// #[pyfunction]
|
||||
/// fn create_dict(py: Python<'_>) -> PyResult<&PyDict> {
|
||||
/// let dict = PyDict::new(py);
|
||||
/// fn create_dict(py: Python<'_>) -> PyResult<Bound<'_, PyDict>> {
|
||||
/// let dict = PyDict::new_bound(py);
|
||||
/// // 👇 A new `PyString` is created
|
||||
/// // for every call of this function.
|
||||
/// dict.set_item("foo", 42)?;
|
||||
|
@ -222,8 +222,8 @@ impl GILOnceCell<Py<PyType>> {
|
|||
/// }
|
||||
///
|
||||
/// #[pyfunction]
|
||||
/// fn create_dict_faster(py: Python<'_>) -> PyResult<&PyDict> {
|
||||
/// let dict = PyDict::new(py);
|
||||
/// fn create_dict_faster(py: Python<'_>) -> PyResult<Bound<'_, PyDict>> {
|
||||
/// let dict = PyDict::new_bound(py);
|
||||
/// // 👇 A `PyString` is created once and reused
|
||||
/// // for the lifetime of the program.
|
||||
/// dict.set_item(intern!(py, "foo"), 42)?;
|
||||
|
@ -270,7 +270,7 @@ impl Interned {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::types::PyDict;
|
||||
use crate::types::{any::PyAnyMethods, dict::PyDictMethods, PyDict};
|
||||
|
||||
#[test]
|
||||
fn test_intern() {
|
||||
|
@ -279,7 +279,7 @@ mod tests {
|
|||
let foo2 = intern!(py, "foo");
|
||||
let foo3 = intern!(py, stringify!(foo));
|
||||
|
||||
let dict = PyDict::new(py);
|
||||
let dict = PyDict::new_bound(py);
|
||||
dict.set_item(foo1, 42_usize).unwrap();
|
||||
assert!(dict.contains(foo2).unwrap());
|
||||
assert_eq!(
|
||||
|
|
|
@ -388,9 +388,9 @@ impl PyAny {
|
|||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let fun = module.getattr("function")?;
|
||||
/// let args = ("hello",);
|
||||
/// let kwargs = PyDict::new(py);
|
||||
/// let kwargs = PyDict::new_bound(py);
|
||||
/// kwargs.set_item("cruel", "world")?;
|
||||
/// let result = fun.call(args, Some(kwargs))?;
|
||||
/// let result = fun.call(args, Some(kwargs.as_gil_ref()))?;
|
||||
/// assert_eq!(result.extract::<&str>()?, "called with args and kwargs");
|
||||
/// Ok(())
|
||||
/// })
|
||||
|
@ -488,9 +488,9 @@ impl PyAny {
|
|||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let instance = module.getattr("a")?;
|
||||
/// let args = ("hello",);
|
||||
/// let kwargs = PyDict::new(py);
|
||||
/// let kwargs = PyDict::new_bound(py);
|
||||
/// kwargs.set_item("cruel", "world")?;
|
||||
/// let result = instance.call_method("method", args, Some(kwargs))?;
|
||||
/// let result = instance.call_method("method", args, Some(kwargs.as_gil_ref()))?;
|
||||
/// assert_eq!(result.extract::<&str>()?, "called with args and kwargs");
|
||||
/// Ok(())
|
||||
/// })
|
||||
|
@ -691,9 +691,9 @@ impl PyAny {
|
|||
/// use pyo3::types::{PyDict, PyList};
|
||||
///
|
||||
/// Python::with_gil(|py| {
|
||||
/// let dict = PyDict::new(py);
|
||||
/// let dict = PyDict::new_bound(py);
|
||||
/// assert!(dict.is_instance_of::<PyAny>());
|
||||
/// let any: &PyAny = dict.as_ref();
|
||||
/// let any = dict.as_any();
|
||||
///
|
||||
/// assert!(any.downcast::<PyDict>().is_ok());
|
||||
/// assert!(any.downcast::<PyList>().is_err());
|
||||
|
@ -1268,9 +1268,9 @@ pub trait PyAnyMethods<'py> {
|
|||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let fun = module.getattr("function")?;
|
||||
/// let args = ("hello",);
|
||||
/// let kwargs = PyDict::new(py);
|
||||
/// let kwargs = PyDict::new_bound(py);
|
||||
/// kwargs.set_item("cruel", "world")?;
|
||||
/// let result = fun.call(args, Some(kwargs))?;
|
||||
/// let result = fun.call(args, Some(kwargs.as_gil_ref()))?;
|
||||
/// assert_eq!(result.extract::<&str>()?, "called with args and kwargs");
|
||||
/// Ok(())
|
||||
/// })
|
||||
|
@ -1360,9 +1360,9 @@ pub trait PyAnyMethods<'py> {
|
|||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let instance = module.getattr("a")?;
|
||||
/// let args = ("hello",);
|
||||
/// let kwargs = PyDict::new(py);
|
||||
/// let kwargs = PyDict::new_bound(py);
|
||||
/// kwargs.set_item("cruel", "world")?;
|
||||
/// let result = instance.call_method("method", args, Some(kwargs))?;
|
||||
/// let result = instance.call_method("method", args, Some(kwargs.as_gil_ref()))?;
|
||||
/// assert_eq!(result.extract::<&str>()?, "called with args and kwargs");
|
||||
/// Ok(())
|
||||
/// })
|
||||
|
@ -1519,9 +1519,9 @@ pub trait PyAnyMethods<'py> {
|
|||
/// use pyo3::types::{PyDict, PyList};
|
||||
///
|
||||
/// Python::with_gil(|py| {
|
||||
/// let dict = PyDict::new(py);
|
||||
/// let dict = PyDict::new_bound(py);
|
||||
/// assert!(dict.is_instance_of::<PyAny>());
|
||||
/// let any: &PyAny = dict.as_ref();
|
||||
/// let any = dict.as_any();
|
||||
///
|
||||
/// assert!(any.downcast::<PyDict>().is_ok());
|
||||
/// assert!(any.downcast::<PyList>().is_err());
|
||||
|
|
|
@ -57,6 +57,13 @@ pyobject_native_type_core!(
|
|||
|
||||
impl PyDict {
|
||||
/// Deprecated form of [`new_bound`][PyDict::new_bound].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyDict::new` will be replaced by `PyDict::new_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
#[inline]
|
||||
pub fn new(py: Python<'_>) -> &PyDict {
|
||||
Self::new_bound(py).into_gil_ref()
|
||||
|
|
|
@ -78,7 +78,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_dict_is_not_ellipsis() {
|
||||
Python::with_gil(|py| {
|
||||
assert!(PyDict::new(py).downcast::<PyEllipsis>().is_err());
|
||||
assert!(PyDict::new_bound(py).downcast::<PyEllipsis>().is_err());
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_dict_is_not_none() {
|
||||
Python::with_gil(|py| {
|
||||
assert!(PyDict::new(py).downcast::<PyNone>().is_err());
|
||||
assert!(PyDict::new_bound(py).downcast::<PyNone>().is_err());
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,7 +81,9 @@ mod tests {
|
|||
#[test]
|
||||
fn test_dict_is_not_notimplemented() {
|
||||
Python::with_gil(|py| {
|
||||
assert!(PyDict::new(py).downcast::<PyNotImplemented>().is_err());
|
||||
assert!(PyDict::new_bound(py)
|
||||
.downcast::<PyNotImplemented>()
|
||||
.is_err());
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,13 +22,13 @@ fn extract_traceback(py: Python<'_>, mut error: PyErr) -> String {
|
|||
}
|
||||
|
||||
#[derive(Debug, FromPyObject)]
|
||||
pub struct A<'a> {
|
||||
pub struct A<'py> {
|
||||
#[pyo3(attribute)]
|
||||
s: String,
|
||||
#[pyo3(item)]
|
||||
t: &'a PyString,
|
||||
t: Bound<'py, PyString>,
|
||||
#[pyo3(attribute("foo"))]
|
||||
p: &'a PyAny,
|
||||
p: Bound<'py, PyAny>,
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -58,8 +58,9 @@ fn test_named_fields_struct() {
|
|||
foo: None,
|
||||
};
|
||||
let py_c = Py::new(py, pya).unwrap();
|
||||
let a: A<'_> =
|
||||
FromPyObject::extract(py_c.as_ref(py)).expect("Failed to extract A from PyA");
|
||||
let a = py_c
|
||||
.extract::<A<'_>>(py)
|
||||
.expect("Failed to extract A from PyA");
|
||||
assert_eq!(a.s, "foo");
|
||||
assert_eq!(a.t.to_string_lossy(), "bar");
|
||||
assert!(a.p.is_none());
|
||||
|
@ -76,10 +77,12 @@ pub struct B {
|
|||
fn test_transparent_named_field_struct() {
|
||||
Python::with_gil(|py| {
|
||||
let test: PyObject = "test".into_py(py);
|
||||
let b: B = FromPyObject::extract(test.as_ref(py)).expect("Failed to extract B from String");
|
||||
let b = test
|
||||
.extract::<B>(py)
|
||||
.expect("Failed to extract B from String");
|
||||
assert_eq!(b.test, "test");
|
||||
let test: PyObject = 1.into_py(py);
|
||||
let b = B::extract(test.as_ref(py));
|
||||
let b = test.extract::<B>(py);
|
||||
assert!(b.is_err());
|
||||
});
|
||||
}
|
||||
|
@ -94,12 +97,14 @@ pub struct D<T> {
|
|||
fn test_generic_transparent_named_field_struct() {
|
||||
Python::with_gil(|py| {
|
||||
let test: PyObject = "test".into_py(py);
|
||||
let d: D<String> =
|
||||
D::extract(test.as_ref(py)).expect("Failed to extract D<String> from String");
|
||||
let d = test
|
||||
.extract::<D<String>>(py)
|
||||
.expect("Failed to extract D<String> from String");
|
||||
assert_eq!(d.test, "test");
|
||||
let test = 1usize.into_py(py);
|
||||
let d: D<usize> =
|
||||
D::extract(test.as_ref(py)).expect("Failed to extract D<usize> from String");
|
||||
let d = test
|
||||
.extract::<D<usize>>(py)
|
||||
.expect("Failed to extract D<usize> from String");
|
||||
assert_eq!(d.test, 1);
|
||||
});
|
||||
}
|
||||
|
@ -128,11 +133,12 @@ fn test_generic_named_fields_struct() {
|
|||
}
|
||||
.into_py(py);
|
||||
|
||||
let e: E<String, usize> =
|
||||
E::extract(pye.as_ref(py)).expect("Failed to extract E<String, usize> from PyE");
|
||||
let e = pye
|
||||
.extract::<E<String, usize>>(py)
|
||||
.expect("Failed to extract E<String, usize> from PyE");
|
||||
assert_eq!(e.test, "test");
|
||||
assert_eq!(e.test2, 2);
|
||||
let e = E::<usize, usize>::extract(pye.as_ref(py));
|
||||
let e = pye.extract::<E<usize, usize>>(py);
|
||||
assert!(e.is_err());
|
||||
});
|
||||
}
|
||||
|
@ -151,7 +157,7 @@ fn test_named_field_with_ext_fn() {
|
|||
test2: 0,
|
||||
}
|
||||
.into_py(py);
|
||||
let c = C::extract(pyc.as_ref(py)).expect("Failed to extract C from PyE");
|
||||
let c = pyc.extract::<C>(py).expect("Failed to extract C from PyE");
|
||||
assert_eq!(c.test, "foo");
|
||||
});
|
||||
}
|
||||
|
@ -163,10 +169,12 @@ pub struct Tuple(String, usize);
|
|||
fn test_tuple_struct() {
|
||||
Python::with_gil(|py| {
|
||||
let tup = PyTuple::new_bound(py, &[1.into_py(py), "test".into_py(py)]);
|
||||
let tup = Tuple::extract(tup.as_gil_ref());
|
||||
let tup = tup.extract::<Tuple>();
|
||||
assert!(tup.is_err());
|
||||
let tup = PyTuple::new_bound(py, &["test".into_py(py), 1.into_py(py)]);
|
||||
let tup = Tuple::extract(tup.as_gil_ref()).expect("Failed to extract Tuple from PyTuple");
|
||||
let tup = tup
|
||||
.extract::<Tuple>()
|
||||
.expect("Failed to extract Tuple from PyTuple");
|
||||
assert_eq!(tup.0, "test");
|
||||
assert_eq!(tup.1, 1);
|
||||
});
|
||||
|
@ -179,10 +187,11 @@ pub struct TransparentTuple(String);
|
|||
fn test_transparent_tuple_struct() {
|
||||
Python::with_gil(|py| {
|
||||
let tup: PyObject = 1.into_py(py);
|
||||
let tup = TransparentTuple::extract(tup.as_ref(py));
|
||||
let tup = tup.extract::<TransparentTuple>(py);
|
||||
assert!(tup.is_err());
|
||||
let test: PyObject = "test".into_py(py);
|
||||
let tup = TransparentTuple::extract(test.as_ref(py))
|
||||
let tup = test
|
||||
.extract::<TransparentTuple>(py)
|
||||
.expect("Failed to extract TransparentTuple from PyTuple");
|
||||
assert_eq!(tup.0, "test");
|
||||
});
|
||||
|
@ -215,7 +224,7 @@ fn test_struct_nested_type_errors() {
|
|||
}
|
||||
.into_py(py);
|
||||
|
||||
let test: PyResult<Baz<String, usize>> = FromPyObject::extract(pybaz.as_ref(py));
|
||||
let test = pybaz.extract::<Baz<String, usize>>(py);
|
||||
assert!(test.is_err());
|
||||
assert_eq!(
|
||||
extract_traceback(py,test.unwrap_err()),
|
||||
|
@ -237,7 +246,7 @@ fn test_struct_nested_type_errors_with_generics() {
|
|||
}
|
||||
.into_py(py);
|
||||
|
||||
let test: PyResult<Baz<usize, String>> = FromPyObject::extract(pybaz.as_ref(py));
|
||||
let test = pybaz.extract::<Baz<usize, usize>>(py);
|
||||
assert!(test.is_err());
|
||||
assert_eq!(
|
||||
extract_traceback(py, test.unwrap_err()),
|
||||
|
@ -251,7 +260,7 @@ fn test_struct_nested_type_errors_with_generics() {
|
|||
fn test_transparent_struct_error_message() {
|
||||
Python::with_gil(|py| {
|
||||
let tup: PyObject = 1.into_py(py);
|
||||
let tup = B::extract(tup.as_ref(py));
|
||||
let tup = tup.extract::<B>(py);
|
||||
assert!(tup.is_err());
|
||||
assert_eq!(
|
||||
extract_traceback(py,tup.unwrap_err()),
|
||||
|
@ -265,7 +274,7 @@ fn test_transparent_struct_error_message() {
|
|||
fn test_tuple_struct_error_message() {
|
||||
Python::with_gil(|py| {
|
||||
let tup: PyObject = (1, "test").into_py(py);
|
||||
let tup = Tuple::extract(tup.as_ref(py));
|
||||
let tup = tup.extract::<Tuple>(py);
|
||||
assert!(tup.is_err());
|
||||
assert_eq!(
|
||||
extract_traceback(py, tup.unwrap_err()),
|
||||
|
@ -279,7 +288,7 @@ fn test_tuple_struct_error_message() {
|
|||
fn test_transparent_tuple_error_message() {
|
||||
Python::with_gil(|py| {
|
||||
let tup: PyObject = 1.into_py(py);
|
||||
let tup = TransparentTuple::extract(tup.as_ref(py));
|
||||
let tup = tup.extract::<TransparentTuple>(py);
|
||||
assert!(tup.is_err());
|
||||
assert_eq!(
|
||||
extract_traceback(py, tup.unwrap_err()),
|
||||
|
@ -290,10 +299,10 @@ fn test_transparent_tuple_error_message() {
|
|||
}
|
||||
|
||||
#[derive(Debug, FromPyObject)]
|
||||
pub enum Foo<'a> {
|
||||
pub enum Foo<'py> {
|
||||
TupleVar(usize, String),
|
||||
StructVar {
|
||||
test: &'a PyString,
|
||||
test: Bound<'py, PyString>,
|
||||
},
|
||||
#[pyo3(transparent)]
|
||||
TransparentTuple(usize),
|
||||
|
@ -325,7 +334,9 @@ pub struct PyBool {
|
|||
fn test_enum() {
|
||||
Python::with_gil(|py| {
|
||||
let tup = PyTuple::new_bound(py, &[1.into_py(py), "test".into_py(py)]);
|
||||
let f = Foo::extract(tup.as_gil_ref()).expect("Failed to extract Foo from tuple");
|
||||
let f = tup
|
||||
.extract::<Foo<'_>>()
|
||||
.expect("Failed to extract Foo from tuple");
|
||||
match f {
|
||||
Foo::TupleVar(test, test2) => {
|
||||
assert_eq!(test, 1);
|
||||
|
@ -339,43 +350,55 @@ fn test_enum() {
|
|||
test2: 0,
|
||||
}
|
||||
.into_py(py);
|
||||
let f = Foo::extract(pye.as_ref(py)).expect("Failed to extract Foo from PyE");
|
||||
let f = pye
|
||||
.extract::<Foo<'_>>(py)
|
||||
.expect("Failed to extract Foo from PyE");
|
||||
match f {
|
||||
Foo::StructVar { test } => assert_eq!(test.to_string_lossy(), "foo"),
|
||||
_ => panic!("Expected extracting Foo::StructVar, got {:?}", f),
|
||||
}
|
||||
|
||||
let int: PyObject = 1.into_py(py);
|
||||
let f = Foo::extract(int.as_ref(py)).expect("Failed to extract Foo from int");
|
||||
let f = int
|
||||
.extract::<Foo<'_>>(py)
|
||||
.expect("Failed to extract Foo from int");
|
||||
match f {
|
||||
Foo::TransparentTuple(test) => assert_eq!(test, 1),
|
||||
_ => panic!("Expected extracting Foo::TransparentTuple, got {:?}", f),
|
||||
}
|
||||
let none = py.None();
|
||||
let f = Foo::extract(none.as_ref(py)).expect("Failed to extract Foo from int");
|
||||
let f = none
|
||||
.extract::<Foo<'_>>(py)
|
||||
.expect("Failed to extract Foo from int");
|
||||
match f {
|
||||
Foo::TransparentStructVar { a } => assert!(a.is_none()),
|
||||
_ => panic!("Expected extracting Foo::TransparentStructVar, got {:?}", f),
|
||||
}
|
||||
|
||||
let pybool = PyBool { bla: true }.into_py(py);
|
||||
let f = Foo::extract(pybool.as_ref(py)).expect("Failed to extract Foo from PyBool");
|
||||
let f = pybool
|
||||
.extract::<Foo<'_>>(py)
|
||||
.expect("Failed to extract Foo from PyBool");
|
||||
match f {
|
||||
Foo::StructVarGetAttrArg { a } => assert!(a),
|
||||
_ => panic!("Expected extracting Foo::StructVarGetAttrArg, got {:?}", f),
|
||||
}
|
||||
|
||||
let dict = PyDict::new(py);
|
||||
let dict = PyDict::new_bound(py);
|
||||
dict.set_item("a", "test").expect("Failed to set item");
|
||||
let f = Foo::extract(dict.as_ref()).expect("Failed to extract Foo from dict");
|
||||
let f = dict
|
||||
.extract::<Foo<'_>>()
|
||||
.expect("Failed to extract Foo from dict");
|
||||
match f {
|
||||
Foo::StructWithGetItem { a } => assert_eq!(a, "test"),
|
||||
_ => panic!("Expected extracting Foo::StructWithGetItem, got {:?}", f),
|
||||
}
|
||||
|
||||
let dict = PyDict::new(py);
|
||||
let dict = PyDict::new_bound(py);
|
||||
dict.set_item("foo", "test").expect("Failed to set item");
|
||||
let f = Foo::extract(dict.as_ref()).expect("Failed to extract Foo from dict");
|
||||
let f = dict
|
||||
.extract::<Foo<'_>>()
|
||||
.expect("Failed to extract Foo from dict");
|
||||
match f {
|
||||
Foo::StructWithGetItemArg { a } => assert_eq!(a, "test"),
|
||||
_ => panic!("Expected extracting Foo::StructWithGetItemArg, got {:?}", f),
|
||||
|
@ -386,8 +409,8 @@ fn test_enum() {
|
|||
#[test]
|
||||
fn test_enum_error() {
|
||||
Python::with_gil(|py| {
|
||||
let dict = PyDict::new(py);
|
||||
let err = Foo::extract(dict.as_ref()).unwrap_err();
|
||||
let dict = PyDict::new_bound(py);
|
||||
let err = dict.extract::<Foo<'_>>().unwrap_err();
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
"\
|
||||
|
@ -402,7 +425,7 @@ TypeError: failed to extract enum Foo ('TupleVar | StructVar | TransparentTuple
|
|||
);
|
||||
|
||||
let tup = PyTuple::empty_bound(py);
|
||||
let err = Foo::extract(tup.as_gil_ref()).unwrap_err();
|
||||
let err = tup.extract::<Foo<'_>>().unwrap_err();
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
"\
|
||||
|
@ -419,23 +442,24 @@ TypeError: failed to extract enum Foo ('TupleVar | StructVar | TransparentTuple
|
|||
}
|
||||
|
||||
#[derive(Debug, FromPyObject)]
|
||||
enum EnumWithCatchAll<'a> {
|
||||
enum EnumWithCatchAll<'py> {
|
||||
#[allow(dead_code)]
|
||||
#[pyo3(transparent)]
|
||||
Foo(Foo<'a>),
|
||||
Foo(Foo<'py>),
|
||||
#[pyo3(transparent)]
|
||||
CatchAll(&'a PyAny),
|
||||
CatchAll(Bound<'py, PyAny>),
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum_catch_all() {
|
||||
Python::with_gil(|py| {
|
||||
let dict = PyDict::new(py);
|
||||
let f = EnumWithCatchAll::extract(dict.as_ref())
|
||||
let dict = PyDict::new_bound(py);
|
||||
let f = dict
|
||||
.extract::<EnumWithCatchAll<'_>>()
|
||||
.expect("Failed to extract EnumWithCatchAll from dict");
|
||||
match f {
|
||||
EnumWithCatchAll::CatchAll(any) => {
|
||||
let d = <&PyDict>::extract(any).expect("Expected pydict");
|
||||
let d = any.extract::<Bound<'_, PyDict>>().expect("Expected pydict");
|
||||
assert!(d.is_empty());
|
||||
}
|
||||
_ => panic!(
|
||||
|
@ -459,8 +483,8 @@ pub enum Bar {
|
|||
#[test]
|
||||
fn test_err_rename() {
|
||||
Python::with_gil(|py| {
|
||||
let dict = PyDict::new(py);
|
||||
let f = Bar::extract(dict.as_ref());
|
||||
let dict = PyDict::new_bound(py);
|
||||
let f = dict.extract::<Bar>();
|
||||
assert!(f.is_err());
|
||||
assert_eq!(
|
||||
f.unwrap_err().to_string(),
|
||||
|
@ -493,7 +517,7 @@ fn test_from_py_with() {
|
|||
)
|
||||
.expect("failed to create dict");
|
||||
|
||||
let zap = Zap::extract_bound(&py_zap).unwrap();
|
||||
let zap = py_zap.extract::<Zap>().unwrap();
|
||||
|
||||
assert_eq!(zap.name, "whatever");
|
||||
assert_eq!(zap.some_object_length, 3usize);
|
||||
|
@ -510,7 +534,7 @@ fn test_from_py_with_tuple_struct() {
|
|||
.eval_bound(r#"("whatever", [1, 2, 3])"#, None, None)
|
||||
.expect("failed to create tuple");
|
||||
|
||||
let zap = ZapTuple::extract_bound(&py_zap).unwrap();
|
||||
let zap = py_zap.extract::<ZapTuple>().unwrap();
|
||||
|
||||
assert_eq!(zap.0, "whatever");
|
||||
assert_eq!(zap.1, 3usize);
|
||||
|
@ -524,7 +548,7 @@ fn test_from_py_with_tuple_struct_error() {
|
|||
.eval_bound(r#"("whatever", [1, 2, 3], "third")"#, None, None)
|
||||
.expect("failed to create tuple");
|
||||
|
||||
let f = ZapTuple::extract_bound(&py_zap);
|
||||
let f = py_zap.extract::<ZapTuple>();
|
||||
|
||||
assert!(f.is_err());
|
||||
assert_eq!(
|
||||
|
@ -547,7 +571,7 @@ fn test_from_py_with_enum() {
|
|||
.eval_bound(r#"("whatever", [1, 2, 3])"#, None, None)
|
||||
.expect("failed to create tuple");
|
||||
|
||||
let zap = ZapEnum::extract_bound(&py_zap).unwrap();
|
||||
let zap = py_zap.extract::<ZapEnum>().unwrap();
|
||||
let expected_zap = ZapEnum::Zip(2);
|
||||
|
||||
assert_eq!(zap, expected_zap);
|
||||
|
@ -564,8 +588,9 @@ pub struct TransparentFromPyWith {
|
|||
#[test]
|
||||
fn test_transparent_from_py_with() {
|
||||
Python::with_gil(|py| {
|
||||
let result =
|
||||
TransparentFromPyWith::extract(PyList::new_bound(py, [1, 2, 3]).as_gil_ref()).unwrap();
|
||||
let result = PyList::new_bound(py, [1, 2, 3])
|
||||
.extract::<TransparentFromPyWith>()
|
||||
.unwrap();
|
||||
let expected = TransparentFromPyWith { len: 3 };
|
||||
|
||||
assert_eq!(result, expected);
|
||||
|
|
|
@ -216,7 +216,7 @@ fn mapping() {
|
|||
let inst = Py::new(
|
||||
py,
|
||||
Mapping {
|
||||
values: PyDict::new(py).into(),
|
||||
values: PyDict::new_bound(py).into(),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use pyo3::{types::PyDict, Py, Python};
|
||||
use pyo3::{types::PyDict, Bound, Py, Python};
|
||||
|
||||
fn main() {
|
||||
let dict: Py<PyDict> = Python::with_gil(|py| PyDict::new(py).into());
|
||||
let dict: Py<PyDict> = Python::with_gil(|py| PyDict::new_bound(py).unbind());
|
||||
|
||||
// Should not be able to get access to Py contents outside of with_gil.
|
||||
let dict: &PyDict = Python::with_gil(|py| dict.as_ref(py));
|
||||
let dict: &Bound<'_, PyDict> = Python::with_gil(|py| dict.bind(py));
|
||||
|
||||
let _py: Python = dict.py(); // Obtain a Python<'p> without GIL.
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error: lifetime may not live long enough
|
||||
--> tests/ui/wrong_aspyref_lifetimes.rs:7:47
|
||||
--> tests/ui/wrong_aspyref_lifetimes.rs:7:58
|
||||
|
|
||||
7 | let dict: &PyDict = Python::with_gil(|py| dict.as_ref(py));
|
||||
| --- ^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
|
||||
| | |
|
||||
| | return type of closure is &'2 PyDict
|
||||
| has type `pyo3::Python<'1>`
|
||||
7 | let dict: &Bound<'_, PyDict> = Python::with_gil(|py| dict.bind(py));
|
||||
| --- ^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
|
||||
| | |
|
||||
| | return type of closure is &'2 pyo3::Bound<'_, PyDict>
|
||||
| has type `pyo3::Python<'1>`
|
||||
|
|
Loading…
Reference in New Issue