diff --git a/CHANGELOG.md b/CHANGELOG.md index af1d1d3ae..9a316c7ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - v0.26.0 - bump MSRV to 1.74, matching PyO3 ([#504](https://github.com/PyO3/rust-numpy/pull/504)) - extend supported `nalgebra` version to `0.34` ([#503](https://github.com/PyO3/rust-numpy/pull/503)) + - Bump PyO3 dependency to v0.26.0. ([#506](https://github.com/PyO3/rust-numpy/pull/506)) - v0.25.0, - Bump PyO3 dependency to v0.25.0. ([#492](https://github.com/PyO3/rust-numpy/pull/492)) diff --git a/Cargo.toml b/Cargo.toml index 9e298dffe..e30f53051 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "numpy" -version = "0.25.0" +version = "0.26.0" authors = [ "The rust-numpy Project Developers", "PyO3 Project and Contributors ", @@ -22,11 +22,11 @@ num-complex = ">= 0.2, < 0.5" num-integer = "0.1" num-traits = "0.2" ndarray = ">= 0.15, < 0.17" -pyo3 = { version = "0.25.0", default-features = false, features = ["macros"] } +pyo3 = { version = "0.26.0", default-features = false, features = ["macros"]} rustc-hash = "2.0" [dev-dependencies] -pyo3 = { version = "0.25", default-features = false, features = [ +pyo3 = { version = "0.26.0", default-features = false, features = [ "auto-initialize", ] } nalgebra = { version = ">=0.30, <0.35", default-features = false, features = [ @@ -34,7 +34,7 @@ nalgebra = { version = ">=0.30, <0.35", default-features = false, features = [ ] } [build-dependencies] -pyo3-build-config = { version = "0.25", features = ["resolve-config"] } +pyo3-build-config = { version = "0.26", features = ["resolve-config"]} [package.metadata.docs.rs] all-features = true diff --git a/README.md b/README.md index 32e72eebd..f7401e8c1 100644 --- a/README.md +++ b/README.md @@ -102,13 +102,13 @@ use numpy::{PyArray1, PyArrayMethods}; use pyo3::{types::{IntoPyDict, PyAnyMethods}, PyResult, Python, ffi::c_str}; fn main() -> PyResult<()> { - Python::with_gil(|py| { + Python::attach(|py| { let np = py.import("numpy")?; let locals = [("np", np)].into_py_dict(py)?; let pyarray = py .eval(c_str!("np.absolute(np.array([-1, -2, -3], dtype='int32'))"), Some(&locals), None)? - .downcast_into::>()?; + .cast_into::>()?; let readonly = pyarray.readonly(); let slice = readonly.as_slice()?; diff --git a/benches/array.rs b/benches/array.rs index 756a352bd..332e6295e 100644 --- a/benches/array.rs +++ b/benches/array.rs @@ -10,7 +10,7 @@ use pyo3::{types::PyAnyMethods, Bound, IntoPyObjectExt, Python}; #[bench] fn extract_success(bencher: &mut Bencher) { - Python::with_gil(|py| { + Python::attach(|py| { let any = PyArray2::::zeros(py, (10, 10), false).into_any(); bencher.iter(|| { @@ -23,7 +23,7 @@ fn extract_success(bencher: &mut Bencher) { #[bench] fn extract_failure(bencher: &mut Bencher) { - Python::with_gil(|py| { + Python::attach(|py| { let any = PyArray2::::zeros(py, (10, 10), false).into_any(); bencher.iter(|| { @@ -35,20 +35,20 @@ fn extract_failure(bencher: &mut Bencher) { } #[bench] -fn downcast_success(bencher: &mut Bencher) { - Python::with_gil(|py| { +fn cast_success(bencher: &mut Bencher) { + Python::attach(|py| { let any = PyArray2::::zeros(py, (10, 10), false).into_any(); - bencher.iter(|| black_box(&any).downcast::>().unwrap()); + bencher.iter(|| black_box(&any).cast::>().unwrap()); }); } #[bench] -fn downcast_failure(bencher: &mut Bencher) { - Python::with_gil(|py| { +fn cast_failure(bencher: &mut Bencher) { + Python::attach(|py| { let any = PyArray2::::zeros(py, (10, 10), false).into_any(); - bencher.iter(|| black_box(&any).downcast::>().unwrap_err()); + bencher.iter(|| black_box(&any).cast::>().unwrap_err()); }); } @@ -63,7 +63,7 @@ impl Iterator for Iter { } fn from_iter(bencher: &mut Bencher, size: usize) { - Python::with_gil(|py| { + Python::attach(|py| { bencher.iter(|| { let iter = black_box(Iter(0..size)); @@ -90,7 +90,7 @@ fn from_iter_large(bencher: &mut Bencher) { fn from_slice(bencher: &mut Bencher, size: usize) { let vec = (0..size).collect::>(); - Python::with_gil(|py| { + Python::attach(|py| { bencher.iter(|| { let slice = black_box(&vec); @@ -115,13 +115,13 @@ fn from_slice_large(bencher: &mut Bencher) { } fn from_object_slice(bencher: &mut Bencher, size: usize) { - let vec = Python::with_gil(|py| { + let vec = Python::attach(|py| { (0..size) .map(|val| val.into_py_any(py).unwrap()) .collect::>() }); - Python::with_gil(|py| { + Python::attach(|py| { bencher.iter(|| { let slice = black_box(&vec); @@ -148,7 +148,7 @@ fn from_object_slice_large(bencher: &mut Bencher) { fn from_vec2(bencher: &mut Bencher, size: usize) { let vec2 = vec![vec![0; size]; size]; - Python::with_gil(|py| { + Python::attach(|py| { bencher.iter(|| { let vec2 = black_box(&vec2); @@ -175,7 +175,7 @@ fn from_vec2_large(bencher: &mut Bencher) { fn from_vec3(bencher: &mut Bencher, size: usize) { let vec3 = vec![vec![vec![0; size]; size]; size]; - Python::with_gil(|py| { + Python::attach(|py| { bencher.iter(|| { let vec3 = black_box(&vec3); diff --git a/benches/borrow.rs b/benches/borrow.rs index f7c0c7641..346a7f7be 100644 --- a/benches/borrow.rs +++ b/benches/borrow.rs @@ -8,7 +8,7 @@ use pyo3::Python; #[bench] fn initial_shared_borrow(bencher: &mut Bencher) { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (6, 5, 4, 3, 2, 1), false); bencher.iter(|| { @@ -21,7 +21,7 @@ fn initial_shared_borrow(bencher: &mut Bencher) { #[bench] fn additional_shared_borrow(bencher: &mut Bencher) { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (6, 5, 4, 3, 2, 1), false); let _shared = (0..128).map(|_| array.readonly()).collect::>(); @@ -36,7 +36,7 @@ fn additional_shared_borrow(bencher: &mut Bencher) { #[bench] fn exclusive_borrow(bencher: &mut Bencher) { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (6, 5, 4, 3, 2, 1), false); bencher.iter(|| { diff --git a/examples/linalg/Cargo.lock b/examples/linalg/Cargo.lock index 78dc1acb6..9c23c1e7f 100644 --- a/examples/linalg/Cargo.lock +++ b/examples/linalg/Cargo.lock @@ -398,7 +398,7 @@ dependencies = [ [[package]] name = "numpy" -version = "0.24.0" +version = "0.26.0" dependencies = [ "libc", "ndarray", @@ -412,9 +412,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openblas-build" @@ -524,11 +524,10 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17da310086b068fbdcefbba30aeb3721d5bb9af8db4987d6735b2183ca567229" +checksum = "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383" dependencies = [ - "cfg-if", "indoc", "libc", "memoffset", @@ -542,19 +541,18 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27165889bd793000a098bb966adc4300c312497ea25cf7a690a9f0ac5aa5fc1" +checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f" dependencies = [ - "once_cell", "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05280526e1dbf6b420062f3ef228b78c0c54ba94e157f5cb724a609d0f2faabc" +checksum = "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105" dependencies = [ "libc", "pyo3-build-config", @@ -562,9 +560,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3ce5686aa4d3f63359a5100c62a127c9f15e8398e5fdeb5deef1fed5cd5f44" +checksum = "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -574,9 +572,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4cf6faa0cbfb0ed08e89beb8103ae9724eb4750e3a78084ba4017cbe94f3855" +checksum = "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf" dependencies = [ "heck", "proc-macro2", diff --git a/examples/linalg/Cargo.toml b/examples/linalg/Cargo.toml index b80adcfaa..29888c7e0 100644 --- a/examples/linalg/Cargo.toml +++ b/examples/linalg/Cargo.toml @@ -9,7 +9,7 @@ name = "rust_linalg" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.25.0", features = ["extension-module"] } +pyo3 = { version = "0.26.0", features = ["extension-module"] } numpy = { path = "../.." } ndarray-linalg = { version = "0.14.1", features = ["openblas-system"] } diff --git a/examples/parallel/Cargo.toml b/examples/parallel/Cargo.toml index 2b53eca47..969632e2d 100644 --- a/examples/parallel/Cargo.toml +++ b/examples/parallel/Cargo.toml @@ -9,7 +9,7 @@ name = "rust_parallel" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.25.0", features = ["extension-module", "multiple-pymethods"] } +pyo3 = { version = "0.26.0", features = ["extension-module", "multiple-pymethods"] } numpy = { path = "../.." } ndarray = { version = "0.16", features = ["rayon", "blas"] } blas-src = { version = "0.8", features = ["openblas"] } diff --git a/examples/simple/Cargo.toml b/examples/simple/Cargo.toml index 9920d1792..f67c69d9d 100644 --- a/examples/simple/Cargo.toml +++ b/examples/simple/Cargo.toml @@ -9,7 +9,7 @@ name = "rust_ext" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.25.0", features = ["extension-module", "abi3-py37"] } +pyo3 = { version = "0.26.0", features = ["extension-module", "abi3-py37"] } numpy = { path = "../.." } [workspace] diff --git a/examples/simple/src/lib.rs b/examples/simple/src/lib.rs index 3bb29e3e1..fd41372a1 100644 --- a/examples/simple/src/lib.rs +++ b/examples/simple/src/lib.rs @@ -9,14 +9,14 @@ use numpy::{ use pyo3::{ exceptions::PyIndexError, pymodule, - types::{PyAnyMethods, PyDict, PyDictMethods, PyModule}, - Bound, FromPyObject, PyAny, PyObject, PyResult, Python, + types::{PyDict, PyDictMethods, PyModule}, + Bound, FromPyObject, Py, PyAny, PyResult, Python, }; #[pymodule] fn rust_ext<'py>(m: &Bound<'py, PyModule>) -> PyResult<()> { - // example using generic PyObject - fn head(py: Python<'_>, x: ArrayViewD<'_, PyObject>) -> PyResult { + // example using generic Py + fn head(py: Python<'_>, x: ArrayViewD<'_, Py>) -> PyResult> { x.get(0) .map(|obj| obj.clone_ref(py)) .ok_or_else(|| PyIndexError::new_err("array index out of range")) @@ -48,7 +48,7 @@ fn rust_ext<'py>(m: &Bound<'py, PyModule>) -> PyResult<()> { // wrapper of `head` #[pyfn(m)] #[pyo3(name = "head")] - fn head_py<'py>(x: PyReadonlyArrayDyn<'py, PyObject>) -> PyResult { + fn head_py<'py>(x: PyReadonlyArrayDyn<'py, Py>) -> PyResult> { head(x.py(), x.as_array()) } @@ -92,7 +92,7 @@ fn rust_ext<'py>(m: &Bound<'py, PyModule>) -> PyResult<()> { .get_item("x") .unwrap() .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); x.readonly().as_array().sum() @@ -141,7 +141,7 @@ fn rust_ext<'py>(m: &Bound<'py, PyModule>) -> PyResult<()> { .into_any()), (SupportedArray::F64(x), SupportedArray::I64(y)) | (SupportedArray::I64(y), SupportedArray::F64(x)) => { - let y = y.cast::(false)?; + let y = y.cast_array::(false)?; Ok( generic_add(x.readonly().as_array(), y.readonly().as_array()) diff --git a/src/array.rs b/src/array.rs index b7623e862..814a303ea 100644 --- a/src/array.rs +++ b/src/array.rs @@ -17,8 +17,8 @@ use ndarray::{ use num_traits::AsPrimitive; use pyo3::{ ffi, - types::{DerefToPyAny, PyAnyMethods, PyModule}, - Bound, DowncastError, Py, PyAny, PyErr, PyObject, PyResult, PyTypeInfo, Python, + types::{DerefToPyAny, PyModule}, + Bound, DowncastError, Py, PyAny, PyErr, PyResult, PyTypeInfo, Python, }; use crate::borrow::{PyReadonlyArray, PyReadwriteArray}; @@ -83,7 +83,7 @@ use crate::untyped_array::{PyUntypedArray, PyUntypedArrayMethods}; /// use ndarray::{array, Array}; /// use pyo3::Python; /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let pyarray = PyArray::arange(py, 0., 4., 1.).reshape([2, 2]).unwrap(); /// let array = array![[3., 4.], [5., 6.]]; /// @@ -146,7 +146,7 @@ impl PyArray { if npyffi::PyArray_Check(ob.py(), ob.as_ptr()) == 0 { return Err(DowncastError::new(ob, ::NAME).into()); } - ob.downcast_unchecked::() + ob.cast_unchecked::() }; // Check if the dimensionality matches `D`. @@ -190,7 +190,7 @@ impl PyArray { /// use numpy::PyArray3; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let arr = unsafe { /// let arr = PyArray3::::new(py, [4, 5, 6], false); /// @@ -238,7 +238,7 @@ impl PyArray { ptr::null_mut(), // obj ); - Bound::from_owned_ptr(py, ptr).downcast_into_unchecked() + Bound::from_owned_ptr(py, ptr).cast_into_unchecked() } unsafe fn new_with_data<'py, ID>( @@ -270,7 +270,7 @@ impl PyArray { container as *mut ffi::PyObject, ); - Bound::from_owned_ptr(py, ptr).downcast_into_unchecked() + Bound::from_owned_ptr(py, ptr).cast_into_unchecked() } pub(crate) unsafe fn from_raw_parts<'py>( @@ -357,7 +357,7 @@ impl PyArray { /// use numpy::{PyArray2, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray2::::zeros(py, [2, 2], true); /// /// assert_eq!(pyarray.readonly().as_slice().unwrap(), [0; 4]); @@ -379,7 +379,7 @@ impl PyArray { T::get_dtype(py).into_dtype_ptr(), if is_fortran { -1 } else { 0 }, ); - Bound::from_owned_ptr(py, ptr).downcast_into_unchecked() + Bound::from_owned_ptr(py, ptr).cast_into_unchecked() } } @@ -394,7 +394,7 @@ impl PyArray { /// use ndarray::array; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::from_owned_array(py, array![[1, 2], [3, 4]]); /// /// assert_eq!(pyarray.readonly().as_array(), array![[1, 2], [3, 4]]); @@ -426,7 +426,7 @@ impl PyArray { /// use ndarray::array; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::from_array(py, &array![[1, 2], [3, 4]]); /// /// assert_eq!(pyarray.readonly().as_array(), array![[1, 2], [3, 4]]); @@ -440,7 +440,7 @@ impl PyArray { } } -impl PyArray { +impl PyArray, D> { /// Construct a NumPy array containing objects stored in a [`ndarray::Array`] /// /// This method uses the internal [`Vec`] of the [`ndarray::Array`] as the base object of the NumPy array. @@ -459,7 +459,7 @@ impl PyArray { /// bar: f64, /// } /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let array = array![ /// Py::new(py, CustomElement { /// foo: 1, @@ -478,7 +478,7 @@ impl PyArray { /// ``` pub fn from_owned_object_array(py: Python<'_>, mut arr: Array, D>) -> Bound<'_, Self> { let (strides, dims) = (arr.npy_strides(), arr.raw_dim()); - let data_ptr = arr.as_mut_ptr() as *const PyObject; + let data_ptr = arr.as_mut_ptr().cast::>().cast_const(); unsafe { Self::from_raw_parts( py, @@ -500,7 +500,7 @@ impl PyArray { /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let slice = &[1, 2, 3, 4, 5]; /// let pyarray = PyArray::from_slice(py, slice); /// assert_eq!(pyarray.readonly().as_slice().unwrap(), &[1, 2, 3, 4, 5]); @@ -523,7 +523,7 @@ impl PyArray { /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let vec = vec![1, 2, 3, 4, 5]; /// let pyarray = PyArray::from_vec(py, vec); /// assert_eq!(pyarray.readonly().as_slice().unwrap(), &[1, 2, 3, 4, 5]); @@ -545,7 +545,7 @@ impl PyArray { /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::from_iter(py, "abcde".chars().map(u32::from)); /// assert_eq!(pyarray.readonly().as_slice().unwrap(), &[97, 98, 99, 100, 101]); /// }); @@ -572,7 +572,7 @@ impl PyArray { /// use pyo3::Python; /// use ndarray::array; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let vec2 = vec![vec![11, 12], vec![21, 22]]; /// let pyarray = PyArray::from_vec2(py, &vec2).unwrap(); /// assert_eq!(pyarray.readonly().as_array(), array![[11, 12], [21, 22]]); @@ -613,7 +613,7 @@ impl PyArray { /// use pyo3::Python; /// use ndarray::array; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let vec3 = vec![ /// vec![vec![111, 112], vec![121, 122]], /// vec![vec![211, 212], vec![221, 222]], @@ -671,7 +671,7 @@ impl> PyArray { /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::arange(py, 2.0, 4.0, 0.5); /// assert_eq!(pyarray.readonly().as_slice().unwrap(), &[2.0, 2.5, 3.0, 3.5]); /// @@ -691,7 +691,7 @@ impl> PyArray { step.as_(), T::get_dtype(py).num(), ); - Bound::from_owned_ptr(py, ptr).downcast_into_unchecked() + Bound::from_owned_ptr(py, ptr).cast_into_unchecked() } } } @@ -785,7 +785,7 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::arange(py, 0, 16, 1).reshape([2, 2, 4]).unwrap(); /// /// assert_eq!(unsafe { *pyarray.get([1, 0, 3]).unwrap() }, 11); @@ -812,7 +812,7 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::arange(py, 0, 16, 1).reshape([2, 2, 4]).unwrap(); /// /// unsafe { @@ -847,7 +847,7 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::arange(py, 0, 16, 1).reshape([2, 2, 4]).unwrap(); /// /// assert_eq!(unsafe { *pyarray.uget([1, 0, 3]) }, 11); @@ -908,7 +908,7 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::arange(py, 0, 16, 1).reshape([2, 2, 4]).unwrap(); /// /// assert_eq!(pyarray.get_owned([1, 0, 3]), Some(11)); @@ -937,10 +937,10 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use pyo3::{Python, types::PyAnyMethods, ffi::c_str}; /// /// # fn main() -> pyo3::PyResult<()> { - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray= py /// .eval(c_str!("__import__('numpy').array([[0, 1], [2, 3]], dtype='int64')"), None, None)? - /// .downcast_into::>()?; + /// .cast_into::>()?; /// /// assert_eq!(pyarray.to_vec()?, vec![0, 1, 2, 3]); /// # Ok(()) @@ -1042,7 +1042,7 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use ndarray::array; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::arange(py, 0, 4, 1).reshape([2, 2]).unwrap(); /// /// assert_eq!( @@ -1066,7 +1066,7 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray_f = PyArray::arange(py, 2.0, 5.0, 1.0); /// let pyarray_i = unsafe { PyArray::::new(py, [3], false) }; /// @@ -1081,6 +1081,16 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { where T: Element; + /// Deprecated version of [`cast_array`](PyArrayMethods::cast_array) + #[deprecated(since = "0.26.0", note = "use `cast_array` instead")] + #[inline] + fn cast(&self, is_fortran: bool) -> PyResult>> + where + T: Element, + { + self.cast_array(is_fortran) + } + /// Cast the `PyArray` to `PyArray`, by allocating a new array. /// /// See also [`PyArray_CastToType`][PyArray_CastToType]. @@ -1091,17 +1101,17 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray_f = PyArray::arange(py, 2.0, 5.0, 1.0); /// - /// let pyarray_i = pyarray_f.cast::(false).unwrap(); + /// let pyarray_i = pyarray_f.cast_array::(false).unwrap(); /// /// assert_eq!(pyarray_i.readonly().as_slice().unwrap(), &[2, 3, 4]); /// }); /// ``` /// /// [PyArray_CastToType]: https://numpy.org/doc/stable/reference/c-api/array.html#c.PyArray_CastToType - fn cast(&self, is_fortran: bool) -> PyResult>> + fn cast_array(&self, is_fortran: bool) -> PyResult>> where T: Element; @@ -1119,7 +1129,7 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use pyo3::Python; /// use ndarray::array; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let array = array![[0, 1, 2], [3, 4, 5]].into_pyarray(py); /// /// let array = array.permute(Some([1, 0])).unwrap(); @@ -1156,7 +1166,7 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use pyo3::Python; /// use ndarray::array; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let array = /// PyArray::from_iter(py, 0..9).reshape_with_order([3, 3], NPY_ORDER::NPY_FORTRANORDER).unwrap(); /// @@ -1205,7 +1215,7 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// use numpy::PyArray; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::::zeros(py, (10, 10), false); /// assert_eq!(pyarray.shape(), [10, 10]); /// @@ -1402,7 +1412,7 @@ where impl<'py, T, D> PyArrayMethods<'py, T, D> for Bound<'py, PyArray> { #[inline(always)] fn as_untyped(&self) -> &Bound<'py, PyUntypedArray> { - unsafe { self.downcast_unchecked() } + unsafe { self.cast_unchecked() } } #[inline(always)] @@ -1441,7 +1451,7 @@ impl<'py, T, D> PyArrayMethods<'py, T, D> for Bound<'py, PyArray> { } fn to_dyn(&self) -> &Bound<'py, PyArray> { - unsafe { self.downcast_unchecked() } + unsafe { self.cast_unchecked() } } fn to_vec(&self) -> Result, NotContiguousError> @@ -1528,7 +1538,7 @@ impl<'py, T, D> PyArrayMethods<'py, T, D> for Bound<'py, PyArray> { } } - fn cast(&self, is_fortran: bool) -> PyResult>> + fn cast_array(&self, is_fortran: bool) -> PyResult>> where T: Element, { @@ -1540,9 +1550,7 @@ impl<'py, T, D> PyArrayMethods<'py, T, D> for Bound<'py, PyArray> { if is_fortran { -1 } else { 0 }, ) }; - unsafe { - Bound::from_owned_ptr_or_err(self.py(), ptr).map(|ob| ob.downcast_into_unchecked()) - } + unsafe { Bound::from_owned_ptr_or_err(self.py(), ptr).map(|ob| ob.cast_into_unchecked()) } } fn permute(&self, axes: Option) -> PyResult>> { @@ -1554,7 +1562,7 @@ impl<'py, T, D> PyArrayMethods<'py, T, D> for Bound<'py, PyArray> { let py = self.py(); let ptr = unsafe { PY_ARRAY_API.PyArray_Transpose(py, self.as_array_ptr(), axes) }; - unsafe { Bound::from_owned_ptr_or_err(py, ptr).map(|ob| ob.downcast_into_unchecked()) } + unsafe { Bound::from_owned_ptr_or_err(py, ptr).map(|ob| ob.cast_into_unchecked()) } } fn reshape_with_order( @@ -1577,7 +1585,7 @@ impl<'py, T, D> PyArrayMethods<'py, T, D> for Bound<'py, PyArray> { order, ) }; - unsafe { Bound::from_owned_ptr_or_err(py, ptr).map(|ob| ob.downcast_into_unchecked()) } + unsafe { Bound::from_owned_ptr_or_err(py, ptr).map(|ob| ob.cast_into_unchecked()) } } unsafe fn resize(&self, newshape: ID) -> PyResult<()> @@ -1653,7 +1661,7 @@ mod tests { #[test] fn test_dyn_to_owned_array() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::from_vec2(py, &[vec![1, 2], vec![3, 4]]) .unwrap() .to_dyn() @@ -1665,8 +1673,8 @@ mod tests { #[test] fn test_hasobject_flag() { - Python::with_gil(|py| { - let array: Bound<'_, PyArray> = + Python::attach(|py| { + let array: Bound<'_, PyArray, _>> = PyArray1::from_slice(py, &[PyList::empty(py).into()]); py_run!(py, array, "assert array.dtype.hasobject"); diff --git a/src/array_like.rs b/src/array_like.rs index 1c7a0b36b..c00fb5de7 100644 --- a/src/array_like.rs +++ b/src/array_like.rs @@ -4,7 +4,7 @@ use std::ops::Deref; use ndarray::{Array1, Dimension, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn}; use pyo3::{ intern, - sync::GILOnceCell, + sync::PyOnceLock, types::{PyAnyMethods, PyDict}, Bound, FromPyObject, Py, PyAny, PyResult, }; @@ -66,7 +66,7 @@ impl Coerce for AllowTypeChange { /// array.as_array().sum() /// } /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let np = get_array_module(py).unwrap(); /// let sum_up = wrap_pyfunction!(sum_up)(py).unwrap(); /// @@ -87,7 +87,7 @@ impl Coerce for AllowTypeChange { /// array.as_array().sum() /// } /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let np = get_array_module(py).unwrap(); /// let sum_up = wrap_pyfunction!(sum_up)(py).unwrap(); /// @@ -107,7 +107,7 @@ impl Coerce for AllowTypeChange { /// array.as_array().sum() /// } /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let np = get_array_module(py).unwrap(); /// let sum_up = wrap_pyfunction!(sum_up)(py).unwrap(); /// @@ -143,7 +143,7 @@ where Vec: FromPyObject<'py>, { fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult { - if let Ok(array) = ob.downcast::>() { + if let Ok(array) = ob.cast::>() { return Ok(Self(array.readonly(), PhantomData)); } @@ -160,7 +160,7 @@ where } } - static AS_ARRAY: GILOnceCell> = GILOnceCell::new(); + static AS_ARRAY: PyOnceLock> = PyOnceLock::new(); let as_array = AS_ARRAY .get_or_try_init(py, || { diff --git a/src/borrow/mod.rs b/src/borrow/mod.rs index dd6846678..b3bf61950 100644 --- a/src/borrow/mod.rs +++ b/src/borrow/mod.rs @@ -40,7 +40,7 @@ //! assert!(res.is_err()); //! } //! -//! Python::with_gil(|py| { +//! Python::attach(|py| { //! let x = PyArray1::::zeros(py, 42, false); //! let y = PyArray1::::zeros(py, 42, false); //! let z = PyArray1::::zeros(py, 42, false); @@ -66,14 +66,14 @@ //! use pyo3::{types::{IntoPyDict, PyAnyMethods}, Python, ffi::c_str}; //! //! # fn main() -> pyo3::PyResult<()> { -//! Python::with_gil(|py| { +//! Python::attach(|py| { //! let array = PyArray1::arange(py, 0.0, 10.0, 1.0); //! let locals = [("array", array)].into_py_dict(py)?; //! -//! let view1 = py.eval(c_str!("array[:5]"), None, Some(&locals))?.downcast_into::>()?; -//! let view2 = py.eval(c_str!("array[5:]"), None, Some(&locals))?.downcast_into::>()?; -//! let view3 = py.eval(c_str!("array[::2]"), None, Some(&locals))?.downcast_into::>()?; -//! let view4 = py.eval(c_str!("array[1::2]"), None, Some(&locals))?.downcast_into::>()?; +//! let view1 = py.eval(c_str!("array[:5]"), None, Some(&locals))?.cast_into::>()?; +//! let view2 = py.eval(c_str!("array[5:]"), None, Some(&locals))?.cast_into::>()?; +//! let view3 = py.eval(c_str!("array[::2]"), None, Some(&locals))?.cast_into::>()?; +//! let view4 = py.eval(c_str!("array[1::2]"), None, Some(&locals))?.cast_into::>()?; //! //! { //! let _view1 = view1.readwrite(); @@ -98,12 +98,12 @@ //! use pyo3::{types::{IntoPyDict, PyAnyMethods}, Python, ffi::c_str}; //! //! # fn main() -> pyo3::PyResult<()> { -//! Python::with_gil(|py| { +//! Python::attach(|py| { //! let array = PyArray2::::zeros(py, (10, 10), false); //! let locals = [("array", array)].into_py_dict(py)?; //! -//! let view1 = py.eval(c_str!("array[:, ::3]"), None, Some(&locals))?.downcast_into::>()?; -//! let view2 = py.eval(c_str!("array[:, 1::3]"), None, Some(&locals))?.downcast_into::>()?; +//! let view1 = py.eval(c_str!("array[:, ::3]"), None, Some(&locals))?.cast_into::>()?; +//! let view2 = py.eval(c_str!("array[:, 1::3]"), None, Some(&locals))?.cast_into::>()?; //! //! // A false conflict as the views do not actually share any elements. //! let res = catch_unwind(AssertUnwindSafe(|| { @@ -140,7 +140,7 @@ //! which does not require aliasing discipline. //! //! Concerning multi-threading in particular: While the GIL needs to be acquired to create borrows, they are not bound to the GIL -//! and will stay active after the GIL is released, for example by calling [`allow_threads`][pyo3::Python::allow_threads]. +//! and will stay active after the GIL is released, for example by calling [`detach`][pyo3::Python::detach]. //! Borrows also do not provide synchronization, i.e. multiple threads borrowing the same array will lead to runtime panics, //! it will not block those threads until already active borrows are released. //! @@ -175,7 +175,7 @@ use std::ops::Deref; use ndarray::{ ArrayView, ArrayViewMut, Dimension, IntoDimension, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn, }; -use pyo3::{types::PyAnyMethods, Bound, FromPyObject, PyAny, PyResult}; +use pyo3::{Bound, FromPyObject, PyAny, PyResult}; use crate::array::{PyArray, PyArrayMethods}; use crate::convert::NpyIndex; @@ -239,7 +239,7 @@ where impl<'py, T: Element, D: Dimension> FromPyObject<'py> for PyReadonlyArray<'py, T, D> { fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult { - let array = obj.downcast::>()?; + let array = obj.cast::>()?; Ok(array.readonly()) } } @@ -312,7 +312,7 @@ where /// } /// /// # fn main() -> pyo3::PyResult<()> { - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let np = py.eval(c_str!("__import__('numpy')"), None, None)?; /// let sum_standard_layout = wrap_pyfunction!(sum_standard_layout)(py)?; /// let sum_dynamic_strides = wrap_pyfunction!(sum_dynamic_strides)(py)?; @@ -478,7 +478,7 @@ where impl<'py, T: Element, D: Dimension> FromPyObject<'py> for PyReadwriteArray<'py, T, D> { fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult { - let array = obj.downcast::>()?; + let array = obj.cast::>()?; Ok(array.readwrite()) } } @@ -604,7 +604,7 @@ where /// use numpy::{PyArray, PyArrayMethods, PyUntypedArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let pyarray = PyArray::arange(py, 0, 10, 1); /// assert_eq!(pyarray.len(), 10); /// @@ -667,7 +667,7 @@ mod tests { #[test] fn test_debug_formatting() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); { @@ -693,7 +693,7 @@ mod tests { #[test] #[should_panic(expected = "AlreadyBorrowed")] fn cannot_clone_exclusive_borrow_via_deref() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (3, 2, 1), false); let exclusive = array.readwrite(); @@ -703,7 +703,7 @@ mod tests { #[test] fn failed_resize_does_not_double_release() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, 10, false); // The view will make the internal reference check of `PyArray_Resize` fail. @@ -711,7 +711,7 @@ mod tests { let _view = py .eval(c_str!("array[:]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let exclusive = array.readwrite(); @@ -721,7 +721,7 @@ mod tests { #[test] fn ineffective_resize_does_not_conflict() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, 10, false); let exclusive = array.readwrite(); diff --git a/src/borrow/shared.rs b/src/borrow/shared.rs index 9f8d1fb6d..837e96629 100644 --- a/src/borrow/shared.rs +++ b/src/borrow/shared.rs @@ -6,8 +6,9 @@ use std::slice::from_raw_parts; use std::sync::Mutex; use num_integer::gcd; +use pyo3::sync::PyOnceLock; use pyo3::types::{PyAnyMethods, PyCapsuleMethods}; -use pyo3::{exceptions::PyTypeError, sync::GILOnceCell, types::PyCapsule, PyResult, Python}; +use pyo3::{exceptions::PyTypeError, types::PyCapsule, PyResult, Python}; use rustc_hash::FxHashMap; use crate::array::get_array_module; @@ -41,8 +42,8 @@ unsafe impl Send for Shared {} // These are the entry points which implement the shared borrow checking API: unsafe extern "C" fn acquire_shared(flags: *mut c_void, array: *mut PyArrayObject) -> c_int { - // SAFETY: GIL must be held when calling `acquire_shared`. - let py = Python::assume_gil_acquired(); + // SAFETY: must be attached when calling `acquire_shared`. + let py = Python::assume_attached(); let flags = &*(flags as *mut BorrowFlags); let address = base_address(py, array); @@ -59,8 +60,8 @@ unsafe extern "C" fn acquire_mut_shared(flags: *mut c_void, array: *mut PyArrayO return -2; } - // SAFETY: GIL must be held when calling `acquire_shared`. - let py = Python::assume_gil_acquired(); + // SAFETY: must be attached when calling `acquire_shared`. + let py = Python::assume_attached(); let flags = &*(flags as *mut BorrowFlags); let address = base_address(py, array); @@ -73,8 +74,8 @@ unsafe extern "C" fn acquire_mut_shared(flags: *mut c_void, array: *mut PyArrayO } unsafe extern "C" fn release_shared(flags: *mut c_void, array: *mut PyArrayObject) { - // SAFETY: GIL must be held when calling `acquire_shared`. - let py = Python::assume_gil_acquired(); + // SAFETY: must be attached when calling `acquire_shared`. + let py = Python::assume_attached(); let flags = &*(flags as *mut BorrowFlags); let address = base_address(py, array); let key = borrow_key(py, array); @@ -83,8 +84,8 @@ unsafe extern "C" fn release_shared(flags: *mut c_void, array: *mut PyArrayObjec } unsafe extern "C" fn release_mut_shared(flags: *mut c_void, array: *mut PyArrayObject) { - // SAFETY: GIL must be held when calling `acquire_shared`. - let py = Python::assume_gil_acquired(); + // SAFETY: must be attached when calling `acquire_shared`. + let py = Python::assume_attached(); let flags = &*(flags as *mut BorrowFlags); let address = base_address(py, array); @@ -95,13 +96,13 @@ unsafe extern "C" fn release_mut_shared(flags: *mut c_void, array: *mut PyArrayO // This global state is a cache used to access the shared borrow checking API from this extension: -struct SharedPtr(GILOnceCell<*const Shared>); +struct SharedPtr(PyOnceLock<*const Shared>); unsafe impl Send for SharedPtr {} unsafe impl Sync for SharedPtr {} -static SHARED: SharedPtr = SharedPtr(GILOnceCell::new()); +static SHARED: SharedPtr = SharedPtr(PyOnceLock::new()); fn get_or_insert_shared<'py>(py: Python<'py>) -> PyResult<&'py Shared> { let shared = SHARED.0.get_or_try_init(py, || insert_shared(py))?; @@ -120,7 +121,7 @@ fn insert_shared<'py>(py: Python<'py>) -> PyResult<*const Shared> { let module = get_array_module(py)?; let capsule = match module.getattr("_RUST_NUMPY_BORROW_CHECKING_API") { - Ok(capsule) => capsule.downcast_into::()?, + Ok(capsule) => capsule.cast_into::()?, Err(_err) => { let flags: *mut BorrowFlags = Box::into_raw(Box::default()); @@ -482,7 +483,7 @@ mod tests { #[test] fn without_base_object() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let base = unsafe { (*array.as_array_ptr()).base }; @@ -499,7 +500,7 @@ mod tests { #[test] fn with_base_object() { - Python::with_gil(|py| { + Python::attach(|py| { let array = Array::::zeros((1, 2, 3)).into_pyarray(py); let base = unsafe { (*array.as_array_ptr()).base }; @@ -519,14 +520,14 @@ mod tests { #[test] fn view_without_base_object() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let locals = [("array", &array)].into_py_dict(py).unwrap(); let view = py .eval(c_str!("array[:,:,0]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_ne!( view.as_ptr().cast::(), @@ -548,14 +549,14 @@ mod tests { #[test] fn view_with_base_object() { - Python::with_gil(|py| { + Python::attach(|py| { let array = Array::::zeros((1, 2, 3)).into_pyarray(py); let locals = [("array", &array)].into_py_dict(py).unwrap(); let view = py .eval(c_str!("array[:,:,0]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_ne!( view.as_ptr().cast::(), @@ -583,14 +584,14 @@ mod tests { #[test] fn view_of_view_without_base_object() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let locals = [("array", &array)].into_py_dict(py).unwrap(); let view1 = py .eval(c_str!("array[:,:,0]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_ne!( view1.as_ptr().cast::(), @@ -601,7 +602,7 @@ mod tests { let view2 = py .eval(c_str!("view1[:,0]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_ne!( view2.as_ptr().cast::(), @@ -631,14 +632,14 @@ mod tests { #[test] fn view_of_view_with_base_object() { - Python::with_gil(|py| { + Python::attach(|py| { let array = Array::::zeros((1, 2, 3)).into_pyarray(py); let locals = [("array", &array)].into_py_dict(py).unwrap(); let view1 = py .eval(c_str!("array[:,:,0]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_ne!( view1.as_ptr().cast::(), @@ -649,7 +650,7 @@ mod tests { let view2 = py .eval(c_str!("view1[:,0]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_ne!( view2.as_ptr().cast::(), @@ -685,14 +686,14 @@ mod tests { #[test] fn view_with_negative_strides() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let locals = [("array", &array)].into_py_dict(py).unwrap(); let view = py .eval(c_str!("array[::-1,:,::-1]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_ne!( view.as_ptr().cast::(), @@ -717,7 +718,7 @@ mod tests { #[test] fn array_with_zero_dimensions() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 0, 3), false); let base = unsafe { (*array.as_array_ptr()).base }; @@ -734,14 +735,14 @@ mod tests { #[test] fn view_with_non_dividing_strides() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (10, 10), false); let locals = [("array", array)].into_py_dict(py).unwrap(); let view1 = py .eval(c_str!("array[:,::3]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let key1 = borrow_key(py, view1.as_array_ptr()); @@ -752,7 +753,7 @@ mod tests { let view2 = py .eval(c_str!("array[:,1::3]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let key2 = borrow_key(py, view2.as_array_ptr()); @@ -763,7 +764,7 @@ mod tests { let view3 = py .eval(c_str!("array[:,::2]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let key3 = borrow_key(py, view3.as_array_ptr()); @@ -774,7 +775,7 @@ mod tests { let view4 = py .eval(c_str!("array[:,1::2]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let key4 = borrow_key(py, view4.as_array_ptr()); @@ -793,7 +794,7 @@ mod tests { #[test] fn borrow_multiple_arrays() { - Python::with_gil(|py| { + Python::attach(|py| { let array1 = PyArray::::zeros(py, 10, false); let array2 = PyArray::::zeros(py, 10, false); @@ -834,7 +835,7 @@ mod tests { #[test] fn borrow_multiple_views() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, 10, false); let base = base_address(py, array.as_array_ptr()); @@ -843,7 +844,7 @@ mod tests { let view1 = py .eval(c_str!("array[:5]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let key1 = borrow_key(py, view1.as_array_ptr()); @@ -862,7 +863,7 @@ mod tests { let view2 = py .eval(c_str!("array[5:]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let key2 = borrow_key(py, view2.as_array_ptr()); @@ -883,7 +884,7 @@ mod tests { let view3 = py .eval(c_str!("array[5:]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let key3 = borrow_key(py, view3.as_array_ptr()); @@ -907,7 +908,7 @@ mod tests { let view4 = py .eval(c_str!("array[7:]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let key4 = borrow_key(py, view4.as_array_ptr()); diff --git a/src/convert.rs b/src/convert.rs index b4c71ec2d..7165f2391 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -23,7 +23,7 @@ use crate::slice_container::PySliceContainer; /// use numpy::{PyArray, IntoPyArray, PyArrayMethods}; /// use pyo3::Python; /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let py_array = vec![1, 2, 3].into_pyarray(py); /// /// assert_eq!(py_array.readonly().as_slice().unwrap(), &[1, 2, 3]); @@ -103,7 +103,7 @@ where /// use numpy::{PyArray, ToPyArray, PyArrayMethods}; /// use pyo3::Python; /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let py_array = vec![1, 2, 3].to_pyarray(py); /// /// assert_eq!(py_array.readonly().as_slice().unwrap(), &[1, 2, 3]); @@ -118,7 +118,7 @@ where /// use ndarray::{arr3, s}; /// use pyo3::Python; /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let array = arr3(&[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]); /// let py_array = array.slice(s![.., 0..1, ..]).to_pyarray(py); /// diff --git a/src/datetime.rs b/src/datetime.rs index d9b51bd7f..d5e65618a 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -15,10 +15,10 @@ //! # use pyo3::types::PyDict; //! //! # fn main() -> pyo3::PyResult<()> { -//! Python::with_gil(|py| { +//! Python::attach(|py| { //! # let locals = py //! # .eval(c_str!("{ 'np': __import__('numpy') }"), None, None)? -//! # .downcast_into::()?; +//! # .cast_into::()?; //! # //! let array = py //! .eval( @@ -26,7 +26,7 @@ //! None, //! Some(&locals), //! )? -//! .downcast_into::>>()?; +//! .cast_into::>>()?; //! //! assert_eq!( //! array.get_owned(0).unwrap(), @@ -39,7 +39,7 @@ //! None, //! Some(&locals), //! )? -//! .downcast_into::>>()?; +//! .cast_into::>>()?; //! //! assert_eq!( //! array.get_owned(0).unwrap(), @@ -258,18 +258,18 @@ mod tests { use pyo3::{ ffi::c_str, py_run, - types::{PyAnyMethods, PyDict, PyModule}, + types::{PyDict, PyModule}, }; use crate::array::{PyArray1, PyArrayMethods}; #[test] fn from_python_to_rust() { - Python::with_gil(|py| { + Python::attach(|py| { let locals = py .eval(c_str!("{ 'np': __import__('numpy') }"), None, None) .unwrap() - .downcast_into::() + .cast_into::() .unwrap(); let array = py @@ -279,7 +279,7 @@ mod tests { Some(&locals), ) .unwrap() - .downcast_into::>>() + .cast_into::>>() .unwrap(); let value: i64 = array.get_owned(0).unwrap().into(); @@ -289,7 +289,7 @@ mod tests { #[test] fn from_rust_to_python() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray1::>::zeros(py, 1, false); *array.readwrite().get_mut(0).unwrap() = Timedelta::::from(5); @@ -297,7 +297,7 @@ mod tests { let np = py .eval(c_str!("__import__('numpy')"), None, None) .unwrap() - .downcast_into::() + .cast_into::() .unwrap(); py_run!(py, array np, "assert array.dtype == np.dtype('timedelta64[m]')"); @@ -323,13 +323,13 @@ mod tests { #[track_caller] fn convert<'py, S: Unit, D: Unit>(py: Python<'py>, expected_value: i64) { let array = PyArray1::>::from_slice(py, &[Timedelta::::from(1)]); - let array = array.cast::>(false).unwrap(); + let array = array.cast_array::>(false).unwrap(); let value: i64 = array.get_owned(0).unwrap().into(); assert_eq!(value, expected_value); } - Python::with_gil(|py| { + Python::attach(|py| { convert::(py, (97 + 400 * 365) / 400); convert::(py, (97 + 400 * 365) / 400 / 12); diff --git a/src/dtype.rs b/src/dtype.rs index 5c65f60e7..6a39bb2b2 100644 --- a/src/dtype.rs +++ b/src/dtype.rs @@ -6,14 +6,14 @@ use std::ptr; use half::{bf16, f16}; use num_traits::{Bounded, Zero}; #[cfg(feature = "half")] -use pyo3::sync::GILOnceCell; +use pyo3::sync::PyOnceLock; use pyo3::{ conversion::IntoPyObject, exceptions::{PyIndexError, PyValueError}, ffi::{self, PyTuple_Size}, pyobject_native_type_named, types::{PyAnyMethods, PyDict, PyDictMethods, PyTuple, PyType}, - Borrowed, Bound, Py, PyAny, PyObject, PyResult, PyTypeInfo, Python, + Borrowed, Bound, Py, PyAny, PyResult, PyTypeInfo, Python, }; use crate::npyffi::{ @@ -33,12 +33,12 @@ pub use num_complex::{Complex32, Complex64}; /// use numpy::pyo3::{types::{IntoPyDict, PyAnyMethods}, Python, ffi::c_str}; /// /// # fn main() -> pyo3::PyResult<()> { -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let locals = [("np", get_array_module(py)?)].into_py_dict(py)?; /// /// let dt = py /// .eval(c_str!("np.array([1, 2, 3.0]).dtype"), Some(&locals), None)? -/// .downcast_into::()?; +/// .cast_into::()?; /// /// assert!(dt.is_equiv_to(&dtype::(py))); /// # Ok(()) @@ -87,8 +87,7 @@ impl PyArrayDescr { unsafe { // None is an invalid input here and is not converted to NPY_DEFAULT_TYPE PY_ARRAY_API.PyArray_DescrConverter2(py, obj.as_ptr(), &mut descr); - Bound::from_owned_ptr_or_err(py, descr.cast()) - .map(|any| any.downcast_into_unchecked()) + Bound::from_owned_ptr_or_err(py, descr.cast()).map(|any| any.cast_into_unchecked()) } } @@ -116,14 +115,14 @@ impl PyArrayDescr { fn from_npy_type<'py>(py: Python<'py>, npy_type: NPY_TYPES) -> Bound<'py, Self> { unsafe { let descr = PY_ARRAY_API.PyArray_DescrFromType(py, npy_type as _); - Bound::from_owned_ptr(py, descr.cast()).downcast_into_unchecked() + Bound::from_owned_ptr(py, descr.cast()).cast_into_unchecked() } } pub(crate) fn new_from_npy_type<'py>(py: Python<'py>, npy_type: NPY_TYPES) -> Bound<'py, Self> { unsafe { let descr = PY_ARRAY_API.PyArray_DescrNewFromType(py, npy_type as _); - Bound::from_owned_ptr(py, descr.cast()).downcast_into_unchecked() + Bound::from_owned_ptr(py, descr.cast()).cast_into_unchecked() } } } @@ -360,7 +359,7 @@ impl<'py> PyArrayDescrMethods<'py> for Bound<'py, PyArrayDescr> { match subarray { None => self.clone(), Some(subarray) => unsafe { - Bound::from_borrowed_ptr(self.py(), subarray.base.cast()).downcast_into_unchecked() + Bound::from_borrowed_ptr(self.py(), subarray.base.cast()).cast_into_unchecked() }, } } @@ -404,18 +403,18 @@ impl<'py> PyArrayDescrMethods<'py> for Bound<'py, PyArrayDescr> { let dict = unsafe { Borrowed::from_ptr(self.py(), PyDataType_FIELDS(self.py(), self.as_dtype_ptr())) }; - let dict = unsafe { dict.downcast_unchecked::() }; + let dict = unsafe { dict.cast_unchecked::() }; // NumPy guarantees that fields are tuples of proper size and type, so this should never panic. let tuple = dict .get_item(name)? .ok_or_else(|| PyIndexError::new_err(name.to_owned()))? - .downcast_into::() + .cast_into::() .unwrap(); // Note that we cannot just extract the entire tuple since the third element can be a title. let dtype = tuple .get_item(0) .unwrap() - .downcast_into::() + .cast_into::() .unwrap(); let offset = tuple.get_item(1).unwrap().extract().unwrap(); Ok((dtype, offset)) @@ -613,7 +612,7 @@ unsafe impl Element for bf16 { const IS_COPY: bool = true; fn get_dtype(py: Python<'_>) -> Bound<'_, PyArrayDescr> { - static DTYPE: GILOnceCell> = GILOnceCell::new(); + static DTYPE: PyOnceLock> = PyOnceLock::new(); DTYPE .get_or_init(py, || { @@ -634,7 +633,7 @@ impl_element_scalar!(Complex64 => NPY_CDOUBLE, #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] impl_element_scalar!(usize, isize); -unsafe impl Element for PyObject { +unsafe impl Element for Py { const IS_COPY: bool = false; fn get_dtype(py: Python<'_>) -> Bound<'_, PyArrayDescr> { @@ -658,7 +657,7 @@ mod tests { #[test] fn test_dtype_new() { - Python::with_gil(|py| { + Python::attach(|py| { assert!(PyArrayDescr::new(py, "float64") .unwrap() .is(dtype::(py))); @@ -666,7 +665,7 @@ mod tests { let dt = PyArrayDescr::new(py, [("a", "O"), ("b", "?")].as_ref()).unwrap(); assert_eq!(dt.names(), Some(vec!["a".to_owned(), "b".to_owned()])); assert!(dt.has_object()); - assert!(dt.get_field("a").unwrap().0.is(dtype::(py))); + assert!(dt.get_field("a").unwrap().0.is(dtype::>(py))); assert!(dt.get_field("b").unwrap().0.is(dtype::(py))); assert!(PyArrayDescr::new(py, 123_usize).is_err()); @@ -678,7 +677,7 @@ mod tests { fn type_name(py: Python<'_>) -> Bound<'_, PyString> { dtype::(py).typeobj().qualname().unwrap() } - Python::with_gil(|py| { + Python::attach(|py| { if is_numpy_2(py) { assert_eq!(type_name::(py), "bool"); } else { @@ -715,7 +714,7 @@ mod tests { #[test] fn test_dtype_methods_scalar() { - Python::with_gil(|py| { + Python::attach(|py| { let dt = dtype::(py); assert_eq!(dt.num(), NPY_TYPES::NPY_DOUBLE as c_int); @@ -740,7 +739,7 @@ mod tests { #[test] fn test_dtype_methods_subarray() { - Python::with_gil(|py| { + Python::attach(|py| { let locals = PyDict::new(py); py_run!( py, @@ -751,7 +750,7 @@ mod tests { .get_item("dtype") .unwrap() .unwrap() - .downcast_into::() + .cast_into::() .unwrap(); assert_eq!(dt.num(), NPY_TYPES::NPY_VOID as c_int); @@ -776,7 +775,7 @@ mod tests { #[test] fn test_dtype_methods_record() { - Python::with_gil(|py| { + Python::attach(|py| { let locals = PyDict::new(py); py_run!( py, @@ -787,7 +786,7 @@ mod tests { .get_item("dtype") .unwrap() .unwrap() - .downcast_into::() + .cast_into::() .unwrap(); assert_eq!(dt.num(), NPY_TYPES::NPY_VOID as c_int); @@ -819,7 +818,7 @@ mod tests { assert!(y.0.is_equiv_to(&dtype::(py))); assert_eq!(y.1, 8); let z = dt.get_field("z").unwrap(); - assert!(z.0.is_equiv_to(&dtype::(py))); + assert!(z.0.is_equiv_to(&dtype::>(py))); assert_eq!(z.1, 16); }); } diff --git a/src/error.rs b/src/error.rs index 7293488fe..dbe852c61 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,7 +4,7 @@ use std::error::Error; use std::fmt; use pyo3::{ - conversion::IntoPyObject, exceptions::PyTypeError, Bound, Py, PyErr, PyErrArguments, PyObject, + conversion::IntoPyObject, exceptions::PyTypeError, Bound, Py, PyAny, PyErr, PyErrArguments, Python, }; @@ -22,7 +22,7 @@ macro_rules! impl_pyerr { impl Error for $err_type {} impl PyErrArguments for $err_type { - fn arguments<'py>(self, py: Python<'py>) -> PyObject { + fn arguments<'py>(self, py: Python<'py>) -> Py { self.to_string() .into_pyobject(py) .unwrap() @@ -91,7 +91,7 @@ struct TypeErrorArguments { } impl PyErrArguments for TypeErrorArguments { - fn arguments<'py>(self, py: Python<'py>) -> PyObject { + fn arguments<'py>(self, py: Python<'py>) -> Py { let err = TypeError { from: self.from.into_bound(py), to: self.to.into_bound(py), diff --git a/src/lib.rs b/src/lib.rs index 195465022..446615e99 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ as well as the [`PyReadonlyArray::try_as_matrix`] and [`PyReadwriteArray::try_as //! use numpy::ndarray::array; //! use numpy::{ToPyArray, PyArray, PyArrayMethods}; //! -//! Python::with_gil(|py| { +//! Python::attach(|py| { //! let py_array = array![[1i64, 2], [3, 4]].to_pyarray(py); //! //! assert_eq!( @@ -41,7 +41,7 @@ as well as the [`PyReadonlyArray::try_as_matrix`] and [`PyReadwriteArray::try_as //! use numpy::nalgebra::Matrix3; //! use numpy::{pyarray, ToPyArray, PyArrayMethods}; //! -//! Python::with_gil(|py| { +//! Python::attach(|py| { //! let py_array = pyarray![py, [0, 1, 2], [3, 4, 5], [6, 7, 8]]; //! //! let py_array_square; @@ -156,7 +156,7 @@ fn cold() {} /// use numpy::ndarray::array; /// use numpy::{pyarray, PyArrayMethods}; /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let array = pyarray![py, [1, 2], [3, 4]]; /// /// assert_eq!( diff --git a/src/npyffi/array.rs b/src/npyffi/array.rs index 045cee49a..4c337de74 100644 --- a/src/npyffi/array.rs +++ b/src/npyffi/array.rs @@ -9,13 +9,13 @@ use std::os::raw::*; use libc::FILE; use pyo3::{ ffi::{self, PyObject, PyTypeObject}, - sync::GILOnceCell, + sync::PyOnceLock, }; use crate::npyffi::*; pub(crate) fn numpy_core_name(py: Python<'_>) -> PyResult<&'static str> { - static MOD_NAME: GILOnceCell<&'static str> = GILOnceCell::new(); + static MOD_NAME: PyOnceLock<&'static str> = PyOnceLock::new(); MOD_NAME .get_or_try_init(py, || { @@ -42,7 +42,7 @@ pub(crate) fn numpy_core_name(py: Python<'_>) -> PyResult<&'static str> { } pub(crate) fn mod_name(py: Python<'_>) -> PyResult<&'static str> { - static MOD_NAME: GILOnceCell = GILOnceCell::new(); + static MOD_NAME: PyOnceLock = PyOnceLock::new(); MOD_NAME .get_or_try_init(py, || { let numpy_core = numpy_core_name(py)?; @@ -64,7 +64,7 @@ const CAPSULE_NAME: &str = "_ARRAY_API"; /// ``` /// use numpy::prelude::*; /// use numpy::{PyArray, npyffi::types::NPY_SORTKIND, PY_ARRAY_API}; -/// pyo3::Python::with_gil(|py| { +/// pyo3::Python::attach(|py| { /// let array = PyArray::from_slice(py, &[3, 2, 4]); /// unsafe { /// PY_ARRAY_API.PyArray_Sort(py, array.as_array_ptr(), 0, NPY_SORTKIND::NPY_QUICKSORT); @@ -72,10 +72,10 @@ const CAPSULE_NAME: &str = "_ARRAY_API"; /// assert_eq!(array.readonly().as_slice().unwrap(), &[2, 3, 4]); /// }) /// ``` -pub static PY_ARRAY_API: PyArrayAPI = PyArrayAPI(GILOnceCell::new()); +pub static PY_ARRAY_API: PyArrayAPI = PyArrayAPI(PyOnceLock::new()); /// See [PY_ARRAY_API] for more. -pub struct PyArrayAPI(GILOnceCell<*const *const c_void>); +pub struct PyArrayAPI(PyOnceLock<*const *const c_void>); unsafe impl Send for PyArrayAPI {} @@ -476,7 +476,7 @@ mod tests { #[test] fn call_api() { - Python::with_gil(|py| unsafe { + Python::attach(|py| unsafe { assert_eq!( PY_ARRAY_API.PyArray_MultiplyIntList(py, [1, 2, 3].as_mut_ptr(), 3), 6 diff --git a/src/npyffi/mod.rs b/src/npyffi/mod.rs index bf846f8e2..5f8be15ca 100644 --- a/src/npyffi/mod.rs +++ b/src/npyffi/mod.rs @@ -13,14 +13,14 @@ use std::mem::forget; use std::os::raw::{c_uint, c_void}; use pyo3::{ - sync::GILOnceCell, + sync::PyOnceLock, types::{PyAnyMethods, PyCapsule, PyCapsuleMethods, PyModule}, PyResult, Python, }; pub const API_VERSION_2_0: c_uint = 0x00000012; -static API_VERSION: GILOnceCell = GILOnceCell::new(); +static API_VERSION: PyOnceLock = PyOnceLock::new(); fn get_numpy_api<'py>( py: Python<'py>, @@ -28,7 +28,7 @@ fn get_numpy_api<'py>( capsule: &str, ) -> PyResult<*const *const c_void> { let module = PyModule::import(py, module)?; - let capsule = module.getattr(capsule)?.downcast_into::()?; + let capsule = module.getattr(capsule)?.cast_into::()?; let api = capsule.pointer() as *const *const c_void; diff --git a/src/npyffi/ufunc.rs b/src/npyffi/ufunc.rs index ef677cc52..bc5d504ca 100644 --- a/src/npyffi/ufunc.rs +++ b/src/npyffi/ufunc.rs @@ -2,12 +2,12 @@ use std::os::raw::*; -use pyo3::{ffi::PyObject, sync::GILOnceCell}; +use pyo3::{ffi::PyObject, sync::PyOnceLock}; use crate::npyffi::*; fn mod_name(py: Python<'_>) -> PyResult<&'static str> { - static MOD_NAME: GILOnceCell = GILOnceCell::new(); + static MOD_NAME: PyOnceLock = PyOnceLock::new(); MOD_NAME .get_or_try_init(py, || { let numpy_core = super::array::numpy_core_name(py)?; @@ -20,9 +20,9 @@ const CAPSULE_NAME: &str = "_UFUNC_API"; /// A global variable which stores a ['capsule'](https://docs.python.org/3/c-api/capsule.html) /// pointer to [Numpy UFunc API](https://numpy.org/doc/stable/reference/c-api/ufunc.html). -pub static PY_UFUNC_API: PyUFuncAPI = PyUFuncAPI(GILOnceCell::new()); +pub static PY_UFUNC_API: PyUFuncAPI = PyUFuncAPI(PyOnceLock::new()); -pub struct PyUFuncAPI(GILOnceCell<*const *const c_void>); +pub struct PyUFuncAPI(PyOnceLock<*const *const c_void>); unsafe impl Send for PyUFuncAPI {} diff --git a/src/strings.rs b/src/strings.rs index 4520cf96f..3204b2df8 100644 --- a/src/strings.rs +++ b/src/strings.rs @@ -50,7 +50,7 @@ use crate::npyffi::NPY_TYPES; /// # use pyo3::Python; /// use numpy::{PyArray1, PyUntypedArrayMethods, PyFixedString}; /// -/// # Python::with_gil(|py| { +/// # Python::attach(|py| { /// let array = PyArray1::>::from_vec(py, vec![[b'f', b'o', b'o'].into()]); /// /// assert!(array.dtype().to_string().contains("S3")); @@ -115,7 +115,7 @@ unsafe impl Element for PyFixedString { /// # use pyo3::Python; /// use numpy::{PyArray1, PyUntypedArrayMethods, PyFixedUnicode}; /// -/// # Python::with_gil(|py| { +/// # Python::attach(|py| { /// let array = PyArray1::>::from_vec(py, vec![[b'b' as _, b'a' as _, b'r' as _].into()]); /// /// assert!(array.dtype().to_string().contains("U3")); diff --git a/src/sum_products.rs b/src/sum_products.rs index 95b6bd8e9..ba18938a7 100644 --- a/src/sum_products.rs +++ b/src/sum_products.rs @@ -34,7 +34,7 @@ impl<'py, T> ArrayOrScalar<'py, T> for T where T: Element + FromPyObject<'py> {} /// use pyo3::Python; /// use numpy::{inner, pyarray, PyArray0}; /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let vector = pyarray![py, 1.0, 2.0, 3.0]; /// let result: f64 = inner(&vector, &vector).unwrap(); /// assert_eq!(result, 14.0); @@ -48,7 +48,7 @@ impl<'py, T> ArrayOrScalar<'py, T> for T where T: Element + FromPyObject<'py> {} /// use numpy::prelude::*; /// use numpy::{inner, pyarray, PyArray0}; /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let vector = pyarray![py, 1, 2, 3]; /// let result: Bound<'_, PyArray0<_>> = inner(&vector, &vector).unwrap(); /// assert_eq!(result.item(), 14); @@ -87,7 +87,7 @@ where /// use ndarray::array; /// use numpy::{dot, pyarray, PyArray2, PyArrayMethods}; /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let matrix = pyarray![py, [1, 0], [0, 1]]; /// let another_matrix = pyarray![py, [4, 1], [2, 2]]; /// @@ -106,7 +106,7 @@ where /// use pyo3::Python; /// use numpy::{dot, pyarray, PyArray0}; /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let vector = pyarray![py, 1.0, 2.0, 3.0]; /// let result: f64 = dot(&vector, &vector).unwrap(); /// assert_eq!(result, 14.0); @@ -177,7 +177,7 @@ where /// use ndarray::array; /// use numpy::{einsum, pyarray, PyArray, PyArray2, PyArrayMethods}; /// -/// Python::with_gil(|py| { +/// Python::attach(|py| { /// let tensor = PyArray::arange(py, 0, 2 * 3 * 4, 1).reshape([2, 3, 4]).unwrap(); /// let another_tensor = pyarray![py, [20, 30], [40, 50], [60, 70]]; /// diff --git a/src/untyped_array.rs b/src/untyped_array.rs index 18bff76ea..df443ec6c 100644 --- a/src/untyped_array.rs +++ b/src/untyped_array.rs @@ -3,9 +3,7 @@ //! [ndarray]: https://numpy.org/doc/stable/reference/arrays.ndarray.html use std::slice; -use pyo3::{ - ffi, pyobject_native_type_named, types::PyAnyMethods, Bound, PyAny, PyTypeInfo, Python, -}; +use pyo3::{ffi, pyobject_native_type_named, Bound, PyAny, PyTypeInfo, Python}; use crate::array::{PyArray, PyArrayMethods}; use crate::cold; @@ -41,11 +39,11 @@ use crate::npyffi; /// let element_type = array.dtype(); /// /// if element_type.is_equiv_to(&dtype::(py)) { -/// let array = array.downcast::>()?; +/// let array = array.cast::>()?; /// /// implementation(array) /// } else if element_type.is_equiv_to(&dtype::(py)) { -/// let array = array.downcast::>()?; +/// let array = array.cast::>()?; /// /// implementation(array) /// } else { @@ -53,7 +51,7 @@ use crate::npyffi; /// } /// } /// # -/// # Python::with_gil(|py| { +/// # Python::attach(|py| { /// # let array = PyArray1::::zeros(py, 42, false); /// # entry_point(py, array.as_untyped()) /// # }).unwrap(); @@ -93,7 +91,7 @@ pub trait PyUntypedArrayMethods<'py>: Sealed { /// use numpy::{dtype, PyArray}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let array = PyArray::from_vec(py, vec![1_i32, 2, 3]); /// /// assert!(array.dtype().is_equiv_to(&dtype::(py))); @@ -114,13 +112,13 @@ pub trait PyUntypedArrayMethods<'py>: Sealed { /// use pyo3::{types::{IntoPyDict, PyAnyMethods}, Python, ffi::c_str}; /// /// # fn main() -> pyo3::PyResult<()> { - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let array = PyArray1::arange(py, 0, 10, 1); /// assert!(array.is_contiguous()); /// /// let view = py /// .eval(c_str!("array[::2]"), None, Some(&[("array", array)].into_py_dict(py)?))? - /// .downcast_into::>()?; + /// .cast_into::>()?; /// assert!(!view.is_contiguous()); /// # Ok(()) /// }) @@ -155,7 +153,7 @@ pub trait PyUntypedArrayMethods<'py>: Sealed { /// use numpy::{PyArray3, PyUntypedArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let arr = PyArray3::::zeros(py, [4, 5, 6], false); /// /// assert_eq!(arr.ndim(), 3); @@ -179,7 +177,7 @@ pub trait PyUntypedArrayMethods<'py>: Sealed { /// use numpy::{PyArray3, PyUntypedArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let arr = PyArray3::::zeros(py, [4, 5, 6], false); /// /// assert_eq!(arr.strides(), &[240, 48, 8]); @@ -211,7 +209,7 @@ pub trait PyUntypedArrayMethods<'py>: Sealed { /// use numpy::{PyArray3, PyUntypedArrayMethods}; /// use pyo3::Python; /// - /// Python::with_gil(|py| { + /// Python::attach(|py| { /// let arr = PyArray3::::zeros(py, [4, 5, 6], false); /// /// assert_eq!(arr.shape(), &[4, 5, 6]); @@ -264,7 +262,7 @@ impl<'py> PyUntypedArrayMethods<'py> for Bound<'py, PyUntypedArray> { fn dtype(&self) -> Bound<'py, PyArrayDescr> { unsafe { let descr_ptr = (*self.as_array_ptr()).descr; - Bound::from_borrowed_ptr(self.py(), descr_ptr.cast()).downcast_into_unchecked() + Bound::from_borrowed_ptr(self.py(), descr_ptr.cast()).cast_into_unchecked() } } } diff --git a/tests/array.rs b/tests/array.rs index af4bee1b2..4603d3097 100644 --- a/tests/array.rs +++ b/tests/array.rs @@ -28,13 +28,13 @@ fn not_contiguous_array(py: Python<'_>) -> Bound<'_, PyArray1> { Some(&get_np_locals(py)), ) .unwrap() - .downcast_into() + .cast_into() .unwrap() } #[test] fn new_c_order() { - Python::with_gil(|py| { + Python::attach(|py| { let dims = [3, 5]; let arr = PyArray::::zeros(py, dims, false); @@ -56,7 +56,7 @@ fn new_c_order() { #[test] fn new_fortran_order() { - Python::with_gil(|py| { + Python::attach(|py| { let dims = [3, 5]; let arr = PyArray::::zeros(py, dims, true); @@ -78,7 +78,7 @@ fn new_fortran_order() { #[test] fn tuple_as_dim() { - Python::with_gil(|py| { + Python::attach(|py| { let dims = (3, 5); let arr = PyArray::::zeros(py, dims, false); @@ -90,7 +90,7 @@ fn tuple_as_dim() { #[test] fn rank_zero_array_has_invalid_strides_dimensions() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = PyArray::::zeros(py, (), false); assert_eq!(arr.ndim(), 0); @@ -106,7 +106,7 @@ fn rank_zero_array_has_invalid_strides_dimensions() { #[test] fn zeros() { - Python::with_gil(|py| { + Python::attach(|py| { let dims = [3, 4]; let arr = PyArray::::zeros(py, dims, false); @@ -129,7 +129,7 @@ fn zeros() { #[test] fn arange() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = PyArray::::arange(py, 0.0, 1.0, 0.1); assert_eq!(arr.ndim(), 1); @@ -139,7 +139,7 @@ fn arange() { #[test] fn as_array() { - Python::with_gil(|py| { + Python::attach(|py| { let pyarr = PyArray::::zeros(py, [3, 2, 4], false).readonly(); let arr = pyarr.as_array(); @@ -160,7 +160,7 @@ fn as_array() { #[test] fn as_raw_array() { - Python::with_gil(|py| { + Python::attach(|py| { let not_contiguous = not_contiguous_array(py); let raw_array_view = not_contiguous.as_raw_array(); @@ -173,7 +173,7 @@ fn as_raw_array() { #[test] fn as_slice() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = PyArray::::zeros(py, [3, 2, 4], false); assert_eq!(arr.readonly().as_slice().unwrap().len(), 3 * 2 * 4); @@ -185,7 +185,7 @@ fn as_slice() { #[test] fn is_instance() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = PyArray2::::zeros(py, [3, 5], false); assert!(arr.is_instance_of::>()); @@ -195,7 +195,7 @@ fn is_instance() { #[test] fn from_vec2() { - Python::with_gil(|py| { + Python::attach(|py| { let pyarray = PyArray::from_vec2(py, &[vec![1, 2, 3], vec![4, 5, 6]]).unwrap(); assert_eq!(pyarray.readonly().as_array(), array![[1, 2, 3], [4, 5, 6]]); @@ -204,7 +204,7 @@ fn from_vec2() { #[test] fn from_vec2_ragged() { - Python::with_gil(|py| { + Python::attach(|py| { let pyarray = PyArray::from_vec2(py, &[vec![1, 2, 3], vec![4, 5]]); let err = pyarray.unwrap_err(); @@ -214,7 +214,7 @@ fn from_vec2_ragged() { #[test] fn from_vec3() { - Python::with_gil(|py| { + Python::attach(|py| { let pyarray = PyArray::from_vec3( py, &[ @@ -234,7 +234,7 @@ fn from_vec3() { #[test] fn from_vec3_ragged() { - Python::with_gil(|py| { + Python::attach(|py| { let pyarray = PyArray::from_vec3( py, &[ @@ -263,9 +263,9 @@ fn from_vec3_ragged() { #[test] fn array_cast() { - Python::with_gil(|py| { + Python::attach(|py| { let arr_f64 = pyarray![py, [1.5, 2.5, 3.5], [1.5, 2.5, 3.5]]; - let arr_i32 = arr_f64.cast::(false).unwrap(); + let arr_i32 = arr_f64.cast_array::(false).unwrap(); assert_eq!(arr_i32.readonly().as_array(), array![[1, 2, 3], [1, 2, 3]]); }); @@ -273,7 +273,7 @@ fn array_cast() { #[test] fn handle_negative_strides() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = array![[2, 3], [4, 5u32]]; let pyarr = arr.to_pyarray(py); @@ -284,7 +284,7 @@ fn handle_negative_strides() { None, ) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!( @@ -296,7 +296,7 @@ fn handle_negative_strides() { #[test] fn dtype_via_python_attribute() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = array![[2, 3], [4, 5u32]]; let pyarr = arr.to_pyarray(py); @@ -307,7 +307,7 @@ fn dtype_via_python_attribute() { None, ) .unwrap() - .downcast_into::() + .cast_into::() .unwrap(); assert!(dt.is_equiv_to(&dtype::(py))); @@ -331,7 +331,7 @@ impl Owner { #[test] fn borrow_from_array_works() { - let array = Python::with_gil(|py| { + let array = Python::attach(|py| { let owner = Py::new( py, Owner { @@ -343,47 +343,47 @@ fn borrow_from_array_works() { owner.getattr(py, "array").unwrap() }); - Python::with_gil(|py| { + Python::attach(|py| { py_run!(py, array, "assert array.shape == (10,)"); }); } #[test] -fn downcasting_works() { - Python::with_gil(|py| { +fn casting_works() { + Python::attach(|py| { let ob = PyArray::from_slice(py, &[1_i32, 2, 3]).into_any(); - assert!(ob.downcast::>().is_ok()); + assert!(ob.cast::>().is_ok()); }); } #[test] -fn downcasting_respects_element_type() { - Python::with_gil(|py| { +fn casting_respects_element_type() { + Python::attach(|py| { let ob = PyArray::from_slice(py, &[1_i32, 2, 3]).into_any(); - assert!(ob.downcast::>().is_err()); + assert!(ob.cast::>().is_err()); }); } #[test] -fn downcasting_respects_dimensionality() { - Python::with_gil(|py| { +fn casting_respects_dimensionality() { + Python::attach(|py| { let ob = PyArray::from_slice(py, &[1_i32, 2, 3]).into_any(); - assert!(ob.downcast::>().is_err()); + assert!(ob.cast::>().is_err()); }); } #[test] fn unbind_works() { - let arr: Py> = Python::with_gil(|py| { + let arr: Py> = Python::attach(|py| { let arr = PyArray::from_slice(py, &[1_i32, 2, 3]); arr.unbind() }); - Python::with_gil(|py| { + Python::attach(|py| { let arr = arr.bind(py); assert_eq!(arr.readonly().as_slice().unwrap(), &[1, 2, 3]); @@ -392,7 +392,7 @@ fn unbind_works() { #[test] fn copy_to_works() { - Python::with_gil(|py| { + Python::attach(|py| { let arr1 = PyArray::arange(py, 2.0, 5.0, 1.0); let arr2 = unsafe { PyArray::::new(py, [3], false) }; @@ -404,7 +404,7 @@ fn copy_to_works() { #[test] fn get_works() { - Python::with_gil(|py| { + Python::attach(|py| { let array = pyarray![py, [[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]]; unsafe { @@ -423,7 +423,7 @@ fn get_works() { #[test] fn permute_and_transpose() { - Python::with_gil(|py| { + Python::attach(|py| { let array = array![[0, 1, 2], [3, 4, 5]].into_pyarray(py); let permuted = array.permute(Some([1, 0])).unwrap(); @@ -456,7 +456,7 @@ fn permute_and_transpose() { #[test] fn reshape() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::from_iter(py, 0..9) .reshape_with_order([3, 3], NPY_ORDER::NPY_FORTRANORDER) .unwrap(); @@ -474,7 +474,7 @@ fn reshape() { #[cfg(feature = "half")] #[test] fn half_f16_works() { - Python::with_gil(|py| { + Python::attach(|py| { let np = py.eval(c_str!("__import__('numpy')"), None, None).unwrap(); let locals = [("np", &np)].into_py_dict(py).unwrap(); @@ -485,7 +485,7 @@ fn half_f16_works() { Some(&locals), ) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!( @@ -512,7 +512,7 @@ fn half_f16_works() { #[cfg(feature = "half")] #[test] fn half_bf16_works() { - Python::with_gil(|py| { + Python::attach(|py| { let np = py.eval(c_str!("__import__('numpy')"), None, None).unwrap(); // NumPy itself does not provide a `bfloat16` dtype itself, // so we import ml_dtypes which does register such a dtype. @@ -528,7 +528,7 @@ fn half_bf16_works() { Some(&locals), ) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!( @@ -554,7 +554,7 @@ fn half_bf16_works() { #[test] fn ascii_strings_with_explicit_dtype_works() { - Python::with_gil(|py| { + Python::attach(|py| { let np = py.eval(c_str!("__import__('numpy')"), None, None).unwrap(); let locals = [("np", &np)].into_py_dict(py).unwrap(); @@ -565,7 +565,7 @@ fn ascii_strings_with_explicit_dtype_works() { Some(&locals), ) .unwrap() - .downcast_into::>>() + .cast_into::>>() .unwrap(); { @@ -590,7 +590,7 @@ fn ascii_strings_with_explicit_dtype_works() { #[test] fn unicode_strings_with_explicit_dtype_works() { - Python::with_gil(|py| { + Python::attach(|py| { let np = py.eval(c_str!("__import__('numpy')"), None, None).unwrap(); let locals = [("np", &np)].into_py_dict(py).unwrap(); @@ -601,7 +601,7 @@ fn unicode_strings_with_explicit_dtype_works() { Some(&locals), ) .unwrap() - .downcast_into::>>() + .cast_into::>>() .unwrap(); { @@ -636,7 +636,7 @@ fn unicode_strings_with_explicit_dtype_works() { #[test] fn ascii_strings_ignore_byteorder() { - Python::with_gil(|py| { + Python::attach(|py| { let np = py.eval(c_str!("__import__('numpy')"), None, None).unwrap(); let locals = [("np", &np)].into_py_dict(py).unwrap(); @@ -647,7 +647,7 @@ fn ascii_strings_ignore_byteorder() { Some(&locals), ) .unwrap() - .downcast::>>() + .cast::>>() .is_ok(); let little_endian_works = py @@ -657,7 +657,7 @@ fn ascii_strings_ignore_byteorder() { Some(&locals), ) .unwrap() - .downcast::>>() + .cast::>>() .is_ok(); let big_endian_works = py @@ -667,7 +667,7 @@ fn ascii_strings_ignore_byteorder() { Some(&locals), ) .unwrap() - .downcast::>>() + .cast::>>() .is_ok(); match (native_endian_works, little_endian_works, big_endian_works) { @@ -679,7 +679,7 @@ fn ascii_strings_ignore_byteorder() { #[test] fn unicode_strings_respect_byteorder() { - Python::with_gil(|py| { + Python::attach(|py| { let np = py.eval(c_str!("__import__('numpy')"), None, None).unwrap(); let locals = [("np", &np)].into_py_dict(py).unwrap(); @@ -690,7 +690,7 @@ fn unicode_strings_respect_byteorder() { Some(&locals), ) .unwrap() - .downcast::>>() + .cast::>>() .is_ok(); let little_endian_works = py @@ -700,7 +700,7 @@ fn unicode_strings_respect_byteorder() { Some(&locals), ) .unwrap() - .downcast::>>() + .cast::>>() .is_ok(); let big_endian_works = py @@ -710,7 +710,7 @@ fn unicode_strings_respect_byteorder() { Some(&locals), ) .unwrap() - .downcast::>>() + .cast::>>() .is_ok(); match (native_endian_works, little_endian_works, big_endian_works) { diff --git a/tests/array_like.rs b/tests/array_like.rs index aa185b174..9a2afcfdf 100644 --- a/tests/array_like.rs +++ b/tests/array_like.rs @@ -14,7 +14,7 @@ fn get_np_locals(py: Python<'_>) -> Bound<'_, PyDict> { #[test] fn extract_reference() { - Python::with_gil(|py| { + Python::attach(|py| { let locals = get_np_locals(py); let py_array = py .eval( @@ -34,7 +34,7 @@ fn extract_reference() { #[test] fn convert_array_on_extract() { - Python::with_gil(|py| { + Python::attach(|py| { let locals = get_np_locals(py); let py_array = py .eval( @@ -56,7 +56,7 @@ fn convert_array_on_extract() { #[test] fn convert_list_on_extract() { - Python::with_gil(|py| { + Python::attach(|py| { let py_list = py .eval(c_str!("[[1.0,2.0],[3.0,4.0]]"), None, None) .unwrap(); @@ -68,7 +68,7 @@ fn convert_list_on_extract() { #[test] fn convert_array_in_list_on_extract() { - Python::with_gil(|py| { + Python::attach(|py| { let locals = get_np_locals(py); let py_array = py .eval( @@ -85,7 +85,7 @@ fn convert_array_in_list_on_extract() { #[test] fn convert_list_on_extract_dyn() { - Python::with_gil(|py| { + Python::attach(|py| { let py_list = py .eval(c_str!("[[[1,2],[3,4]],[[5,6],[7,8]]]"), None, None) .unwrap(); @@ -102,7 +102,7 @@ fn convert_list_on_extract_dyn() { #[test] fn convert_1d_list_on_extract() { - Python::with_gil(|py| { + Python::attach(|py| { let py_list = py.eval(c_str!("[1,2,3,4]"), None, None).unwrap(); let extracted_array_1d = py_list.extract::>().unwrap(); let extracted_array_dyn = py_list.extract::>().unwrap(); @@ -117,7 +117,7 @@ fn convert_1d_list_on_extract() { #[test] fn unsafe_cast_shall_fail() { - Python::with_gil(|py| { + Python::attach(|py| { let locals = get_np_locals(py); let py_list = py .eval( @@ -134,7 +134,7 @@ fn unsafe_cast_shall_fail() { #[test] fn unsafe_cast_with_coerce_works() { - Python::with_gil(|py| { + Python::attach(|py| { let locals = get_np_locals(py); let py_list = py .eval( diff --git a/tests/borrow.rs b/tests/borrow.rs index 2cf38bb84..49bf59d61 100644 --- a/tests/borrow.rs +++ b/tests/borrow.rs @@ -13,7 +13,7 @@ use pyo3::{ #[test] fn distinct_borrows() { - Python::with_gil(|py| { + Python::attach(|py| { let array1 = PyArray::::zeros(py, (1, 2, 3), false); let array2 = PyArray::::zeros(py, (1, 2, 3), false); @@ -27,7 +27,7 @@ fn distinct_borrows() { #[test] fn multiple_shared_borrows() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let shared1 = array.readonly(); @@ -41,7 +41,7 @@ fn multiple_shared_borrows() { #[test] #[should_panic(expected = "AlreadyBorrowed")] fn exclusive_and_shared_borrows() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let _exclusive = array.readwrite(); @@ -52,7 +52,7 @@ fn exclusive_and_shared_borrows() { #[test] #[should_panic(expected = "AlreadyBorrowed")] fn shared_and_exclusive_borrows() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let _shared = array.readonly(); @@ -62,7 +62,7 @@ fn shared_and_exclusive_borrows() { #[test] fn multiple_exclusive_borrows() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let _exclusive = array.try_readwrite().unwrap(); @@ -74,7 +74,7 @@ fn multiple_exclusive_borrows() { #[test] fn exclusive_borrow_requires_writeable() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); unsafe { @@ -99,7 +99,7 @@ impl Borrower { #[test] #[should_panic(expected = "AlreadyBorrowed")] fn borrows_span_frames() { - Python::with_gil(|py| { + Python::attach(|py| { let borrower = Py::new(py, Borrower).unwrap(); let array = PyArray::::zeros(py, (1, 2, 3), false); @@ -112,16 +112,16 @@ fn borrows_span_frames() { #[test] fn borrows_span_threads() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let _exclusive = array.readwrite(); let array = array.unbind(); - py.allow_threads(move || { + py.detach(move || { let thread = spawn(move || { - Python::with_gil(|py| { + Python::attach(|py| { let array = array.bind(py); let _exclusive = array.readwrite(); @@ -135,7 +135,7 @@ fn borrows_span_threads() { #[test] fn shared_borrows_can_be_cloned() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let shared1 = array.readonly(); @@ -149,21 +149,21 @@ fn shared_borrows_can_be_cloned() { #[test] #[should_panic(expected = "AlreadyBorrowed")] fn overlapping_views_conflict() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let locals = [("array", array)].into_py_dict(py).unwrap(); let view1 = py .eval(c_str!("array[0,0,0:2]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view1.shape(), [2]); let view2 = py .eval(c_str!("array[0,0,1:3]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view2.shape(), [2]); @@ -174,21 +174,21 @@ fn overlapping_views_conflict() { #[test] fn non_overlapping_views_do_not_conflict() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let locals = [("array", array)].into_py_dict(py).unwrap(); let view1 = py .eval(c_str!("array[0,0,0:1]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view1.shape(), [1]); let view2 = py .eval(c_str!("array[0,0,2:3]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view2.shape(), [1]); @@ -203,21 +203,21 @@ fn non_overlapping_views_do_not_conflict() { #[test] #[should_panic(expected = "AlreadyBorrowed")] fn conflict_due_to_overlapping_views() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, 3, false); let locals = [("array", array)].into_py_dict(py).unwrap(); let view1 = py .eval(c_str!("array[0:2]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view1.shape(), [2]); let view2 = py .eval(c_str!("array[1:3]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view2.shape(), [2]); @@ -229,21 +229,21 @@ fn conflict_due_to_overlapping_views() { #[test] #[should_panic(expected = "AlreadyBorrowed")] fn conflict_due_to_reborrow_of_overlapping_views() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, 3, false); let locals = [("array", array)].into_py_dict(py).unwrap(); let view1 = py .eval(c_str!("array[0:2]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view1.shape(), [2]); let view2 = py .eval(c_str!("array[1:3]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view2.shape(), [2]); @@ -257,28 +257,28 @@ fn conflict_due_to_reborrow_of_overlapping_views() { #[test] fn interleaved_views_do_not_conflict() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (23, 42, 3), false); let locals = [("array", array)].into_py_dict(py).unwrap(); let view1 = py .eval(c_str!("array[:,:,0]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view1.shape(), [23, 42]); let view2 = py .eval(c_str!("array[:,:,1]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view2.shape(), [23, 42]); let view3 = py .eval(c_str!("array[:,:,2]"), None, Some(&locals)) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); assert_eq!(view2.shape(), [23, 42]); @@ -294,7 +294,7 @@ fn interleaved_views_do_not_conflict() { #[test] fn extract_readonly() { - Python::with_gil(|py| { + Python::attach(|py| { let ob = PyArray::::zeros(py, (1, 2, 3), false).into_any(); ob.extract::>().unwrap(); }); @@ -302,7 +302,7 @@ fn extract_readonly() { #[test] fn extract_readwrite() { - Python::with_gil(|py| { + Python::attach(|py| { let ob = PyArray::::zeros(py, (1, 2, 3), false).into_any(); ob.extract::>().unwrap(); }); @@ -310,7 +310,7 @@ fn extract_readwrite() { #[test] fn readonly_as_array_slice_get() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let array = array.readonly(); @@ -322,7 +322,7 @@ fn readonly_as_array_slice_get() { #[test] fn readwrite_as_array_slice() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (1, 2, 3), false); let mut array = array.readwrite(); @@ -337,7 +337,7 @@ fn readwrite_as_array_slice() { #[test] fn resize_using_exclusive_borrow() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, 3, false); assert_eq!(array.shape(), [3]); @@ -351,7 +351,7 @@ fn resize_using_exclusive_borrow() { #[test] fn can_make_python_array_nonwriteable() { - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray1::::zeros(py, 10, false); let locals = [("array", &array)].into_py_dict(py).unwrap(); array.readwrite().make_nonwriteable(); @@ -370,7 +370,7 @@ fn can_make_python_array_nonwriteable() { #[cfg(feature = "nalgebra")] #[test] fn matrix_from_numpy() { - Python::with_gil(|py| { + Python::attach(|py| { let array = numpy::pyarray![py, [0, 1, 2], [3, 4, 5], [6, 7, 8]]; { @@ -408,7 +408,7 @@ fn matrix_from_numpy() { } }); - Python::with_gil(|py| { + Python::attach(|py| { let array = numpy::pyarray![py, 0, 1, 2]; { @@ -434,7 +434,7 @@ fn matrix_from_numpy() { } }); - Python::with_gil(|py| { + Python::attach(|py| { let array = PyArray::::zeros(py, (2, 2, 2), false); let array = array.readonly(); @@ -443,7 +443,7 @@ fn matrix_from_numpy() { assert!(matrix.is_none()); }); - Python::with_gil(|py| { + Python::attach(|py| { let array = numpy::pyarray![py, [0, 1, 2], [3, 4, 5], [6, 7, 8]]; let array = py .eval( @@ -452,7 +452,7 @@ fn matrix_from_numpy() { None, ) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let array = array.readonly(); @@ -461,7 +461,7 @@ fn matrix_from_numpy() { assert!(matrix.is_none()); }); - Python::with_gil(|py| { + Python::attach(|py| { let array = numpy::pyarray![py, [[0, 1], [2, 3]], [[4, 5], [6, 7]]]; let array = py .eval( @@ -470,7 +470,7 @@ fn matrix_from_numpy() { None, ) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let array = array.readonly(); @@ -485,7 +485,7 @@ fn matrix_from_numpy() { assert_eq!(matrix, nalgebra::Matrix2::new(0, 2, 4, 6)); }); - Python::with_gil(|py| { + Python::attach(|py| { let array = numpy::pyarray![py, [[0, 1], [2, 3]], [[4, 5], [6, 7]]]; let array = py .eval( @@ -494,7 +494,7 @@ fn matrix_from_numpy() { None, ) .unwrap() - .downcast_into::>() + .cast_into::>() .unwrap(); let array = array.readonly(); @@ -509,7 +509,7 @@ fn matrix_from_numpy() { assert_eq!(matrix, nalgebra::Matrix2::new(0, 2, 4, 6)); }); - Python::with_gil(|py| { + Python::attach(|py| { let array = numpy::pyarray![py, [0, 1, 2], [3, 4, 5], [6, 7, 8]]; let array = array.readonly(); diff --git a/tests/sum_products.rs b/tests/sum_products.rs index 05dfca14a..93c79717a 100644 --- a/tests/sum_products.rs +++ b/tests/sum_products.rs @@ -4,7 +4,7 @@ use pyo3::{Bound, Python}; #[test] fn test_dot() { - Python::with_gil(|py| { + Python::attach(|py| { let a = pyarray![py, [1, 0], [0, 1]]; let b = pyarray![py, [4, 1], [2, 2]]; let c: Bound<'_, PyArray2<_>> = dot(&a, &b).unwrap(); @@ -30,7 +30,7 @@ fn test_dot() { #[test] fn test_inner() { - Python::with_gil(|py| { + Python::attach(|py| { let a = pyarray![py, 1, 2, 3]; let b = pyarray![py, 0, 1, 0]; let c: Bound<'_, PyArray0<_>> = inner(&a, &b).unwrap(); @@ -56,7 +56,7 @@ fn test_inner() { #[test] fn test_einsum() { - Python::with_gil(|py| { + Python::attach(|py| { let a = PyArray1::::arange(py, 0, 25, 1) .reshape([5, 5]) .unwrap(); diff --git a/tests/to_py.rs b/tests/to_py.rs index c18d2d6db..89fdf1195 100644 --- a/tests/to_py.rs +++ b/tests/to_py.rs @@ -11,7 +11,7 @@ use pyo3::{ #[test] fn to_pyarray_vec() { - Python::with_gil(|py| { + Python::attach(|py| { #[allow(clippy::useless_vec)] let arr = vec![1, 2, 3].to_pyarray(py); @@ -22,7 +22,7 @@ fn to_pyarray_vec() { #[test] fn to_pyarray_boxed_slice() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = vec![1, 2, 3].into_boxed_slice().to_pyarray(py); assert_eq!(arr.shape(), [3]); @@ -32,7 +32,7 @@ fn to_pyarray_boxed_slice() { #[test] fn to_pyarray_array() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = Array3::::zeros((3, 4, 2)); let shape = arr.shape().to_vec(); @@ -51,7 +51,7 @@ fn to_pyarray_array() { #[test] fn iter_to_pyarray() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = PyArray::from_iter(py, (0..10).map(|x| x * x)); assert_eq!( @@ -63,7 +63,7 @@ fn iter_to_pyarray() { #[test] fn long_iter_to_pyarray() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = PyArray::from_iter(py, 0_u32..512); assert_eq!( @@ -78,7 +78,7 @@ fn from_small_array() { macro_rules! small_array_test { ($($t:ty)+) => { $({ - Python::with_gil(|py| { + Python::attach(|py| { let array: [$t; 2] = [<$t>::MIN, <$t>::MAX]; let pyarray = array.to_pyarray(py); @@ -96,7 +96,7 @@ fn from_small_array() { #[test] fn usize_dtype() { - Python::with_gil(|py| { + Python::attach(|py| { let x = vec![1_usize, 2, 3].into_pyarray(py); if cfg!(target_pointer_width = "64") { @@ -109,7 +109,7 @@ fn usize_dtype() { #[test] fn into_pyarray_vec() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = vec![1, 2, 3].into_pyarray(py); assert_eq!(arr.readonly().as_slice().unwrap(), &[1, 2, 3]) @@ -118,7 +118,7 @@ fn into_pyarray_vec() { #[test] fn into_pyarray_boxed_slice() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = vec![1, 2, 3].into_boxed_slice().into_pyarray(py); assert_eq!(arr.readonly().as_slice().unwrap(), &[1, 2, 3]) @@ -127,7 +127,7 @@ fn into_pyarray_boxed_slice() { #[test] fn into_pyarray_array() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = Array3::::zeros((3, 4, 2)); let shape = arr.shape().to_vec(); @@ -146,7 +146,7 @@ fn into_pyarray_array() { #[test] fn into_pyarray_cannot_resize() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = vec![1, 2, 3].into_pyarray(py); unsafe { @@ -157,7 +157,7 @@ fn into_pyarray_cannot_resize() { #[test] fn into_pyarray_can_write() { - Python::with_gil(|py| { + Python::attach(|py| { let arr = vec![1, 2, 3].into_pyarray(py); py_run!(py, arr, "assert arr.flags['WRITEABLE']"); @@ -170,7 +170,7 @@ fn collapsed_into_pyarray() { // Check that `into_pyarray` works for array with the pointer of the first element is // not at the start of the allocation. // See https://github.com/PyO3/rust-numpy/issues/182 for more. - Python::with_gil(|py| { + Python::attach(|py| { let mut arr = Array2::::from_shape_fn([3, 4], |(i, j)| (i * 10 + j) as f64); arr.slice_collapse(s![1.., ..]); let cloned_arr = arr.clone(); @@ -183,7 +183,7 @@ fn collapsed_into_pyarray() { #[test] fn sliced_to_pyarray() { - Python::with_gil(|py| { + Python::attach(|py| { let matrix = Array2::from_shape_vec([4, 2], vec![0, 1, 2, 3, 4, 5, 6, 7]).unwrap(); let sliced_matrix = matrix.slice(s![1..4; -1, ..]); @@ -197,7 +197,7 @@ fn sliced_to_pyarray() { #[test] fn forder_to_pyarray() { - Python::with_gil(|py| { + Python::attach(|py| { let matrix = Array2::from_shape_vec([4, 2], vec![0, 1, 2, 3, 4, 5, 6, 7]).unwrap(); let forder_matrix = matrix.reversed_axes(); @@ -214,7 +214,7 @@ fn forder_to_pyarray() { #[test] fn forder_into_pyarray() { - Python::with_gil(|py| { + Python::attach(|py| { let matrix = Array2::from_shape_vec([4, 2], vec![0, 1, 2, 3, 4, 5, 6, 7]).unwrap(); let forder_matrix = matrix.reversed_axes(); @@ -231,7 +231,7 @@ fn forder_into_pyarray() { #[test] fn to_pyarray_object_vec() { - Python::with_gil(|py| { + Python::attach(|py| { let dict = PyDict::new(py); let string = PyString::new(py, "Hello:)"); #[allow(clippy::useless_vec)] // otherwise we do not test the right trait impl @@ -250,7 +250,7 @@ fn to_pyarray_object_vec() { #[test] fn to_pyarray_object_array() { - Python::with_gil(|py| { + Python::attach(|py| { let mut nd_arr = Array2::from_shape_fn((2, 3), |(_, _)| py.None()); nd_arr[(0, 2)] = PyDict::new(py).into_any().unbind(); nd_arr[(1, 0)] = PyString::new(py, "Hello:)").into_any().unbind(); @@ -273,7 +273,7 @@ fn to_pyarray_object_array() { #[test] fn slice_container_type_confusion() { - Python::with_gil(|py| { + Python::attach(|py| { let mut nd_arr = Array2::from_shape_fn((2, 3), |(_, _)| py.None()); nd_arr[(0, 2)] = PyDict::new(py).into_any().unbind(); nd_arr[(1, 0)] = PyString::new(py, "Hello:)").into_any().unbind(); @@ -294,7 +294,7 @@ fn matrix_to_numpy() { let matrix = nalgebra::Matrix3::::new(0, 1, 2, 3, 4, 5, 6, 7, 8); assert!(nalgebra::RawStorage::is_contiguous(&matrix.data)); - Python::with_gil(|py| { + Python::attach(|py| { let array = matrix.to_pyarray(py); assert_eq!( @@ -306,7 +306,7 @@ fn matrix_to_numpy() { let matrix = matrix.row(0); assert!(!nalgebra::RawStorage::is_contiguous(&matrix.data)); - Python::with_gil(|py| { + Python::attach(|py| { let array = matrix.to_pyarray(py); assert_eq!(array.readonly().as_array(), array![[0, 1, 2]]); @@ -314,7 +314,7 @@ fn matrix_to_numpy() { let vector = nalgebra::Vector4::::new(-4, 1, 2, 3); - Python::with_gil(|py| { + Python::attach(|py| { let array = vector.to_pyarray(py); assert_eq!(array.readonly().as_array(), array![[-4], [1], [2], [3]]); @@ -322,7 +322,7 @@ fn matrix_to_numpy() { let vector = nalgebra::RowVector2::::new(23, 42); - Python::with_gil(|py| { + Python::attach(|py| { let array = vector.to_pyarray(py); assert_eq!(array.readonly().as_array(), array![[23, 42]]);