diff --git a/examples/decorator/src/lib.rs b/examples/decorator/src/lib.rs index bc369c62b1e..3d96f145421 100644 --- a/examples/decorator/src/lib.rs +++ b/examples/decorator/src/lib.rs @@ -13,7 +13,7 @@ pub struct PyCounter { count: Cell, // This is the actual function being wrapped. - wraps: Py, + wraps: PyDetached, } #[pymethods] @@ -24,7 +24,7 @@ impl PyCounter { // 1. It doesn't guarantee the object can actually be called successfully // 2. We still need to handle any exceptions that the function might raise #[new] - fn __new__(wraps: Py) -> Self { + fn __new__(wraps: PyDetached) -> Self { PyCounter { count: Cell::new(0), wraps, @@ -42,7 +42,7 @@ impl PyCounter { py: Python<'_>, args: &PyTuple, kwargs: Option<&PyDict>, - ) -> PyResult> { + ) -> PyResult> { let old_count = self.count.get(); let new_count = old_count + 1; self.count.set(new_count); diff --git a/guide/src/class.md b/guide/src/class.md index e3f3502780b..c39ded1151e 100644 --- a/guide/src/class.md +++ b/guide/src/class.md @@ -63,7 +63,7 @@ Rust lifetimes are used by the Rust compiler to reason about a program's memory As soon as Rust data is exposed to Python, there is no guarantee that the Rust compiler can make on how long the data will live. Python is a reference-counted language and those references can be held for an arbitrarily long time which is untraceable by the Rust compiler. The only possible way to express this correctly is to require that any `#[pyclass]` does not borrow data for any lifetime shorter than the `'static` lifetime, i.e. the `#[pyclass]` cannot have any lifetime parameters. -When you need to share ownership of data between Python and Rust, instead of using borrowed references with lifetimes consider using reference-counted smart pointers such as [`Arc`] or [`Py`]. +When you need to share ownership of data between Python and Rust, instead of using borrowed references with lifetimes consider using reference-counted smart pointers such as [`Arc`] or [`PyDetached`]. #### No generic parameters @@ -115,7 +115,7 @@ impl Nonzero { ``` If you want to return an existing object (for example, because your `new` -method caches the values it returns), `new` can return `pyo3::Py`. +method caches the values it returns), `new` can return `pyo3::PyDetached`. As you can see, the Rust method name is not important here; this way you can still, use `new()` for a Rust-level constructor. @@ -202,14 +202,14 @@ struct MyClass { num: i32, } -fn return_myclass() -> Py { - Python::with_gil(|py| Py::new(py, MyClass { num: 1 }).unwrap()) +fn return_myclass() -> PyDetached { + Python::with_gil(|py| PyDetached::new(py, MyClass { num: 1 }).unwrap()) } let obj = return_myclass(); Python::with_gil(|py| { - let cell = obj.as_ref(py); // Py::as_ref returns &PyCell + let cell = obj.as_ref(py); // PyDetached::as_ref returns &PyCell let obj_ref = cell.borrow(); // Get PyRef assert_eq!(obj_ref.num, 1); }); @@ -230,12 +230,12 @@ struct FrozenCounter { value: AtomicUsize, } -let py_counter: Py = Python::with_gil(|py| { +let py_counter: PyDetached = Python::with_gil(|py| { let counter = FrozenCounter { value: AtomicUsize::new(0), }; - Py::new(py, counter).unwrap() + PyDetached::new(py, counter).unwrap() }); py_counter.get().value.fetch_add(1, Ordering::Relaxed); @@ -343,10 +343,10 @@ impl SubSubClass { let base = PyClassInitializer::from(BaseClass::new()); let sub = base.add_subclass(SubClass { val2: val }); if val % 2 == 0 { - Ok(Py::new(py, sub)?.to_object(py)) + Ok(PyDetached::new(py, sub)?.to_object(py)) } else { let sub_sub = sub.add_subclass(SubSubClass { val3: val }); - Ok(Py::new(py, sub_sub)?.to_object(py)) + Ok(PyDetached::new(py, sub_sub)?.to_object(py)) } } } @@ -778,7 +778,7 @@ fn increment_then_print_field(my_class: &PyCell) { // Take a GIL-indepedent reference when you want to store the reference elsewhere. #[pyfunction] -fn print_refcnt(my_class: Py, py: Python<'_>) { +fn print_refcnt(my_class: PyDetached, py: Python<'_>) { println!("{}", my_class.get_refcnt(py)); } ``` @@ -971,8 +971,8 @@ enum MyEnum { } Python::with_gil(|py| { - let x = Py::new(py, MyEnum::Variant).unwrap(); - let y = Py::new(py, MyEnum::OtherVariant).unwrap(); + let x = PyDetached::new(py, MyEnum::Variant).unwrap(); + let y = PyDetached::new(py, MyEnum::OtherVariant).unwrap(); let cls = py.get_type::(); pyo3::py_run!(py, x y cls, r#" assert x == cls.Variant @@ -1016,7 +1016,7 @@ enum MyEnum{ Python::with_gil(|py| { let cls = py.get_type::(); - let x = Py::new(py, MyEnum::Variant).unwrap(); + let x = PyDetached::new(py, MyEnum::Variant).unwrap(); pyo3::py_run!(py, cls x, r#" assert repr(x) == 'MyEnum.Variant' assert repr(cls.OtherVariant) == 'MyEnum.OtherVariant' @@ -1057,7 +1057,7 @@ enum MyEnum { } Python::with_gil(|py| { - let x = Py::new(py, MyEnum::Variant).unwrap(); + let x = PyDetached::new(py, MyEnum::Variant).unwrap(); let cls = py.get_type::(); pyo3::py_run!(py, x cls, r#" assert repr(x) == 'RenamedEnum.UPPERCASE' @@ -1148,7 +1148,7 @@ impl<'a, 'py> pyo3::impl_::extract_argument::PyFunctionArgument<'a, 'py> for &'a impl pyo3::IntoPy for MyClass { fn into_py(self, py: pyo3::Python<'_>) -> pyo3::PyObject { - pyo3::IntoPy::into_py(pyo3::Py::new(py, self).unwrap(), py) + pyo3::IntoPy::into_py(pyo3::PyDetached::new(py, self).unwrap(), py) } } @@ -1196,7 +1196,7 @@ impl pyo3::impl_::pyclass::PyClassImpl for MyClass { [`GILGuard`]: {{#PYO3_DOCS_URL}}/pyo3/struct.GILGuard.html [`PyTypeInfo`]: {{#PYO3_DOCS_URL}}/pyo3/type_object/trait.PyTypeInfo.html -[`Py`]: {{#PYO3_DOCS_URL}}/pyo3/struct.Py.html +[`PyDetached`]: {{#PYO3_DOCS_URL}}/pyo3/struct.PyDetached.html [`PyCell`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyCell.html [`PyClass`]: {{#PYO3_DOCS_URL}}/pyo3/pyclass/trait.PyClass.html [`PyRef`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html diff --git a/guide/src/class/call.md b/guide/src/class/call.md index 3b20986239b..2a5bb796763 100644 --- a/guide/src/class/call.md +++ b/guide/src/class/call.md @@ -77,7 +77,7 @@ fn __call__( py: Python<'_>, args: &PyTuple, kwargs: Option<&PyDict>, -) -> PyResult> { +) -> PyResult> { self.count += 1; let name = self.wraps.getattr(py, "__name__")?; diff --git a/guide/src/class/object.md b/guide/src/class/object.md index c6bf04834fe..a14ef902791 100644 --- a/guide/src/class/object.md +++ b/guide/src/class/object.md @@ -143,7 +143,7 @@ impl Number { > #[pymethods] > impl NotHashable { > #[classattr] -> const __hash__: Option> = None; +> const __hash__: Option> = None; > } > ``` diff --git a/guide/src/class/protocols.md b/guide/src/class/protocols.md index 4577a5102b6..fd42d998a2d 100644 --- a/guide/src/class/protocols.md +++ b/guide/src/class/protocols.md @@ -197,11 +197,11 @@ struct Container { #[pymethods] impl Container { - fn __iter__(slf: PyRef<'_, Self>) -> PyResult> { + fn __iter__(slf: PyRef<'_, Self>) -> PyResult> { let iter = Iter { inner: slf.iter.clone().into_iter(), }; - Py::new(slf.py(), iter) + PyDetached::new(slf.py(), iter) } } diff --git a/guide/src/faq.md b/guide/src/faq.md index 8308acc64de..5859f67bfc4 100644 --- a/guide/src/faq.md +++ b/guide/src/faq.md @@ -131,7 +131,7 @@ struct Inner {/* fields omitted */} #[pyclass] struct Outer { #[pyo3(get)] - inner: Py, + inner: PyDetached, } #[pymethods] @@ -139,7 +139,7 @@ impl Outer { #[new] fn __new__(py: Python<'_>) -> PyResult { Ok(Self { - inner: Py::new(py, Inner {})?, + inner: PyDetached::new(py, Inner {})?, }) } } @@ -183,7 +183,7 @@ struct MyClass; ## I'm trying to call Python from Rust but I get `STATUS_DLL_NOT_FOUND` or `STATUS_ENTRYPOINT_NOT_FOUND`! -This happens on Windows when linking to the python DLL fails or the wrong one is linked. The Python DLL on Windows will usually be called something like: +This happens on Windows when linking to the python DLL fails or the wrong one is linked. The Python DLL on Windows will usually be called something like: - `python3X.dll` for Python 3.X, e.g. `python310.dll` for Python 3.10 - `python3.dll` when using PyO3's `abi3` feature diff --git a/guide/src/features.md b/guide/src/features.md index 8ed2a2ed0bc..f87fc917f4a 100644 --- a/guide/src/features.md +++ b/guide/src/features.md @@ -159,7 +159,7 @@ struct Permission { #[derive(Serialize, Deserialize)] struct User { username: String, - permissions: Vec>, + permissions: Vec>, } # } ``` diff --git a/guide/src/memory.md b/guide/src/memory.md index f9201e3f003..d132b3807de 100644 --- a/guide/src/memory.md +++ b/guide/src/memory.md @@ -144,7 +144,7 @@ reference count reaches zero? It depends whether or not we are holding the GIL. # use pyo3::types::PyString; # fn main() -> PyResult<()> { Python::with_gil(|py| -> PyResult<()> { - let hello: Py = py.eval("\"Hello World!\"", None, None)?.extract()?; + let hello: PyDetached = py.eval("\"Hello World!\"", None, None)?.extract()?; println!("Python says: {}", hello.as_ref(py)); Ok(()) })?; @@ -165,7 +165,7 @@ we are *not* holding the GIL? # use pyo3::prelude::*; # use pyo3::types::PyString; # fn main() -> PyResult<()> { -let hello: Py = Python::with_gil(|py| { +let hello: PyDetached = Python::with_gil(|py| { py.eval("\"Hello World!\"", None, None)?.extract() })?; // Do some stuff... @@ -196,7 +196,7 @@ We can avoid the delay in releasing memory if we are careful to drop the # use pyo3::prelude::*; # use pyo3::types::PyString; # fn main() -> PyResult<()> { -let hello: Py = +let hello: PyDetached = Python::with_gil(|py| py.eval("\"Hello World!\"", None, None)?.extract())?; // Do some stuff... // Now sometime later in the program: @@ -218,7 +218,7 @@ until the GIL is dropped. # use pyo3::prelude::*; # use pyo3::types::PyString; # fn main() -> PyResult<()> { -let hello: Py = +let hello: PyDetached = Python::with_gil(|py| py.eval("\"Hello World!\"", None, None)?.extract())?; // Do some stuff... // Now sometime later in the program: diff --git a/guide/src/migration.md b/guide/src/migration.md index 4538f799877..40e6db4cc90 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -288,7 +288,7 @@ drop(second); The replacement is [`Python::with_gil`]() which is more cumbersome but enforces the proper nesting by design, e.g. -```rust +```rust,ignore # #![allow(dead_code)] # use pyo3::prelude::*; @@ -464,7 +464,7 @@ Python::with_gil(|py| { After, some type annotations may be necessary: -```rust +```rust,ignore # use pyo3::prelude::*; # # fn main() { @@ -579,7 +579,7 @@ impl MyClass { ### Removed `PartialEq` for object wrappers -The Python object wrappers `Py` and `PyAny` had implementations of `PartialEq` +The Python object wrappers `PyDetached` and `PyAny` had implementations of `PartialEq` so that `object_a == object_b` would compare the Python objects for pointer equality, which corresponds to the `is` operator, not the `==` operator in Python. This has been removed in favor of a new method: use @@ -921,7 +921,7 @@ let list_ref: &PyList = list_py.as_ref(py); ``` After: -```rust +```rust,ignore use pyo3::{Py, types::PyList}; # pyo3::Python::with_gil(|py| { let list_py: Py = PyList::empty(py).into(); diff --git a/guide/src/performance.md b/guide/src/performance.md index 23fb59c4e90..6326eb57e45 100644 --- a/guide/src/performance.md +++ b/guide/src/performance.md @@ -64,7 +64,7 @@ For example, instead of writing # use pyo3::prelude::*; # use pyo3::types::PyList; -struct Foo(Py); +struct Foo(PyDetached); struct FooRef<'a>(&'a PyList); @@ -81,7 +81,7 @@ use more efficient # #![allow(dead_code)] # use pyo3::prelude::*; # use pyo3::types::PyList; -# struct Foo(Py); +# struct Foo(PyDetached); # struct FooRef<'a>(&'a PyList); # impl PartialEq for FooRef<'_> { diff --git a/guide/src/python_from_rust.md b/guide/src/python_from_rust.md index ed51b772d2d..b53dd8c9237 100644 --- a/guide/src/python_from_rust.md +++ b/guide/src/python_from_rust.md @@ -32,7 +32,7 @@ fn main() -> PyResult<()> { let arg3 = "arg3"; Python::with_gil(|py| { - let fun: Py = PyModule::from_code( + let fun: PyDetached = PyModule::from_code( py, "def example(*args, **kwargs): if args != (): @@ -78,7 +78,7 @@ fn main() -> PyResult<()> { let val2 = 2; Python::with_gil(|py| { - let fun: Py = PyModule::from_code( + let fun: PyDetached = PyModule::from_code( py, "def example(*args, **kwargs): if args != (): @@ -372,9 +372,9 @@ fn main() -> PyResult<()> { "/python_app/utils/foo.py" )); let py_app = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/python_app/app.py")); - let from_python = Python::with_gil(|py| -> PyResult> { + let from_python = Python::with_gil(|py| -> PyResult> { PyModule::from_code(py, py_foo, "utils.foo", "utils.foo")?; - let app: Py = PyModule::from_code(py, py_app, "", "")? + let app: PyDetached = PyModule::from_code(py, py_app, "", "")? .getattr("run")? .into(); app.call0(py) @@ -405,10 +405,10 @@ use std::path::Path; fn main() -> PyResult<()> { let path = Path::new("/usr/share/python_app"); let py_app = fs::read_to_string(path.join("app.py"))?; - let from_python = Python::with_gil(|py| -> PyResult> { + let from_python = Python::with_gil(|py| -> PyResult> { let syspath: &PyList = py.import("sys")?.getattr("path")?.downcast()?; syspath.insert(0, &path)?; - let app: Py = PyModule::from_code(py, &py_app, "", "")? + let app: PyDetached = PyModule::from_code(py, &py_app, "", "")? .getattr("run")? .into(); app.call0(py) diff --git a/guide/src/trait_bounds.md b/guide/src/trait_bounds.md index 7d6e6ea44a4..857eaa7f692 100644 --- a/guide/src/trait_bounds.md +++ b/guide/src/trait_bounds.md @@ -73,7 +73,7 @@ use pyo3::prelude::*; # } struct UserModel { - model: Py, + model: PyDetached, } impl Model for UserModel { @@ -127,7 +127,7 @@ Let's add the PyO3 annotations and add a constructor: #[pyclass] struct UserModel { - model: Py, + model: PyDetached, } #[pymodule] @@ -139,7 +139,7 @@ fn trait_exposure(_py: Python<'_>, m: &PyModule) -> PyResult<()> { #[pymethods] impl UserModel { #[new] - pub fn new(model: Py) -> Self { + pub fn new(model: PyDetached) -> Self { UserModel { model } } } @@ -172,7 +172,7 @@ This wrapper will also perform the type conversions between Python and Rust. # # #[pyclass] # struct UserModel { -# model: Py, +# model: PyDetached, # } # # impl Model for UserModel { @@ -316,7 +316,7 @@ class Model: This call results in the following panic: ```block -pyo3_runtime.PanicException: called `Result::unwrap()` on an `Err` value: PyErr { type: Py(0x10dcf79f0, PhantomData) } +pyo3_runtime.PanicException: called `Result::unwrap()` on an `Err` value: PyErr { type: PyDetached(0x10dcf79f0, PhantomData) } ``` This error code is not helpful for a Python user that does not know anything about Rust, or someone that does not know PyO3 was used to interface the Rust code. @@ -340,7 +340,7 @@ We used in our `get_results` method the following call that performs the type co # # #[pyclass] # struct UserModel { -# model: Py, +# model: PyDetached, # } impl Model for UserModel { @@ -392,7 +392,7 @@ Let's break it down in order to perform better error handling: # # #[pyclass] # struct UserModel { -# model: Py, +# model: PyDetached, # } impl Model for UserModel { @@ -480,7 +480,7 @@ pub fn solve_wrapper(model: &mut UserModel) { #[pyclass] pub struct UserModel { - model: Py, + model: PyDetached, } #[pymodule] @@ -493,7 +493,7 @@ fn trait_exposure(_py: Python<'_>, m: &PyModule) -> PyResult<()> { #[pymethods] impl UserModel { #[new] - pub fn new(model: Py) -> Self { + pub fn new(model: PyDetached) -> Self { UserModel { model } } diff --git a/guide/src/types.md b/guide/src/types.md index 8bbc48d3aa4..9b5b2ca1bd8 100644 --- a/guide/src/types.md +++ b/guide/src/types.md @@ -76,11 +76,11 @@ let obj: &PyAny = PyList::empty(py); // To &PyList with PyAny::downcast let _: &PyList = obj.downcast()?; -// To Py (aka PyObject) with .into() -let _: Py = obj.into(); +// To PyDetached (aka PyObject) with .into() +let _: PyDetached = obj.into(); -// To Py with PyAny::extract -let _: Py = obj.extract()?; +// To PyDetached with PyAny::extract +let _: PyDetached = obj.extract()?; # Ok(()) # }).unwrap(); ``` @@ -91,16 +91,16 @@ For a `&PyAny` object reference `any` where the underlying object is a `#[pyclas # use pyo3::prelude::*; # #[pyclass] #[derive(Clone)] struct MyClass { } # Python::with_gil(|py| -> PyResult<()> { -let obj: &PyAny = Py::new(py, MyClass {})?.into_ref(py); +let obj: &PyAny = PyDetached::new(py, MyClass {})?.into_ref(py); // To &PyCell with PyAny::downcast let _: &PyCell = obj.downcast()?; -// To Py (aka PyObject) with .into() -let _: Py = obj.into(); +// To PyDetached (aka PyObject) with .into() +let _: PyDetached = obj.into(); -// To Py with PyAny::extract -let _: Py = obj.extract()?; +// To PyDetached with PyAny::extract +let _: PyDetached = obj.extract()?; // To MyClass with PyAny::extract, if MyClass: Clone let _: MyClass = obj.extract()?; @@ -144,8 +144,8 @@ let _: &PyAny = list; // To &PyAny explicitly with .as_ref() let _: &PyAny = list.as_ref(); -// To Py with .into() or Py::from() -let _: Py = list.into(); +// To PyDetached with .into() or PyDetached::from() +let _: PyDetached = list.into(); // To PyObject with .into() or .to_object(py) let _: PyObject = list.into(); @@ -173,18 +173,18 @@ For a `Py`, the conversions are as below: # use pyo3::prelude::*; # use pyo3::types::PyList; # Python::with_gil(|py| { -let list: Py = PyList::empty(py).into(); +let list: PyDetached = PyList::empty(py).into(); -// To &PyList with Py::as_ref() (borrows from the Py) +// To &PyList with PyDetached::as_ref() (borrows from the Py) let _: &PyList = list.as_ref(py); # let list_clone = list.clone(); // Because `.into_ref()` will consume `list`. -// To &PyList with Py::into_ref() (moves the pointer into PyO3's object storage) +// To &PyList with PyDetached::into_ref() (moves the pointer into PyO3's object storage) let _: &PyList = list.into_ref(py); # let list = list_clone; -// To Py (aka PyObject) with .into() -let _: Py = list.into(); +// To PyDetached (aka PyObject) with .into() +let _: PyDetached = list.into(); # }) ``` @@ -195,24 +195,24 @@ For a `#[pyclass] struct MyClass`, the conversions for `Py` are below: # Python::with_gil(|py| { # #[pyclass] struct MyClass { } # Python::with_gil(|py| -> PyResult<()> { -let my_class: Py = Py::new(py, MyClass { })?; +let my_class: PyDetached = PyDetached::new(py, MyClass { })?; -// To &PyCell with Py::as_ref() (borrows from the Py) +// To &PyCell with PyDetached::as_ref() (borrows from the Py) let _: &PyCell = my_class.as_ref(py); # let my_class_clone = my_class.clone(); // Because `.into_ref()` will consume `my_class`. -// To &PyCell with Py::into_ref() (moves the pointer into PyO3's object storage) +// To &PyCell with PyDetached::into_ref() (moves the pointer into PyO3's object storage) let _: &PyCell = my_class.into_ref(py); # let my_class = my_class_clone.clone(); -// To Py (aka PyObject) with .into_py(py) -let _: Py = my_class.into_py(py); +// To PyDetached (aka PyObject) with .into_py(py) +let _: PyDetached = my_class.into_py(py); # let my_class = my_class_clone; -// To PyRef<'_, MyClass> with Py::borrow or Py::try_borrow +// To PyRef<'_, MyClass> with PyDetached::borrow or PyDetached::try_borrow let _: PyRef<'_, MyClass> = my_class.try_borrow(py)?; -// To PyRefMut<'_, MyClass> with Py::borrow_mut or Py::try_borrow_mut +// To PyRefMut<'_, MyClass> with PyDetached::borrow_mut or PyDetached::try_borrow_mut let _: PyRefMut<'_, MyClass> = my_class.try_borrow_mut(py)?; # Ok(()) # }).unwrap(); diff --git a/newsfragments/3655.changed.md b/newsfragments/3655.changed.md new file mode 100644 index 00000000000..33600a5b5bd --- /dev/null +++ b/newsfragments/3655.changed.md @@ -0,0 +1 @@ +Rename `Py` to `PyDetached`. diff --git a/pyo3-benches/benches/bench_comparisons.rs b/pyo3-benches/benches/bench_comparisons.rs index ffd4c1a452f..7c73dbcb766 100644 --- a/pyo3-benches/benches/bench_comparisons.rs +++ b/pyo3-benches/benches/bench_comparisons.rs @@ -45,8 +45,12 @@ impl OrderedRichcmp { fn bench_ordered_dunder_methods(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let obj1 = Py::new(py, OrderedDunderMethods(0)).unwrap().into_ref(py); - let obj2 = Py::new(py, OrderedDunderMethods(1)).unwrap().into_ref(py); + let obj1 = PyDetached::new(py, OrderedDunderMethods(0)) + .unwrap() + .into_ref(py); + let obj2 = PyDetached::new(py, OrderedDunderMethods(1)) + .unwrap() + .into_ref(py); b.iter(|| obj2.gt(obj1).unwrap()); }); @@ -54,8 +58,8 @@ fn bench_ordered_dunder_methods(b: &mut Bencher<'_>) { fn bench_ordered_richcmp(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let obj1 = Py::new(py, OrderedRichcmp(0)).unwrap().into_ref(py); - let obj2 = Py::new(py, OrderedRichcmp(1)).unwrap().into_ref(py); + let obj1 = PyDetached::new(py, OrderedRichcmp(0)).unwrap().into_ref(py); + let obj2 = PyDetached::new(py, OrderedRichcmp(1)).unwrap().into_ref(py); b.iter(|| obj2.gt(obj1).unwrap()); }); diff --git a/pyo3-macros-backend/src/method.rs b/pyo3-macros-backend/src/method.rs index cb025149c0d..1674a1d89e4 100644 --- a/pyo3-macros-backend/src/method.rs +++ b/pyo3-macros-backend/src/method.rs @@ -187,7 +187,7 @@ impl SelfType { .map_err(::std::convert::Into::<_pyo3::PyErr>::into) .and_then( #[allow(clippy::useless_conversion)] // In case slf is PyCell - #[allow(unknown_lints, clippy::unnecessary_fallible_conversions)] // In case slf is Py (unknown_lints can be removed when MSRV is 1.75+) + #[allow(unknown_lints, clippy::unnecessary_fallible_conversions)] // In case slf is PyDetached (unknown_lints can be removed when MSRV is 1.75+) |cell| ::std::convert::TryFrom::try_from(cell).map_err(::std::convert::Into::into) ) diff --git a/pyo3-macros-backend/src/pyclass.rs b/pyo3-macros-backend/src/pyclass.rs index 239514ae38a..8faf3a3878d 100644 --- a/pyo3-macros-backend/src/pyclass.rs +++ b/pyo3-macros-backend/src/pyclass.rs @@ -875,7 +875,7 @@ impl<'a> PyClassImplsBuilder<'a> { quote! { impl _pyo3::IntoPy<_pyo3::PyObject> for #cls { fn into_py(self, py: _pyo3::Python) -> _pyo3::PyObject { - _pyo3::IntoPy::into_py(_pyo3::Py::new(py, self).unwrap(), py) + _pyo3::IntoPy::into_py(_pyo3::PyDetached::new(py, self).unwrap(), py) } } } diff --git a/src/conversion.rs b/src/conversion.rs index 665cdeca781..f9695fc84a0 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -6,7 +6,7 @@ use crate::pyclass::boolean_struct::False; use crate::type_object::PyTypeInfo; use crate::types::PyTuple; use crate::{ - ffi, gil, Py, PyAny, PyCell, PyClass, PyNativeType, PyObject, PyRef, PyRefMut, Python, + ffi, gil, PyAny, PyCell, PyClass, PyDetached, PyNativeType, PyObject, PyRef, PyRefMut, Python, }; use std::cell::Cell; use std::ptr::NonNull; @@ -24,7 +24,7 @@ use std::ptr::NonNull; /// use pyo3::ffi; /// /// Python::with_gil(|py| { -/// let s: Py = "foo".into_py(py); +/// let s: PyDetached = "foo".into_py(py); /// let ptr = s.as_ptr(); /// /// let is_really_a_pystring = unsafe { ffi::PyUnicode_CheckExact(ptr) }; @@ -180,7 +180,7 @@ pub trait IntoPy: Sized { /// Extract a type from a Python object. /// /// -/// Normal usage is through the `extract` methods on [`Py`] and [`PyAny`], which forward to this trait. +/// Normal usage is through the `extract` methods on [`PyDetached`] and [`PyAny`], which forward to this trait. /// /// # Examples /// @@ -190,7 +190,7 @@ pub trait IntoPy: Sized { /// /// # fn main() -> PyResult<()> { /// Python::with_gil(|py| { -/// let obj: Py = PyString::new(py, "blah").into(); +/// let obj: PyDetached = PyString::new(py, "blah").into(); /// /// // Straight from an owned reference /// let s: &str = obj.extract(py)?; @@ -440,8 +440,8 @@ mod implementations { } /// Converts `()` to an empty Python tuple. -impl IntoPy> for () { - fn into_py(self, py: Python<'_>) -> Py { +impl IntoPy> for () { + fn into_py(self, py: Python<'_>) -> PyDetached { PyTuple::empty(py).into() } } @@ -547,7 +547,7 @@ where /// let t = TestClass { num: 10 }; /// /// Python::with_gil(|py| { -/// let pyvalue = Py::new(py, t).unwrap().to_object(py); +/// let pyvalue = PyDetached::new(py, t).unwrap().to_object(py); /// let t: TestClass = pyvalue.extract(py).unwrap(); /// }) /// ``` diff --git a/src/conversions/num_bigint.rs b/src/conversions/num_bigint.rs index 5cc2157d446..00324870110 100644 --- a/src/conversions/num_bigint.rs +++ b/src/conversions/num_bigint.rs @@ -48,7 +48,7 @@ //! ``` use crate::{ - ffi, types::*, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject, + ffi, types::*, FromPyObject, IntoPy, PyAny, PyDetached, PyObject, PyResult, Python, ToPyObject, }; use num_bigint::{BigInt, BigUint}; @@ -110,11 +110,12 @@ impl<'source> FromPyObject<'source> for BigInt { fn extract(ob: &'source PyAny) -> PyResult { let py = ob.py(); // fast path - checking for subclass of `int` just checks a bit in the type object - let num_owned: Py; + let num_owned: PyDetached; let num = if let Ok(long) = ob.downcast::() { long } else { - num_owned = unsafe { Py::from_owned_ptr_or_err(py, ffi::PyNumber_Index(ob.as_ptr()))? }; + num_owned = + unsafe { PyDetached::from_owned_ptr_or_err(py, ffi::PyNumber_Index(ob.as_ptr()))? }; num_owned.as_ref(py) }; let n_bits = int_n_bits(num)?; @@ -158,11 +159,12 @@ impl<'source> FromPyObject<'source> for BigUint { fn extract(ob: &'source PyAny) -> PyResult { let py = ob.py(); // fast path - checking for subclass of `int` just checks a bit in the type object - let num_owned: Py; + let num_owned: PyDetached; let num = if let Ok(long) = ob.downcast::() { long } else { - num_owned = unsafe { Py::from_owned_ptr_or_err(py, ffi::PyNumber_Index(ob.as_ptr()))? }; + num_owned = + unsafe { PyDetached::from_owned_ptr_or_err(py, ffi::PyNumber_Index(ob.as_ptr()))? }; num_owned.as_ref(py) }; let n_bits = int_n_bits(num)?; diff --git a/src/conversions/rust_decimal.rs b/src/conversions/rust_decimal.rs index 173e57851c9..06cd1473dc5 100644 --- a/src/conversions/rust_decimal.rs +++ b/src/conversions/rust_decimal.rs @@ -52,7 +52,9 @@ use crate::exceptions::PyValueError; use crate::sync::GILOnceCell; use crate::types::PyType; -use crate::{intern, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject}; +use crate::{ + intern, FromPyObject, IntoPy, PyAny, PyDetached, PyObject, PyResult, Python, ToPyObject, +}; use rust_decimal::Decimal; use std::str::FromStr; @@ -68,7 +70,7 @@ impl FromPyObject<'_> for Decimal { } } -static DECIMAL_CLS: GILOnceCell> = GILOnceCell::new(); +static DECIMAL_CLS: GILOnceCell> = GILOnceCell::new(); fn get_decimal_cls(py: Python<'_>) -> PyResult<&PyType> { DECIMAL_CLS diff --git a/src/conversions/serde.rs b/src/conversions/serde.rs index a769bd70273..9d3441d1123 100644 --- a/src/conversions/serde.rs +++ b/src/conversions/serde.rs @@ -1,6 +1,6 @@ #![cfg(feature = "serde")] -//! Enables (de)serialization of [`Py`]`` objects via [serde](https://docs.rs/serde). +//! Enables (de)serialization of [`PyDetached`]`` objects via [serde](https://docs.rs/serde). //! //! # Setup //! @@ -12,10 +12,10 @@ //! serde = "1.0" //! ``` -use crate::{Py, PyAny, PyClass, Python}; +use crate::{PyAny, PyClass, PyDetached, Python}; use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer}; -impl Serialize for Py +impl Serialize for PyDetached where T: Serialize + PyClass, { @@ -31,18 +31,18 @@ where } } -impl<'de, T> Deserialize<'de> for Py +impl<'de, T> Deserialize<'de> for PyDetached where T: PyClass + Deserialize<'de>, { - fn deserialize(deserializer: D) -> Result, D::Error> + fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { let deserialized = T::deserialize(deserializer)?; Python::with_gil(|py| { - Py::new(py, deserialized).map_err(|e| de::Error::custom(e.to_string())) + PyDetached::new(py, deserialized).map_err(|e| de::Error::custom(e.to_string())) }) } } diff --git a/src/conversions/std/array.rs b/src/conversions/std/array.rs index 167f8070632..255511fb359 100644 --- a/src/conversions/std/array.rs +++ b/src/conversions/std/array.rs @@ -1,7 +1,8 @@ use crate::types::PySequence; use crate::{exceptions, PyErr}; use crate::{ - ffi, FromPyObject, IntoPy, Py, PyAny, PyDowncastError, PyObject, PyResult, Python, ToPyObject, + ffi, FromPyObject, IntoPy, PyAny, PyDetached, PyDowncastError, PyObject, PyResult, Python, + ToPyObject, }; impl IntoPy for [T; N] @@ -14,10 +15,10 @@ where let ptr = ffi::PyList_New(len); - // We create the `Py` pointer here for two reasons: + // We create the `PyDetached` pointer here for two reasons: // - panics if the ptr is null // - its Drop cleans up the list if user code panics. - let list: Py = Py::from_owned_ptr(py, ptr); + let list: PyDetached = PyDetached::from_owned_ptr(py, ptr); for (i, obj) in (0..len).zip(self) { let obj = obj.into_py(py).into_ptr(); diff --git a/src/conversions/std/ipaddr.rs b/src/conversions/std/ipaddr.rs index ca3c8728f9b..7fa6c8596e3 100755 --- a/src/conversions/std/ipaddr.rs +++ b/src/conversions/std/ipaddr.rs @@ -3,7 +3,9 @@ use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use crate::exceptions::PyValueError; use crate::sync::GILOnceCell; use crate::types::PyType; -use crate::{intern, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject}; +use crate::{ + intern, FromPyObject, IntoPy, PyAny, PyDetached, PyObject, PyResult, Python, ToPyObject, +}; impl FromPyObject<'_> for IpAddr { fn extract(obj: &PyAny) -> PyResult { @@ -27,7 +29,7 @@ impl FromPyObject<'_> for IpAddr { impl ToPyObject for Ipv4Addr { fn to_object(&self, py: Python<'_>) -> PyObject { - static IPV4_ADDRESS: GILOnceCell> = GILOnceCell::new(); + static IPV4_ADDRESS: GILOnceCell> = GILOnceCell::new(); IPV4_ADDRESS .get_or_try_init_type_ref(py, "ipaddress", "IPv4Address") .expect("failed to load ipaddress.IPv4Address") @@ -39,7 +41,7 @@ impl ToPyObject for Ipv4Addr { impl ToPyObject for Ipv6Addr { fn to_object(&self, py: Python<'_>) -> PyObject { - static IPV6_ADDRESS: GILOnceCell> = GILOnceCell::new(); + static IPV6_ADDRESS: GILOnceCell> = GILOnceCell::new(); IPV6_ADDRESS .get_or_try_init_type_ref(py, "ipaddress", "IPv6Address") .expect("failed to load ipaddress.IPv6Address") diff --git a/src/conversions/std/osstr.rs b/src/conversions/std/osstr.rs index b2c143866ac..6d9447204b0 100644 --- a/src/conversions/std/osstr.rs +++ b/src/conversions/std/osstr.rs @@ -58,7 +58,7 @@ impl FromPyObject<'_> for OsString { { // Decode from Python's lossless bytes string representation back into raw bytes let fs_encoded_bytes = unsafe { - crate::Py::::from_owned_ptr( + crate::PyDetached::::from_owned_ptr( ob.py(), ffi::PyUnicode_EncodeFSDefault(pystring.as_ptr()), ) diff --git a/src/conversions/std/string.rs b/src/conversions/std/string.rs index b4bc8c26099..8fa485295dd 100644 --- a/src/conversions/std/string.rs +++ b/src/conversions/std/string.rs @@ -3,7 +3,8 @@ use std::borrow::Cow; #[cfg(feature = "experimental-inspect")] use crate::inspect::types::TypeInfo; use crate::{ - types::PyString, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject, + types::PyString, FromPyObject, IntoPy, PyAny, PyDetached, PyObject, PyResult, Python, + ToPyObject, }; /// Converts a Rust `str` to a Python object. @@ -27,9 +28,9 @@ impl<'a> IntoPy for &'a str { } } -impl<'a> IntoPy> for &'a str { +impl<'a> IntoPy> for &'a str { #[inline] - fn into_py(self, py: Python<'_>) -> Py { + fn into_py(self, py: Python<'_>) -> PyDetached { PyString::new(py, self).into() } diff --git a/src/coroutine.rs b/src/coroutine.rs index 6380b4e0a1f..b2005f44369 100644 --- a/src/coroutine.rs +++ b/src/coroutine.rs @@ -16,7 +16,7 @@ use crate::{ panic::PanicException, pyclass::IterNextOutput, types::{PyIterator, PyString}, - IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python, + IntoPy, PyAny, PyDetached, PyErr, PyObject, PyResult, Python, }; pub(crate) mod cancel; @@ -29,7 +29,7 @@ const COROUTINE_REUSED_ERROR: &str = "cannot reuse already awaited coroutine"; /// Python coroutine wrapping a [`Future`]. #[pyclass(crate = "crate")] pub struct Coroutine { - name: Option>, + name: Option>, qualname_prefix: Option<&'static str>, throw_callback: Option, future: Option> + Send>>>, @@ -44,7 +44,7 @@ impl Coroutine { /// /// `Coroutine `throw` drop the wrapped future and reraise the exception passed pub(crate) fn new( - name: Option>, + name: Option>, qualname_prefix: Option<&'static str>, throw_callback: Option, future: F, @@ -134,7 +134,7 @@ pub(crate) fn iter_result(result: IterNextOutput) -> PyResul #[pymethods(crate = "crate")] impl Coroutine { #[getter] - fn __name__(&self, py: Python<'_>) -> PyResult> { + fn __name__(&self, py: Python<'_>) -> PyResult> { match &self.name { Some(name) => Ok(name.clone_ref(py)), None => Err(PyAttributeError::new_err("__name__")), @@ -142,7 +142,7 @@ impl Coroutine { } #[getter] - fn __qualname__(&self, py: Python<'_>) -> PyResult> { + fn __qualname__(&self, py: Python<'_>) -> PyResult> { match (&self.name, &self.qualname_prefix) { (Some(name), Some(prefix)) => Ok(format!("{}.{}", prefix, name.as_ref(py).to_str()?) .as_str() @@ -166,7 +166,7 @@ impl Coroutine { drop(self.future.take()); } - fn __await__(self_: Py) -> Py { + fn __await__(self_: PyDetached) -> PyDetached { self_ } diff --git a/src/coroutine/waker.rs b/src/coroutine/waker.rs index 8a1166ce3fb..bfc351fceda 100644 --- a/src/coroutine/waker.rs +++ b/src/coroutine/waker.rs @@ -1,6 +1,6 @@ use crate::sync::GILOnceCell; use crate::types::PyCFunction; -use crate::{intern, wrap_pyfunction, Py, PyAny, PyObject, PyResult, Python}; +use crate::{intern, wrap_pyfunction, PyAny, PyDetached, PyObject, PyResult, Python}; use pyo3_macros::pyfunction; use std::sync::Arc; use std::task::Wake; @@ -65,7 +65,7 @@ impl LoopAndFuture { } fn set_result(&self, py: Python<'_>) -> PyResult<()> { - static RELEASE_WAITER: GILOnceCell> = GILOnceCell::new(); + static RELEASE_WAITER: GILOnceCell> = GILOnceCell::new(); let release_waiter = RELEASE_WAITER .get_or_try_init(py, || wrap_pyfunction!(release_waiter, py).map(Into::into))?; // `Future.set_result` must be called in event loop thread, diff --git a/src/err/err_state.rs b/src/err/err_state.rs index b9bda9b7013..684a2f30770 100644 --- a/src/err/err_state.rs +++ b/src/err/err_state.rs @@ -2,16 +2,16 @@ use crate::{ exceptions::{PyBaseException, PyTypeError}, ffi, types::{PyTraceback, PyType}, - IntoPy, Py, PyAny, PyObject, PyTypeInfo, Python, + IntoPy, PyAny, PyDetached, PyObject, PyTypeInfo, Python, }; #[derive(Clone)] pub(crate) struct PyErrStateNormalized { #[cfg(not(Py_3_12))] - ptype: Py, - pub pvalue: Py, + ptype: PyDetached, + pub pvalue: PyDetached, #[cfg(not(Py_3_12))] - ptraceback: Option>, + ptraceback: Option>, } impl PyErrStateNormalized { @@ -39,7 +39,7 @@ impl PyErrStateNormalized { #[cfg(Py_3_12)] pub(crate) fn take(py: Python<'_>) -> Option { - unsafe { Py::from_owned_ptr_or_opt(py, ffi::PyErr_GetRaisedException()) } + unsafe { PyDetached::from_owned_ptr_or_opt(py, ffi::PyErr_GetRaisedException()) } .map(|pvalue| PyErrStateNormalized { pvalue }) } @@ -51,9 +51,9 @@ impl PyErrStateNormalized { ptraceback: *mut ffi::PyObject, ) -> Self { PyErrStateNormalized { - ptype: Py::from_owned_ptr_or_opt(py, ptype).expect("Exception type missing"), - pvalue: Py::from_owned_ptr_or_opt(py, pvalue).expect("Exception value missing"), - ptraceback: Py::from_owned_ptr_or_opt(py, ptraceback), + ptype: PyDetached::from_owned_ptr_or_opt(py, ptype).expect("Exception type missing"), + pvalue: PyDetached::from_owned_ptr_or_opt(py, pvalue).expect("Exception value missing"), + ptraceback: PyDetached::from_owned_ptr_or_opt(py, ptraceback), } } } @@ -108,7 +108,7 @@ impl PyErrState { pvalue: pvalue.into(), #[cfg(not(Py_3_12))] ptraceback: unsafe { - Py::from_owned_ptr_or_opt( + PyDetached::from_owned_ptr_or_opt( pvalue.py(), ffi::PyException_GetTraceback(pvalue.as_ptr()), ) @@ -140,8 +140,8 @@ impl PyErrState { ptraceback, } => { let mut ptype = ptype.into_ptr(); - let mut pvalue = pvalue.map_or(std::ptr::null_mut(), Py::into_ptr); - let mut ptraceback = ptraceback.map_or(std::ptr::null_mut(), Py::into_ptr); + let mut pvalue = pvalue.map_or(std::ptr::null_mut(), PyDetached::into_ptr); + let mut ptraceback = ptraceback.map_or(std::ptr::null_mut(), PyDetached::into_ptr); unsafe { ffi::PyErr_NormalizeException(&mut ptype, &mut pvalue, &mut ptraceback); PyErrStateNormalized::from_normalized_ffi_tuple(py, ptype, pvalue, ptraceback) @@ -161,8 +161,8 @@ impl PyErrState { ptraceback, } => ( ptype.into_ptr(), - pvalue.map_or(std::ptr::null_mut(), Py::into_ptr), - ptraceback.map_or(std::ptr::null_mut(), Py::into_ptr), + pvalue.map_or(std::ptr::null_mut(), PyDetached::into_ptr), + ptraceback.map_or(std::ptr::null_mut(), PyDetached::into_ptr), ), PyErrState::Normalized(PyErrStateNormalized { ptype, @@ -171,7 +171,7 @@ impl PyErrState { }) => ( ptype.into_ptr(), pvalue.into_ptr(), - ptraceback.map_or(std::ptr::null_mut(), Py::into_ptr), + ptraceback.map_or(std::ptr::null_mut(), PyDetached::into_ptr), ), }; unsafe { ffi::PyErr_Restore(ptype, pvalue, ptraceback) } diff --git a/src/err/mod.rs b/src/err/mod.rs index cd2139b607e..cd4b2d21919 100644 --- a/src/err/mod.rs +++ b/src/err/mod.rs @@ -5,7 +5,7 @@ use crate::{ exceptions::{self, PyBaseException}, ffi, }; -use crate::{IntoPy, Py, PyAny, PyObject, Python, ToPyObject}; +use crate::{IntoPy, PyAny, PyDetached, PyObject, Python, ToPyObject}; use std::borrow::Cow; use std::cell::UnsafeCell; use std::ffi::CString; @@ -220,7 +220,7 @@ impl PyErr { } /// Consumes self to take ownership of the exception value contained in this error. - pub fn into_value(self, py: Python<'_>) -> Py { + pub fn into_value(self, py: Python<'_>) -> PyDetached { // NB technically this causes one reference count increase and decrease in quick succession // on pvalue, but it's probably not worth optimizing this right now for the additional code // complexity. @@ -395,7 +395,7 @@ impl PyErr { doc: Option<&str>, base: Option<&PyType>, dict: Option, - ) -> PyResult> { + ) -> PyResult> { let base: *mut ffi::PyObject = match base { None => std::ptr::null_mut(), Some(obj) => obj.as_ptr(), @@ -426,7 +426,7 @@ impl PyErr { ) }; - unsafe { Py::from_owned_ptr_or_err(py, ptr) } + unsafe { PyDetached::from_owned_ptr_or_err(py, ptr) } } /// Prints a standard traceback to `sys.stderr`. @@ -641,7 +641,7 @@ impl PyErr { // PyException_SetCause _steals_ a reference to cause, so must use .into_ptr() ffi::PyException_SetCause( value.as_ptr(), - cause.map_or(std::ptr::null_mut(), Py::into_ptr), + cause.map_or(std::ptr::null_mut(), PyDetached::into_ptr), ); } } @@ -738,7 +738,7 @@ impl<'a> IntoPy for &'a PyErr { } struct PyDowncastErrorArguments { - from: Py, + from: PyDetached, to: Cow<'static, str>, } diff --git a/src/exceptions.rs b/src/exceptions.rs index 6ff662b4ae4..f7da7856532 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -100,7 +100,7 @@ macro_rules! import_exception { impl $name { fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject { use $crate::sync::GILOnceCell; - static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> = + static TYPE_OBJECT: GILOnceCell<$crate::PyDetached<$crate::types::PyType>> = GILOnceCell::new(); TYPE_OBJECT @@ -238,7 +238,7 @@ macro_rules! create_exception_type_object { impl $name { fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject { use $crate::sync::GILOnceCell; - static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> = + static TYPE_OBJECT: GILOnceCell<$crate::PyDetached<$crate::types::PyType>> = GILOnceCell::new(); TYPE_OBJECT diff --git a/src/ffi/tests.rs b/src/ffi/tests.rs index 2cbd84dc6db..ddc7d0faf57 100644 --- a/src/ffi/tests.rs +++ b/src/ffi/tests.rs @@ -4,7 +4,7 @@ use crate::Python; #[cfg(not(Py_LIMITED_API))] use crate::{ types::{PyDict, PyString}, - IntoPy, Py, PyAny, + IntoPy, PyAny, PyDetached, }; #[cfg(not(any(Py_3_12, Py_LIMITED_API)))] use libc::wchar_t; @@ -14,7 +14,7 @@ use libc::wchar_t; #[test] fn test_datetime_fromtimestamp() { Python::with_gil(|py| { - let args: Py = (100,).into_py(py); + let args: PyDetached = (100,).into_py(py); let dt: &PyAny = unsafe { PyDateTime_IMPORT(); py.from_owned_ptr(PyDateTime_FromTimestamp(args.as_ptr())) @@ -35,7 +35,7 @@ fn test_datetime_fromtimestamp() { #[test] fn test_date_fromtimestamp() { Python::with_gil(|py| { - let args: Py = (100,).into_py(py); + let args: PyDetached = (100,).into_py(py); let dt: &PyAny = unsafe { PyDateTime_IMPORT(); py.from_owned_ptr(PyDate_FromTimestamp(args.as_ptr())) diff --git a/src/gil.rs b/src/gil.rs index d346ad95ea9..7cc7f3b6129 100644 --- a/src/gil.rs +++ b/src/gil.rs @@ -786,7 +786,7 @@ mod tests { #[test] #[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled fn test_clone_without_gil() { - use crate::{Py, PyAny}; + use crate::{PyAny, PyDetached}; use std::{sync::Arc, thread}; // Some events for synchronizing @@ -795,7 +795,7 @@ mod tests { static REFCNT_CHECKED: Event = Event::new(); Python::with_gil(|py| { - let obj: Arc> = Arc::new(get_object(py)); + let obj: Arc> = Arc::new(get_object(py)); let thread_obj = Arc::clone(&obj); let count = obj.get_refcnt(py); @@ -826,7 +826,7 @@ mod tests { println!("4. The other thread is now hogging the GIL, we clone without it held"); // Cloning without GIL should not update reference count - let cloned = Py::clone(&*obj); + let cloned = PyDetached::clone(&*obj); OBJECT_CLONED.set(); cloned }); @@ -851,7 +851,7 @@ mod tests { #[test] #[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled fn test_clone_in_other_thread() { - use crate::Py; + use crate::PyDetached; use std::{sync::Arc, thread}; // Some events for synchronizing @@ -866,7 +866,7 @@ mod tests { let t = thread::spawn(move || { // Cloning without GIL should not update reference count #[allow(clippy::redundant_clone)] - let _ = Py::clone(&*thread_obj); + let _ = PyDetached::clone(&*thread_obj); OBJECT_CLONED.set(); }); diff --git a/src/impl_/coroutine.rs b/src/impl_/coroutine.rs index 32f3e94ad8a..52d4ef8a10a 100644 --- a/src/impl_/coroutine.rs +++ b/src/impl_/coroutine.rs @@ -8,7 +8,7 @@ use crate::{ coroutine::{cancel::ThrowCallback, Coroutine}, pyclass::boolean_struct::False, types::PyString, - IntoPy, Py, PyAny, PyCell, PyClass, PyErr, PyObject, PyResult, Python, + IntoPy, PyAny, PyCell, PyClass, PyDetached, PyErr, PyObject, PyResult, Python, }; pub fn new_coroutine( @@ -25,16 +25,16 @@ where Coroutine::new(Some(name.into()), qualname_prefix, throw_callback, future) } -fn get_ptr(obj: &Py) -> *mut T { - // SAFETY: Py can be casted as *const PyCell +fn get_ptr(obj: &PyDetached) -> *mut T { + // SAFETY: PyDetached can be casted as *const PyCell unsafe { &*(obj.as_ptr() as *const PyCell) }.get_ptr() } -pub struct RefGuard(Py); +pub struct RefGuard(PyDetached); impl RefGuard { pub fn new(obj: &PyAny) -> PyResult { - let owned: Py = obj.extract()?; + let owned: PyDetached = obj.extract()?; mem::forget(owned.try_borrow(obj.py())?); Ok(RefGuard(owned)) } @@ -54,11 +54,11 @@ impl Drop for RefGuard { } } -pub struct RefMutGuard>(Py); +pub struct RefMutGuard>(PyDetached); impl> RefMutGuard { pub fn new(obj: &PyAny) -> PyResult { - let owned: Py = obj.extract()?; + let owned: PyDetached = obj.extract()?; mem::forget(owned.try_borrow_mut(obj.py())?); Ok(RefMutGuard(owned)) } diff --git a/src/impl_/pyclass.rs b/src/impl_/pyclass.rs index 3941dfcb3e7..04d07561bdd 100644 --- a/src/impl_/pyclass.rs +++ b/src/impl_/pyclass.rs @@ -7,7 +7,8 @@ use crate::{ pycell::PyCellLayout, pyclass_init::PyObjectInit, types::PyBool, - Py, PyAny, PyCell, PyClass, PyErr, PyMethodDefType, PyNativeType, PyResult, PyTypeInfo, Python, + PyAny, PyCell, PyClass, PyDetached, PyErr, PyMethodDefType, PyNativeType, PyResult, PyTypeInfo, + Python, }; use std::{ borrow::Cow, @@ -329,7 +330,7 @@ slot_fragment_trait! { attr: *mut ffi::PyObject, ) -> PyResult<*mut ffi::PyObject> { Err(PyErr::new::( - (Py::::from_borrowed_ptr(py, attr),) + (PyDetached::::from_borrowed_ptr(py, attr),) )) } } diff --git a/src/impl_/pyclass/lazy_type_object.rs b/src/impl_/pyclass/lazy_type_object.rs index af52033a702..0087063cd21 100644 --- a/src/impl_/pyclass/lazy_type_object.rs +++ b/src/impl_/pyclass/lazy_type_object.rs @@ -61,7 +61,7 @@ impl LazyTypeObject { } impl LazyTypeObjectInner { - // Uses dynamically dispatched fn(Python<'py>) -> PyResult + // Uses dynamically dispatched fn(Python<'py>) -> PyResult // so that this code is only instantiated once, instead of for every T // like the generic LazyTypeObject methods above. fn get_or_try_init<'py>( diff --git a/src/impl_/pymodule.rs b/src/impl_/pymodule.rs index 7c5243fcf1c..3c8c76563a4 100644 --- a/src/impl_/pymodule.rs +++ b/src/impl_/pymodule.rs @@ -7,7 +7,7 @@ use portable_atomic::{AtomicI64, Ordering}; #[cfg(not(PyPy))] use crate::exceptions::PyImportError; -use crate::{ffi, sync::GILOnceCell, types::PyModule, Py, PyResult, Python}; +use crate::{ffi, sync::GILOnceCell, types::PyModule, PyDetached, PyResult, Python}; /// `Sync` wrapper of `ffi::PyModuleDef`. pub struct ModuleDef { @@ -18,7 +18,7 @@ pub struct ModuleDef { #[cfg(all(not(PyPy), Py_3_9, not(all(windows, Py_LIMITED_API, not(Py_3_10)))))] interpreter: AtomicI64, /// Initialized module object, cached to avoid reinitialization. - module: GILOnceCell>, + module: GILOnceCell>, } /// Wrapper to enable initializer to be used in const fns. @@ -64,7 +64,7 @@ impl ModuleDef { } } /// Builds a module using user given initializer. Used for [`#[pymodule]`][crate::pymodule]. - pub fn make_module(&'static self, py: Python<'_>) -> PyResult> { + pub fn make_module(&'static self, py: Python<'_>) -> PyResult> { #[cfg(all(PyPy, not(Py_3_8)))] { const PYPY_GOOD_VERSION: [u8; 3] = [7, 3, 8]; @@ -120,7 +120,7 @@ impl ModuleDef { self.module .get_or_try_init(py, || { let module = unsafe { - Py::::from_owned_ptr_or_err( + PyDetached::::from_owned_ptr_or_err( py, ffi::PyModule_Create(self.ffi_def.get()), )? diff --git a/src/impl_/trampoline.rs b/src/impl_/trampoline.rs index 5ae75e0fd2e..07beafcd86f 100644 --- a/src/impl_/trampoline.rs +++ b/src/impl_/trampoline.rs @@ -11,12 +11,12 @@ use std::{ use crate::{ callback::PyCallbackOutput, ffi, impl_::panic::PanicTrap, methods::IPowModulo, - panic::PanicException, types::PyModule, GILPool, Py, PyResult, Python, + panic::PanicException, types::PyModule, GILPool, PyDetached, PyResult, Python, }; #[inline] pub unsafe fn module_init( - f: for<'py> unsafe fn(Python<'py>) -> PyResult>, + f: for<'py> unsafe fn(Python<'py>) -> PyResult>, ) -> *mut ffi::PyObject { trampoline(|py| f(py).map(|module| module.into_ptr())) } diff --git a/src/instance.rs b/src/instance.rs index 1c0fdbcb596..d847fd1c621 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -43,21 +43,21 @@ pub unsafe trait PyNativeType: Sized { } } -/// A GIL-attached equivalent to `Py`. +/// A GIL-attached equivalent to `PyDetached`. #[repr(transparent)] -pub(crate) struct Py2<'py, T>(Python<'py>, ManuallyDrop>); +pub(crate) struct Py2<'py, T>(Python<'py>, ManuallyDrop>); impl<'py> Py2<'py, PyAny> { /// Constructs a new Py2 from a pointer. Panics if ptr is null. pub(crate) unsafe fn from_owned_ptr(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self { - Self(py, ManuallyDrop::new(Py::from_owned_ptr(py, ptr))) + Self(py, ManuallyDrop::new(PyDetached::from_owned_ptr(py, ptr))) } // /// Constructs a new Py2 from a pointer. Returns None if ptr is null. // /// // /// Safety: ptr must be a valid pointer to a Python object, or NULL. // pub unsafe fn from_owned_ptr_or_opt(py: Python<'py>, ptr: *mut ffi::PyObject) -> Option { - // Py::from_owned_ptr_or_opt(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj))) + // PyDetached::from_owned_ptr_or_opt(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj))) // } /// Constructs a new Py2 from a pointer. Returns error if ptr is null. @@ -65,7 +65,7 @@ impl<'py> Py2<'py, PyAny> { py: Python<'py>, ptr: *mut ffi::PyObject, ) -> PyResult { - Py::from_owned_ptr_or_err(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj))) + PyDetached::from_owned_ptr_or_err(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj))) } } @@ -226,7 +226,7 @@ unsafe impl AsPyPointer for Py2<'_, T> { /// to get a (mutable) reference to a contained pyclass, using a scheme similar to std's [`RefCell`]. /// See the [`PyCell` guide entry](https://pyo3.rs/latest/class.html#pycell-and-interior-mutability) /// for more information. -/// - You can call methods directly on `Py` with [`Py::call`], [`Py::call_method`] and friends. +/// - You can call methods directly on `PyDetached` with [`Py::call`], [`Py::call_method`] and friends. /// These require passing in the [`Python<'py>`](crate::Python) token but are otherwise similar to the corresponding /// methods on [`PyAny`]. /// @@ -264,7 +264,7 @@ unsafe impl AsPyPointer for Py2<'_, T> { /// } /// ``` /// -/// [`Py`]`` can be used to get around this by converting `dict` into a GIL-independent reference: +/// [`PyDetached`]`` can be used to get around this by converting `dict` into a GIL-independent reference: /// /// ```rust /// use pyo3::prelude::*; @@ -272,7 +272,7 @@ unsafe impl AsPyPointer for Py2<'_, T> { /// /// #[pyclass] /// struct Foo { -/// inner: Py, +/// inner: PyDetached, /// } /// /// #[pymethods] @@ -280,7 +280,7 @@ unsafe impl AsPyPointer for Py2<'_, T> { /// #[new] /// fn __new__() -> Foo { /// Python::with_gil(|py| { -/// let dict: Py = PyDict::new(py).into(); +/// let dict: PyDetached = PyDict::new(py).into(); /// Foo { inner: dict } /// }) /// } @@ -309,7 +309,7 @@ unsafe impl AsPyPointer for Py2<'_, T> { /// /// #[pyclass] /// struct Foo { -/// inner: Py, +/// inner: PyDetached, /// } /// /// #[pymethods] @@ -317,7 +317,7 @@ unsafe impl AsPyPointer for Py2<'_, T> { /// #[new] /// fn __new__() -> PyResult { /// Python::with_gil(|py| { -/// let bar: Py = Py::new(py, Bar {})?; +/// let bar: PyDetached = PyDetached::new(py, Bar {})?; /// Ok(Foo { inner: bar }) /// }) /// } @@ -343,7 +343,7 @@ unsafe impl AsPyPointer for Py2<'_, T> { /// As with [`Rc`]``, cloning it increases its reference count rather than duplicating /// the underlying object. /// -/// This can be done using either [`Py::clone_ref`] or [`Py`]``'s [`Clone`] trait implementation. +/// This can be done using either [`Py::clone_ref`] or [`PyDetached`]``'s [`Clone`] trait implementation. /// [`Py::clone_ref`] will be faster if you happen to be already holding the GIL. /// /// ```rust @@ -352,12 +352,12 @@ unsafe impl AsPyPointer for Py2<'_, T> { /// /// # fn main() { /// Python::with_gil(|py| { -/// let first: Py = PyDict::new(py).into(); +/// let first: PyDetached = PyDict::new(py).into(); /// /// // All of these are valid syntax -/// let second = Py::clone_ref(&first, py); +/// let second = PyDetached::clone_ref(&first, py); /// let third = first.clone_ref(py); -/// let fourth = Py::clone(&first); +/// let fourth = PyDetached::clone(&first); /// let fifth = first.clone(); /// /// // Disposing of our original `Py` just decrements the reference count. @@ -373,20 +373,20 @@ unsafe impl AsPyPointer for Py2<'_, T> { /// /// # Preventing reference cycles /// -/// It is easy to accidentally create reference cycles using [`Py`]``. +/// It is easy to accidentally create reference cycles using [`PyDetached`]``. /// The Python interpreter can break these reference cycles within pyclasses if they /// [integrate with the garbage collector][gc]. If your pyclass contains other Python /// objects you should implement it to avoid leaking memory. /// /// # A note on Python reference counts /// -/// Dropping a [`Py`]`` will eventually decrease Python's reference count +/// Dropping a [`PyDetached`]`` will eventually decrease Python's reference count /// of the pointed-to variable, allowing Python's garbage collector to free /// the associated memory, but this may not happen immediately. This is -/// because a [`Py`]`` can be dropped at any time, but the Python reference +/// because a [`PyDetached`]`` can be dropped at any time, but the Python reference /// count can only be modified when the GIL is held. /// -/// If a [`Py`]`` is dropped while its thread happens to be holding the +/// If a [`PyDetached`]`` is dropped while its thread happens to be holding the /// GIL then the Python reference count will be decreased immediately. /// Otherwise, the reference count will be decreased the next time the GIL is /// reacquired. @@ -400,15 +400,22 @@ unsafe impl AsPyPointer for Py2<'_, T> { /// [`RefCell`]: std::cell::RefCell /// [gc]: https://pyo3.rs/main/class/protocols.html#garbage-collector-integration #[repr(transparent)] -pub struct Py(NonNull, PhantomData); +pub struct PyDetached(NonNull, PhantomData); + +#[deprecated( + since = "0.21.0", + note = "`Py` has been renamed to `PyDetached` to make space for an upcoming rework to the PyO3 API." +)] +/// Deprecated name for [`PyDetached`]. +pub type Py = PyDetached; // The inner value is only accessed through ways that require proving the gil is held #[cfg(feature = "nightly")] -unsafe impl crate::marker::Ungil for Py {} -unsafe impl Send for Py {} -unsafe impl Sync for Py {} +unsafe impl crate::marker::Ungil for PyDetached {} +unsafe impl Send for PyDetached {} +unsafe impl Sync for PyDetached {} -impl Py +impl PyDetached where T: PyClass, { @@ -423,22 +430,22 @@ where /// struct Foo {/* fields omitted */} /// /// # fn main() -> PyResult<()> { - /// Python::with_gil(|py| -> PyResult> { - /// let foo: Py = Py::new(py, Foo {})?; + /// Python::with_gil(|py| -> PyResult> { + /// let foo: PyDetached = PyDetached::new(py, Foo {})?; /// Ok(foo) /// })?; /// # Ok(()) /// # } /// ``` - pub fn new(py: Python<'_>, value: impl Into>) -> PyResult> { + pub fn new(py: Python<'_>, value: impl Into>) -> PyResult> { let initializer = value.into(); let obj = initializer.create_cell(py)?; - let ob = unsafe { Py::from_owned_ptr(py, obj as _) }; + let ob = unsafe { PyDetached::from_owned_ptr(py, obj as _) }; Ok(ob) } } -impl Py +impl PyDetached where T: HasPyGilRef, { @@ -463,7 +470,7 @@ where /// # use pyo3::types::PyList; /// # /// Python::with_gil(|py| { - /// let list: Py = PyList::empty(py).into(); + /// let list: PyDetached = PyList::empty(py).into(); /// // FIXME as_ref() no longer makes sense with new Py API, remove this doc /// // let list: &PyList = list.as_ref(py); /// // assert_eq!(list.len(), 0); @@ -479,7 +486,7 @@ where /// struct MyClass {} /// /// Python::with_gil(|py| { - /// let my_class: Py = Py::new(py, MyClass {}).unwrap(); + /// let my_class: PyDetached = PyDetached::new(py, MyClass {}).unwrap(); /// let my_class_cell: &PyCell = my_class.as_ref(py); /// assert!(my_class_cell.try_borrow().is_ok()); /// }); @@ -505,8 +512,8 @@ where /// ```rust,compile_fail /// # use pyo3::prelude::*; /// # - /// fn new_py_any<'py>(py: Python<'py>, value: impl IntoPy>) -> &'py PyAny { - /// let obj: Py = value.into_py(py); + /// fn new_py_any<'py>(py: Python<'py>, value: impl IntoPy>) -> &'py PyAny { + /// let obj: PyDetached = value.into_py(py); /// /// // The lifetime of the return value of this function is the shortest /// // of `obj` and `py`. As `obj` is owned by the current function, @@ -522,8 +529,8 @@ where /// ```rust /// # use pyo3::prelude::*; /// # #[allow(dead_code)] // This is just to show it compiles. - /// fn new_py_any<'py>(py: Python<'py>, value: impl IntoPy>) -> &'py PyAny { - /// let obj: Py = value.into_py(py); + /// fn new_py_any<'py>(py: Python<'py>, value: impl IntoPy>) -> &'py PyAny { + /// let obj: PyDetached = value.into_py(py); /// /// // This reference's lifetime is determined by `py`'s lifetime. /// // Because that originates from outside this function, @@ -536,7 +543,7 @@ where } } -impl Py { +impl PyDetached { /// Returns the raw FFI pointer represented by self. /// /// # Safety @@ -564,7 +571,7 @@ impl Py { } } -impl Py +impl PyDetached where T: PyClass, { @@ -590,7 +597,7 @@ where /// /// # fn main() -> PyResult<()> { /// Python::with_gil(|py| -> PyResult<()> { - /// let foo: Py = Py::new(py, Foo { inner: 73 })?; + /// let foo: PyDetached = PyDetached::new(py, Foo { inner: 73 })?; /// let inner: &u8 = &foo.borrow(py).inner; /// /// assert_eq!(*inner, 73); @@ -627,7 +634,7 @@ where /// /// # fn main() -> PyResult<()> { /// Python::with_gil(|py| -> PyResult<()> { - /// let foo: Py = Py::new(py, Foo { inner: 73 })?; + /// let foo: PyDetached = PyDetached::new(py, Foo { inner: 73 })?; /// foo.borrow_mut(py).inner = 35; /// /// assert_eq!(foo.borrow(py).inner, 35); @@ -697,7 +704,7 @@ where /// let cell = Python::with_gil(|py| { /// let counter = FrozenCounter { value: AtomicUsize::new(0) }; /// - /// Py::new(py, counter).unwrap() + /// PyDetached::new(py, counter).unwrap() /// }); /// /// cell.get().value.fetch_add(1, Ordering::Relaxed); @@ -715,11 +722,11 @@ where } } -impl Py { - /// Attaches this `Py` to the given Python context, allowing access to further Python APIs. +impl PyDetached { + /// Attaches this `PyDetached` to the given Python context, allowing access to further Python APIs. pub(crate) fn attach<'py>(&self, _py: Python<'py>) -> &Py2<'py, T> { - // Safety: `Py2` has the same layout as `Py` - unsafe { &*(self as *const Py).cast() } + // Safety: `Py2` has the same layout as `PyDetached` + unsafe { &*(self as *const PyDetached).cast() } } /// Same as `attach` but takes ownership of `self`. @@ -756,8 +763,8 @@ impl Py { /// /// # fn main() { /// Python::with_gil(|py| { - /// let first: Py = PyDict::new(py).into(); - /// let second = Py::clone_ref(&first, py); + /// let first: PyDetached = PyDict::new(py).into(); + /// let second = PyDetached::clone_ref(&first, py); /// /// // Both point to the same object /// assert!(first.is(&second)); @@ -765,8 +772,8 @@ impl Py { /// # } /// ``` #[inline] - pub fn clone_ref(&self, py: Python<'_>) -> Py { - unsafe { Py::from_borrowed_ptr(py, self.0.as_ptr()) } + pub fn clone_ref(&self, py: Python<'_>) -> PyDetached { + unsafe { PyDetached::from_borrowed_ptr(py, self.0.as_ptr()) } } /// Returns whether the object is considered to be None. @@ -814,10 +821,10 @@ impl Py { /// # Example: `intern!`ing the attribute name /// /// ``` - /// # use pyo3::{intern, pyfunction, types::PyModule, IntoPy, Py, Python, PyObject, PyResult}; + /// # use pyo3::{intern, pyfunction, types::PyModule, IntoPy, PyDetached, Python, PyObject, PyResult}; /// # /// #[pyfunction] - /// fn version(sys: Py, py: Python<'_>) -> PyResult { + /// fn version(sys: PyDetached, py: Python<'_>) -> PyResult { /// sys.getattr(py, intern!(py, "version")) /// } /// # @@ -828,7 +835,7 @@ impl Py { /// ``` pub fn getattr(&self, py: Python<'_>, attr_name: N) -> PyResult where - N: IntoPy>, + N: IntoPy>, { self.attach(py).as_any().getattr(attr_name).map(Into::into) } @@ -857,8 +864,8 @@ impl Py { /// ``` pub fn setattr(&self, py: Python<'_>, attr_name: N, value: V) -> PyResult<()> where - N: IntoPy>, - V: IntoPy>, + N: IntoPy>, + V: IntoPy>, { self.attach(py) .as_any() @@ -871,7 +878,7 @@ impl Py { pub fn call( &self, py: Python<'_>, - args: impl IntoPy>, + args: impl IntoPy>, kwargs: Option<&PyDict>, ) -> PyResult { self.attach(py).as_any().call(args, kwargs).map(Into::into) @@ -880,7 +887,11 @@ impl Py { /// Calls the object with only positional arguments. /// /// This is equivalent to the Python expression `self(*args)`. - pub fn call1(&self, py: Python<'_>, args: impl IntoPy>) -> PyResult { + pub fn call1( + &self, + py: Python<'_>, + args: impl IntoPy>, + ) -> PyResult { self.attach(py).as_any().call1(args).map(Into::into) } @@ -905,8 +916,8 @@ impl Py { kwargs: Option<&PyDict>, ) -> PyResult where - N: IntoPy>, - A: IntoPy>, + N: IntoPy>, + A: IntoPy>, { self.attach(py) .as_any() @@ -922,8 +933,8 @@ impl Py { /// macro can be used to intern `name`. pub fn call_method1(&self, py: Python<'_>, name: N, args: A) -> PyResult where - N: IntoPy>, - A: IntoPy>, + N: IntoPy>, + A: IntoPy>, { self.attach(py) .as_any() @@ -939,7 +950,7 @@ impl Py { /// macro can be used to intern `name`. pub fn call_method0(&self, py: Python<'_>, name: N) -> PyResult where - N: IntoPy>, + N: IntoPy>, { self.attach(py).as_any().call_method0(name).map(Into::into) } @@ -955,9 +966,9 @@ impl Py { /// # Panics /// Panics if `ptr` is null. #[inline] - pub unsafe fn from_owned_ptr(py: Python<'_>, ptr: *mut ffi::PyObject) -> Py { + pub unsafe fn from_owned_ptr(py: Python<'_>, ptr: *mut ffi::PyObject) -> PyDetached { match NonNull::new(ptr) { - Some(nonnull_ptr) => Py(nonnull_ptr, PhantomData), + Some(nonnull_ptr) => PyDetached(nonnull_ptr, PhantomData), None => crate::err::panic_after_error(py), } } @@ -972,9 +983,9 @@ impl Py { pub unsafe fn from_owned_ptr_or_err( py: Python<'_>, ptr: *mut ffi::PyObject, - ) -> PyResult> { + ) -> PyResult> { match NonNull::new(ptr) { - Some(nonnull_ptr) => Ok(Py(nonnull_ptr, PhantomData)), + Some(nonnull_ptr) => Ok(PyDetached(nonnull_ptr, PhantomData)), None => Err(PyErr::fetch(py)), } } @@ -987,7 +998,7 @@ impl Py { /// If non-null, `ptr` must be a pointer to a Python object of type T. #[inline] pub unsafe fn from_owned_ptr_or_opt(_py: Python<'_>, ptr: *mut ffi::PyObject) -> Option { - NonNull::new(ptr).map(|nonnull_ptr| Py(nonnull_ptr, PhantomData)) + NonNull::new(ptr).map(|nonnull_ptr| PyDetached(nonnull_ptr, PhantomData)) } /// Create a `Py` instance by creating a new reference from the given FFI pointer. @@ -998,7 +1009,7 @@ impl Py { /// # Panics /// Panics if `ptr` is null. #[inline] - pub unsafe fn from_borrowed_ptr(py: Python<'_>, ptr: *mut ffi::PyObject) -> Py { + pub unsafe fn from_borrowed_ptr(py: Python<'_>, ptr: *mut ffi::PyObject) -> PyDetached { match Self::from_borrowed_ptr_or_opt(py, ptr) { Some(slf) => slf, None => crate::err::panic_after_error(py), @@ -1032,7 +1043,7 @@ impl Py { ) -> Option { NonNull::new(ptr).map(|nonnull_ptr| { ffi::Py_INCREF(ptr); - Py(nonnull_ptr, PhantomData) + PyDetached(nonnull_ptr, PhantomData) }) } @@ -1054,15 +1065,15 @@ impl Py { } } -impl ToPyObject for Py { - /// Converts `Py` instance -> PyObject. +impl ToPyObject for PyDetached { + /// Converts `PyDetached` instance -> PyObject. fn to_object(&self, py: Python<'_>) -> PyObject { unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) } } } -impl IntoPy for Py { - /// Converts a `Py` instance to `PyObject`. +impl IntoPy for PyDetached { + /// Converts a `PyDetached` instance to `PyObject`. /// Consumes `self` without calling `Py_DECREF()`. #[inline] fn into_py(self, _py: Python<'_>) -> PyObject { @@ -1070,7 +1081,7 @@ impl IntoPy for Py { } } -impl IntoPy for &'_ Py { +impl IntoPy for &'_ PyDetached { #[inline] fn into_py(self, py: Python<'_>) -> PyObject { self.to_object(py) @@ -1078,14 +1089,14 @@ impl IntoPy for &'_ Py { } impl ToPyObject for Py2<'_, T> { - /// Converts `Py` instance -> PyObject. + /// Converts `PyDetached` instance -> PyObject. fn to_object(&self, py: Python<'_>) -> PyObject { unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) } } } impl IntoPy for Py2<'_, T> { - /// Converts a `Py` instance to `PyObject`. + /// Converts a `PyDetached` instance to `PyObject`. /// Consumes `self` without calling `Py_DECREF()`. #[inline] fn into_py(self, _py: Python<'_>) -> PyObject { @@ -1094,7 +1105,7 @@ impl IntoPy for Py2<'_, T> { } impl IntoPy for &Py2<'_, T> { - /// Converts a `Py` instance to `PyObject`. + /// Converts a `PyDetached` instance to `PyObject`. /// Consumes `self` without calling `Py_DECREF()`. #[inline] fn into_py(self, _py: Python<'_>) -> PyObject { @@ -1102,7 +1113,7 @@ impl IntoPy for &Py2<'_, T> { } } -unsafe impl crate::AsPyPointer for Py { +unsafe impl crate::AsPyPointer for PyDetached { /// Gets the underlying FFI pointer, returns a borrowed pointer. #[inline] fn as_ptr(&self) -> *mut ffi::PyObject { @@ -1112,7 +1123,7 @@ unsafe impl crate::AsPyPointer for Py { impl std::convert::From<&'_ PyAny> for PyObject { fn from(obj: &PyAny) -> Self { - unsafe { Py::from_borrowed_ptr(obj.py(), obj.as_ptr()) } + unsafe { PyDetached::from_borrowed_ptr(obj.py(), obj.as_ptr()) } } } @@ -1121,16 +1132,16 @@ where T: PyNativeType + AsRef, { fn from(obj: &T) -> Self { - unsafe { Py::from_borrowed_ptr(obj.py(), obj.as_ref().as_ptr()) } + unsafe { PyDetached::from_borrowed_ptr(obj.py(), obj.as_ref().as_ptr()) } } } -impl std::convert::From> for PyObject +impl std::convert::From> for PyObject where T: AsRef, { #[inline] - fn from(other: Py) -> Self { + fn from(other: PyDetached) -> Self { unsafe { Self::from_non_null(other.into_non_null()) } } } @@ -1146,7 +1157,7 @@ where } } -impl std::convert::From> for Py { +impl std::convert::From> for PyDetached { #[inline] fn from(other: Py2<'_, T>) -> Self { unsafe { Self::from_non_null(other.into_non_null()) } @@ -1154,37 +1165,37 @@ impl std::convert::From> for Py { } // `&PyCell` can be converted to `Py` -impl std::convert::From<&PyCell> for Py +impl std::convert::From<&PyCell> for PyDetached where T: PyClass, { fn from(cell: &PyCell) -> Self { - unsafe { Py::from_borrowed_ptr(cell.py(), cell.as_ptr()) } + unsafe { PyDetached::from_borrowed_ptr(cell.py(), cell.as_ptr()) } } } -impl<'a, T> std::convert::From> for Py +impl<'a, T> std::convert::From> for PyDetached where T: PyClass, { fn from(pyref: PyRef<'a, T>) -> Self { - unsafe { Py::from_borrowed_ptr(pyref.py(), pyref.as_ptr()) } + unsafe { PyDetached::from_borrowed_ptr(pyref.py(), pyref.as_ptr()) } } } -impl<'a, T> std::convert::From> for Py +impl<'a, T> std::convert::From> for PyDetached where T: PyClass, { fn from(pyref: PyRefMut<'a, T>) -> Self { - unsafe { Py::from_borrowed_ptr(pyref.py(), pyref.as_ptr()) } + unsafe { PyDetached::from_borrowed_ptr(pyref.py(), pyref.as_ptr()) } } } /// If the GIL is held this increments `self`'s reference count. -/// Otherwise this registers the [`Py`]`` instance to have its reference count +/// Otherwise this registers the [`PyDetached`]`` instance to have its reference count /// incremented the next time PyO3 acquires the GIL. -impl Clone for Py { +impl Clone for PyDetached { fn clone(&self) -> Self { unsafe { gil::register_incref(self.0); @@ -1193,8 +1204,8 @@ impl Clone for Py { } } -/// Dropping a `Py` instance decrements the reference count on the object by 1. -impl Drop for Py { +/// Dropping a `PyDetached` instance decrements the reference count on the object by 1. +impl Drop for PyDetached { fn drop(&mut self) { unsafe { gil::register_decref(self.0); @@ -1202,7 +1213,7 @@ impl Drop for Py { } } -impl<'a, T> FromPyObject<'a> for Py +impl<'a, T> FromPyObject<'a> for PyDetached where T: PyTypeInfo, &'a T::AsRefTarget: FromPyObject<'a>, @@ -1212,7 +1223,7 @@ where fn extract(ob: &'a PyAny) -> PyResult { unsafe { ob.extract::<&T::AsRefTarget>() - .map(|val| Py::from_borrowed_ptr(ob.py(), val.as_ptr())) + .map(|val| PyDetached::from_borrowed_ptr(ob.py(), val.as_ptr())) } } } @@ -1234,14 +1245,14 @@ where /// /// However for GIL lifetime reasons, cause() cannot be implemented for `Py`. /// Use .as_ref() to get the GIL-scoped error if you need to inspect the cause. -impl std::error::Error for Py +impl std::error::Error for PyDetached where T: std::error::Error + PyTypeInfo, T::AsRefTarget: std::fmt::Display, { } -impl std::fmt::Display for Py +impl std::fmt::Display for PyDetached where T: PyTypeInfo, T::AsRefTarget: std::fmt::Display, @@ -1251,7 +1262,7 @@ where } } -impl std::fmt::Debug for Py { +impl std::fmt::Debug for PyDetached { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("Py").field(&self.0.as_ptr()).finish() } @@ -1262,8 +1273,8 @@ impl std::fmt::Debug for Py { /// This is an owned reference a Python object without any type information. This value can also be /// safely sent between threads. /// -/// See the documentation for [`Py`](struct.Py.html). -pub type PyObject = Py; +/// See the documentation for [`PyDetached`](struct.Py.html). +pub type PyObject = PyDetached; impl PyObject { /// Downcast this `PyObject` to a concrete Python type or pyclass. @@ -1303,7 +1314,7 @@ impl PyObject { /// } /// /// Python::with_gil(|py| { - /// let class: PyObject = Py::new(py, Class { i: 0 }).unwrap().into_py(py); + /// let class: PyObject = PyDetached::new(py, Class { i: 0 }).unwrap().into_py(py); /// /// let class_cell: &PyCell = class.downcast(py)?; /// @@ -1340,7 +1351,7 @@ impl PyObject { #[cfg(test)] mod tests { - use super::{Py, Py2, PyObject}; + use super::{Py2, PyDetached, PyObject}; use crate::types::{PyDict, PyString}; use crate::{PyAny, PyResult, Python, ToPyObject}; @@ -1375,9 +1386,9 @@ mod tests { #[test] fn py_from_dict() { - let dict: Py = Python::with_gil(|py| { + let dict: PyDetached = Python::with_gil(|py| { let native = PyDict::new(py); - Py::from(native) + PyDetached::from(native) }); assert_eq!(Python::with_gil(|py| dict.get_refcnt(py)), 1); @@ -1386,7 +1397,7 @@ mod tests { #[test] fn pyobject_from_py() { Python::with_gil(|py| { - let dict: Py = PyDict::new(py).into(); + let dict: PyDetached = PyDict::new(py).into(); let cnt = dict.get_refcnt(py); let p: PyObject = dict.into(); assert_eq!(p.get_refcnt(py), cnt); @@ -1404,7 +1415,7 @@ class A: a = A() "#; let module = PyModule::from_code(py, CODE, "", "")?; - let instance: Py = module.getattr("a")?.into(); + let instance: PyDetached = module.getattr("a")?.into(); instance.getattr(py, "foo").unwrap_err(); @@ -1431,7 +1442,7 @@ class A: a = A() "#; let module = PyModule::from_code(py, CODE, "", "")?; - let instance: Py = module.getattr("a")?.into(); + let instance: PyDetached = module.getattr("a")?.into(); let foo = crate::intern!(py, "foo"); let bar = crate::intern!(py, "bar"); @@ -1446,7 +1457,7 @@ a = A() #[test] fn invalid_attr() -> PyResult<()> { Python::with_gil(|py| { - let instance: Py = py.eval("object()", None, None)?.into(); + let instance: PyDetached = py.eval("object()", None, None)?.into(); instance.getattr(py, "foo").unwrap_err(); @@ -1524,7 +1535,7 @@ a = A() fn instance_borrow_methods() { // More detailed tests of the underlying semantics in pycell.rs Python::with_gil(|py| { - let instance = Py::new(py, SomeClass(0)).unwrap(); + let instance = PyDetached::new(py, SomeClass(0)).unwrap(); assert_eq!(instance.borrow(py).0, 0); assert_eq!(instance.try_borrow(py).unwrap().0, 0); assert_eq!(instance.borrow_mut(py).0, 0); @@ -1543,7 +1554,7 @@ a = A() fn cell_tryfrom() { // More detailed tests of the underlying semantics in pycell.rs Python::with_gil(|py| { - let instance: &PyAny = Py::new(py, SomeClass(0)).unwrap().into_ref(py); + let instance: &PyAny = PyDetached::new(py, SomeClass(0)).unwrap().into_ref(py); let _: &PyCell = PyTryInto::try_into(instance).unwrap(); let _: &PyCell = PyTryInto::try_into_exact(instance).unwrap(); }) diff --git a/src/lib.rs b/src/lib.rs index 985ec0aa4ff..5bdaf1ef32f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,7 +41,7 @@ //! //! ## The GIL-independent types //! -//! When wrapped in [`Py`]`<...>`, like with [`Py`]`<`[`PyAny`]`>` or [`Py`]``, Python +//! When wrapped in [`PyDetached`]`<...>`, like with [`PyDetached`]`<`[`PyAny`]`>` or [`PyDetached`]``, Python //! objects no longer have a limited lifetime which makes them easier to store in structs and pass //! between functions. However, you cannot do much with them without a //! [`Python<'py>`](crate::Python) token, for which you’d need to reacquire the GIL. @@ -94,7 +94,7 @@ //! - [`rust_decimal`]: Enables conversions between Python's decimal.Decimal and [rust_decimal]'s //! [`Decimal`] type. //! - [`serde`]: Allows implementing [serde]'s [`Serialize`] and [`Deserialize`] traits for -//! [`Py`]`` for all `T` that implement [`Serialize`] and [`Deserialize`]. +//! [`PyDetached`]`` for all `T` that implement [`Serialize`] and [`Deserialize`]. //! - [`smallvec`][smallvec]: Enables conversions between Python list and [smallvec]'s [`SmallVec`]. //! //! ## Unstable features @@ -300,7 +300,7 @@ pub use crate::err::{PyDowncastError, PyErr, PyErrArguments, PyResult}; pub use crate::gil::GILPool; #[cfg(not(PyPy))] pub use crate::gil::{prepare_freethreaded_python, with_embedded_python_interpreter}; -pub use crate::instance::{Py, PyNativeType, PyObject}; +pub use crate::instance::{PyDetached, PyNativeType, PyObject}; pub use crate::marker::Python; pub use crate::pycell::{PyCell, PyRef, PyRefMut}; pub use crate::pyclass::PyClass; @@ -309,6 +309,9 @@ pub use crate::type_object::{PyTypeCheck, PyTypeInfo}; pub use crate::types::PyAny; pub use crate::version::PythonVersionInfo; +#[allow(deprecated)] +pub use crate::instance::Py; + // Expected to become public API in 0.21 under a different name pub(crate) use crate::instance::Py2; pub(crate) mod ffi_ptr_ext; diff --git a/src/marker.rs b/src/marker.rs index a6517fa1844..cf1727a56d0 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -105,8 +105,8 @@ //! impl !Ungil for Python<'_> {} //! impl !Ungil for ffi::PyObject {} //! -//! // `Py` wraps it in a safe api, so this is OK -//! unsafe impl Ungil for Py {} +//! // `PyDetached` wraps it in a safe api, so this is OK +//! unsafe impl Ungil for PyDetached {} //! # } //! ``` //! @@ -114,7 +114,7 @@ //! //! [`SendWrapper`]: https://docs.rs/send_wrapper/latest/send_wrapper/struct.SendWrapper.html //! [`Rc`]: std::rc::Rc -//! [`Py`]: crate::Py +//! [`PyDetached`]: crate::Py use crate::err::{self, PyDowncastError, PyErr, PyResult}; use crate::gil::{GILGuard, GILPool, SuspendGIL}; use crate::impl_::not_send::NotSend; @@ -123,7 +123,7 @@ use crate::types::{ PyAny, PyDict, PyEllipsis, PyModule, PyNone, PyNotImplemented, PyString, PyType, }; use crate::version::PythonVersionInfo; -use crate::{ffi, FromPyPointer, IntoPy, Py, PyObject, PyTypeCheck, PyTypeInfo}; +use crate::{ffi, FromPyPointer, IntoPy, PyDetached, PyObject, PyTypeCheck, PyTypeInfo}; use std::ffi::{CStr, CString}; use std::marker::PhantomData; use std::os::raw::c_int; @@ -378,7 +378,7 @@ pub use nightly::Ungil; /// [`GILPool`] to manage memory. /// /// [scoping rules]: https://doc.rust-lang.org/stable/book/ch04-01-what-is-ownership.html#ownership-rules -/// [`Py::clone_ref`]: crate::Py::clone_ref +/// [`Py::clone_ref`]: crate::PyDetached::clone_ref /// [Memory Management]: https://pyo3.rs/main/memory.html#gil-bound-memory #[derive(Copy, Clone)] pub struct Python<'py>(PhantomData<(&'py GILGuard, NotSend)>); @@ -481,7 +481,7 @@ impl<'py> Python<'py> { /// Only types that implement [`Ungil`] can cross the closure. See the /// [module level documentation](self) for more information. /// - /// If you need to pass Python objects into the closure you can use [`Py`]``to create a + /// If you need to pass Python objects into the closure you can use [`PyDetached`]``to create a /// reference independent of the GIL lifetime. However, you cannot do much with those without a /// [`Python`] token, for which you'd need to reacquire the GIL. /// @@ -528,7 +528,7 @@ impl<'py> Python<'py> { /// } /// ``` /// - /// [`Py`]: crate::Py + /// [`PyDetached`]: crate::Py /// [`PyString`]: crate::types::PyString /// [auto-traits]: https://doc.rust-lang.org/nightly/unstable-book/language-features/auto-traits.html /// [Parallelism]: https://pyo3.rs/main/parallelism.html @@ -690,7 +690,7 @@ impl<'py> Python<'py> { /// Imports the Python module with the specified name. pub fn import(self, name: N) -> PyResult<&'py PyModule> where - N: IntoPy>, + N: IntoPy>, { PyModule::import(self, name) } @@ -1065,7 +1065,7 @@ impl<'unbound> Python<'unbound> { mod tests { use super::*; use crate::types::{IntoPyDict, PyDict, PyList}; - use crate::Py; + use crate::PyDetached; use std::sync::Arc; #[test] @@ -1154,7 +1154,7 @@ mod tests { #[test] fn test_allow_threads_pass_stuff_in() { - let list: Py = Python::with_gil(|py| { + let list: PyDetached = Python::with_gil(|py| { let list = PyList::new(py, vec!["foo", "bar"]); list.into() }); diff --git a/src/prelude.rs b/src/prelude.rs index 28a6e835a3c..6e89f16b44e 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -11,12 +11,15 @@ pub use crate::conversion::{FromPyObject, IntoPy, ToPyObject}; pub use crate::conversion::{PyTryFrom, PyTryInto}; pub use crate::err::{PyErr, PyResult}; -pub use crate::instance::{Py, PyObject}; +pub use crate::instance::{PyDetached, PyObject}; pub use crate::marker::Python; pub use crate::pycell::{PyCell, PyRef, PyRefMut}; pub use crate::pyclass_init::PyClassInitializer; pub use crate::types::{PyAny, PyModule}; +#[allow(deprecated)] +pub use crate::Py; + #[cfg(feature = "macros")] pub use pyo3_macros::{pyclass, pyfunction, pymethods, pymodule, FromPyObject}; diff --git a/src/pycell.rs b/src/pycell.rs index 3bc80a7eb07..cdd6efde20d 100644 --- a/src/pycell.rs +++ b/src/pycell.rs @@ -92,7 +92,7 @@ //! # } //! # fn main() -> PyResult<()> { //! Python::with_gil(|py| { -//! let n = Py::new(py, Number { inner: 0 })?; +//! let n = PyDetached::new(py, Number { inner: 0 })?; //! //! // We borrow the guard and then dereference //! // it to get a mutable reference to Number @@ -128,7 +128,7 @@ //! } //! # fn main() { //! # Python::with_gil(|py| { -//! # let n = Py::new(py, Number{inner: 35}).unwrap(); +//! # let n = PyDetached::new(py, Number{inner: 35}).unwrap(); //! # let n2 = n.clone_ref(py); //! # assert!(n.is(&n2)); //! # let fun = pyo3::wrap_pyfunction!(swap_numbers, py).unwrap(); @@ -165,7 +165,7 @@ //! # fn main() { //! # // With duplicate numbers //! # Python::with_gil(|py| { -//! # let n = Py::new(py, Number{inner: 35}).unwrap(); +//! # let n = PyDetached::new(py, Number{inner: 35}).unwrap(); //! # let n2 = n.clone_ref(py); //! # assert!(n.is(&n2)); //! # let fun = pyo3::wrap_pyfunction!(swap_numbers, py).unwrap(); @@ -174,8 +174,8 @@ //! # //! # // With two different numbers //! # Python::with_gil(|py| { -//! # let n = Py::new(py, Number{inner: 35}).unwrap(); -//! # let n2 = Py::new(py, Number{inner: 42}).unwrap(); +//! # let n = PyDetached::new(py, Number{inner: 35}).unwrap(); +//! # let n2 = PyDetached::new(py, Number{inner: 42}).unwrap(); //! # assert!(!n.is(&n2)); //! # let fun = pyo3::wrap_pyfunction!(swap_numbers, py).unwrap(); //! # fun.call1((&n, &n2)).unwrap(); @@ -283,7 +283,7 @@ impl PyCell { /// Makes a new `PyCell` on the Python heap and return the reference to it. /// /// In cases where the value in the cell does not need to be accessed immediately after - /// creation, consider [`Py::new`](crate::Py::new) as a more efficient alternative. + /// creation, consider [`Py::new`](crate::PyDetached::new) as a more efficient alternative. pub fn new(py: Python<'_>, value: impl Into>) -> PyResult<&Self> { unsafe { let initializer = value.into(); diff --git a/src/pycell/impl_.rs b/src/pycell/impl_.rs index 62875e67ae4..8ce555c8bd3 100644 --- a/src/pycell/impl_.rs +++ b/src/pycell/impl_.rs @@ -276,7 +276,7 @@ mod tests { #[test] fn test_mutable_borrow_prevents_further_borrows() { Python::with_gil(|py| { - let mmm = Py::new( + let mmm = PyDetached::new( py, PyClassInitializer::from(MutableBase) .add_subclass(MutableChildOfMutableBase) @@ -327,7 +327,7 @@ mod tests { #[test] fn test_immutable_borrows_prevent_mutable_borrows() { Python::with_gil(|py| { - let mmm = Py::new( + let mmm = PyDetached::new( py, PyClassInitializer::from(MutableBase) .add_subclass(MutableChildOfMutableBase) diff --git a/src/pyclass/create_type_object.rs b/src/pyclass/create_type_object.rs index a7196f30288..7d0a322b421 100644 --- a/src/pyclass/create_type_object.rs +++ b/src/pyclass/create_type_object.rs @@ -12,7 +12,8 @@ use crate::{ trampoline::trampoline, }, types::PyType, - Py, PyCell, PyClass, PyGetterDef, PyMethodDefType, PyResult, PySetterDef, PyTypeInfo, Python, + PyCell, PyClass, PyDetached, PyGetterDef, PyMethodDefType, PyResult, PySetterDef, PyTypeInfo, + Python, }; use std::{ borrow::Cow, @@ -24,7 +25,7 @@ use std::{ }; pub(crate) struct PyClassTypeObject { - pub type_object: Py, + pub type_object: PyDetached, #[allow(dead_code)] // This is purely a cache that must live as long as the type object getset_destructors: Vec, } @@ -428,8 +429,8 @@ impl PyTypeBuilder { }; // Safety: We've correctly setup the PyType_Spec at this point - let type_object: Py = - unsafe { Py::from_owned_ptr_or_err(py, ffi::PyType_FromSpec(&mut spec))? }; + let type_object: PyDetached = + unsafe { PyDetached::from_owned_ptr_or_err(py, ffi::PyType_FromSpec(&mut spec))? }; #[cfg(not(Py_3_11))] bpo_45315_workaround(py, class_name); diff --git a/src/pyclass_init.rs b/src/pyclass_init.rs index 63761f435bb..5964ae899e6 100644 --- a/src/pyclass_init.rs +++ b/src/pyclass_init.rs @@ -1,7 +1,7 @@ //! Contains initialization utilities for `#[pyclass]`. use crate::callback::IntoPyCallbackOutput; use crate::impl_::pyclass::{PyClassBaseType, PyClassDict, PyClassThreadChecker, PyClassWeakRef}; -use crate::{ffi, Py, PyCell, PyClass, PyErr, PyResult, Python}; +use crate::{ffi, PyCell, PyClass, PyDetached, PyErr, PyResult, Python}; use crate::{ ffi::PyTypeObject, pycell::{ @@ -137,7 +137,7 @@ impl PyObjectInit for PyNativeTypeInitializer { pub struct PyClassInitializer(PyClassInitializerImpl); enum PyClassInitializerImpl { - Existing(Py), + Existing(PyDetached), New { init: T, super_init: ::Initializer, @@ -294,9 +294,9 @@ where } } -impl From> for PyClassInitializer { +impl From> for PyClassInitializer { #[inline] - fn from(value: Py) -> PyClassInitializer { + fn from(value: PyDetached) -> PyClassInitializer { PyClassInitializer(PyClassInitializerImpl::Existing(value)) } } diff --git a/src/sync.rs b/src/sync.rs index 91a83106798..f33bbbe4a20 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -1,5 +1,5 @@ //! Synchronization mechanisms based on the Python GIL. -use crate::{types::PyString, types::PyType, Py, PyErr, PyVisit, Python}; +use crate::{types::PyString, types::PyType, PyDetached, PyErr, PyVisit, Python}; use std::cell::UnsafeCell; /// Value with concurrent access protected by the GIL. @@ -73,7 +73,7 @@ unsafe impl Sync for GILProtected where T: Send {} /// use pyo3::prelude::*; /// use pyo3::types::PyList; /// -/// static LIST_CELL: GILOnceCell> = GILOnceCell::new(); +/// static LIST_CELL: GILOnceCell> = GILOnceCell::new(); /// /// pub fn get_shared_list(py: Python<'_>) -> &PyList { /// LIST_CELL @@ -187,7 +187,7 @@ impl GILOnceCell { } } -impl GILOnceCell> { +impl GILOnceCell> { /// Get a reference to the contained Python type, initializing it if needed. /// /// This is a shorthand method for `get_or_init` which imports the type from Python on init. @@ -249,7 +249,7 @@ macro_rules! intern { /// Implementation detail for `intern!` macro. #[doc(hidden)] -pub struct Interned(&'static str, GILOnceCell>); +pub struct Interned(&'static str, GILOnceCell>); impl Interned { /// Creates an empty holder for an interned `str`. diff --git a/src/tests/common.rs b/src/tests/common.rs index bc5a33d5cdd..7bca8effb9f 100644 --- a/src/tests/common.rs +++ b/src/tests/common.rs @@ -75,11 +75,11 @@ mod inner { #[cfg(all(feature = "macros", Py_3_8))] impl UnraisableCapture { - pub fn install(py: Python<'_>) -> Py { + pub fn install(py: Python<'_>) -> PyDetached { let sys = py.import("sys").unwrap(); let old_hook = sys.getattr("unraisablehook").unwrap().into(); - let capture = Py::new( + let capture = PyDetached::new( py, UnraisableCapture { capture: None, diff --git a/src/tests/hygiene/pyclass.rs b/src/tests/hygiene/pyclass.rs index 4d07009cad6..162d4321952 100644 --- a/src/tests/hygiene/pyclass.rs +++ b/src/tests/hygiene/pyclass.rs @@ -26,7 +26,7 @@ pub struct Bar { #[pyo3(get, set)] b: Foo, #[pyo3(get, set)] - c: ::std::option::Option>, + c: ::std::option::Option>, } #[crate::pyclass] diff --git a/src/tests/hygiene/pymethods.rs b/src/tests/hygiene/pymethods.rs index 8e5bce8eefe..970d90675dc 100644 --- a/src/tests/hygiene/pymethods.rs +++ b/src/tests/hygiene/pymethods.rs @@ -114,8 +114,11 @@ impl Dummy { fn __delitem__(&self, key: u32) {} - fn __iter__(_: crate::pycell::PyRef<'_, Self>, py: crate::Python<'_>) -> crate::Py { - crate::Py::new(py, DummyIter {}).unwrap() + fn __iter__( + _: crate::pycell::PyRef<'_, Self>, + py: crate::Python<'_>, + ) -> crate::PyDetached { + crate::PyDetached::new(py, DummyIter {}).unwrap() } fn __next__(&mut self) -> ::std::option::Option<()> { @@ -125,8 +128,8 @@ impl Dummy { fn __reversed__( slf: crate::pycell::PyRef<'_, Self>, py: crate::Python<'_>, - ) -> crate::Py { - crate::Py::new(py, DummyIter {}).unwrap() + ) -> crate::PyDetached { + crate::PyDetached::new(py, DummyIter {}).unwrap() } fn __contains__(&self, item: u32) -> bool { @@ -343,8 +346,8 @@ impl Dummy { fn __aiter__( slf: crate::pycell::PyRef<'_, Self>, py: crate::Python<'_>, - ) -> crate::Py { - crate::Py::new(py, DummyIter {}).unwrap() + ) -> crate::PyDetached { + crate::PyDetached::new(py, DummyIter {}).unwrap() } fn __anext__(&mut self) -> ::std::option::Option<()> { @@ -507,8 +510,11 @@ impl Dummy { fn __delitem__(&self, key: u32) {} - fn __iter__(_: crate::pycell::PyRef<'_, Self>, py: crate::Python<'_>) -> crate::Py { - crate::Py::new(py, DummyIter {}).unwrap() + fn __iter__( + _: crate::pycell::PyRef<'_, Self>, + py: crate::Python<'_>, + ) -> crate::PyDetached { + crate::PyDetached::new(py, DummyIter {}).unwrap() } fn __next__(&mut self) -> ::std::option::Option<()> { @@ -518,8 +524,8 @@ impl Dummy { fn __reversed__( slf: crate::pycell::PyRef<'_, Self>, py: crate::Python<'_>, - ) -> crate::Py { - crate::Py::new(py, DummyIter {}).unwrap() + ) -> crate::PyDetached { + crate::PyDetached::new(py, DummyIter {}).unwrap() } fn __contains__(&self, item: u32) -> bool { @@ -735,8 +741,8 @@ impl Dummy { fn __aiter__( slf: crate::pycell::PyRef<'_, Self>, py: crate::Python<'_>, - ) -> crate::Py { - crate::Py::new(py, DummyIter {}).unwrap() + ) -> crate::PyDetached { + crate::PyDetached::new(py, DummyIter {}).unwrap() } fn __anext__(&mut self) -> ::std::option::Option<()> { diff --git a/src/type_object.rs b/src/type_object.rs index 428de86accf..f3cc90be13f 100644 --- a/src/type_object.rs +++ b/src/type_object.rs @@ -29,7 +29,7 @@ pub trait PySizedLayout: PyLayout + Sized {} /// - `Py::as_ref` will hand out references to `Self::AsRefTarget`. /// - `Self::AsRefTarget` must have the same layout as `UnsafeCell`. pub unsafe trait HasPyGilRef { - /// Utility type to make Py::as_ref work. + /// Utility type to make PyDetached::as_ref work. type AsRefTarget: PyNativeType; } diff --git a/src/types/any.rs b/src/types/any.rs index 23548265c54..a6a4d6d9b18 100644 --- a/src/types/any.rs +++ b/src/types/any.rs @@ -9,7 +9,7 @@ use crate::type_object::{HasPyGilRef, PyTypeCheck, PyTypeInfo}; #[cfg(not(PyPy))] use crate::types::PySuper; use crate::types::{PyDict, PyIterator, PyList, PyString, PyTuple, PyType}; -use crate::{err, ffi, Py, PyNativeType, Python}; +use crate::{err, ffi, PyDetached, PyNativeType, Python}; use std::cell::UnsafeCell; use std::cmp::Ordering; use std::os::raw::c_int; @@ -27,8 +27,8 @@ use std::os::raw::c_int; /// - It can't be used in situations where the GIL is temporarily released, /// such as [`Python::allow_threads`](crate::Python::allow_threads)'s closure. /// - The underlying Python object, if mutable, can be mutated through any reference. -/// - It can be converted to the GIL-independent [`Py`]`<`[`PyAny`]`>`, -/// allowing it to outlive the GIL scope. However, using [`Py`]`<`[`PyAny`]`>`'s API +/// - It can be converted to the GIL-independent [`PyDetached`]`<`[`PyAny`]`>`, +/// allowing it to outlive the GIL scope. However, using [`PyDetached`]`<`[`PyAny`]`>`'s API /// *does* require a [`Python<'py>`](crate::Python) token. /// /// It can be cast to a concrete type with PyAny::downcast (for native Python types only) @@ -100,7 +100,7 @@ impl PyAny { /// ``` pub fn hasattr(&self, attr_name: N) -> PyResult where - N: IntoPy>, + N: IntoPy>, { Py2::borrowed_from_gil_ref(&self).hasattr(attr_name) } @@ -129,7 +129,7 @@ impl PyAny { /// ``` pub fn getattr(&self, attr_name: N) -> PyResult<&PyAny> where - N: IntoPy>, + N: IntoPy>, { Py2::borrowed_from_gil_ref(&self) .getattr(attr_name) @@ -149,7 +149,7 @@ impl PyAny { #[allow(dead_code)] // Currently only used with num-complex+abi3, so dead without that. pub(crate) fn lookup_special(&self, attr_name: N) -> PyResult> where - N: IntoPy>, + N: IntoPy>, { let py = self.py(); let self_type = self.get_type(); @@ -205,7 +205,7 @@ impl PyAny { /// ``` pub fn setattr(&self, attr_name: N, value: V) -> PyResult<()> where - N: IntoPy>, + N: IntoPy>, V: ToPyObject, { Py2::borrowed_from_gil_ref(&self).setattr(attr_name, value) @@ -219,7 +219,7 @@ impl PyAny { /// to intern `attr_name`. pub fn delattr(&self, attr_name: N) -> PyResult<()> where - N: IntoPy>, + N: IntoPy>, { Py2::borrowed_from_gil_ref(&self).delattr(attr_name) } @@ -443,7 +443,7 @@ impl PyAny { /// ``` pub fn call( &self, - args: impl IntoPy>, + args: impl IntoPy>, kwargs: Option<&PyDict>, ) -> PyResult<&PyAny> { Py2::borrowed_from_gil_ref(&self) @@ -504,7 +504,7 @@ impl PyAny { /// }) /// # } /// ``` - pub fn call1(&self, args: impl IntoPy>) -> PyResult<&PyAny> { + pub fn call1(&self, args: impl IntoPy>) -> PyResult<&PyAny> { Py2::borrowed_from_gil_ref(&self) .call1(args) .map(Py2::into_gil_ref) @@ -547,8 +547,8 @@ impl PyAny { /// ``` pub fn call_method(&self, name: N, args: A, kwargs: Option<&PyDict>) -> PyResult<&PyAny> where - N: IntoPy>, - A: IntoPy>, + N: IntoPy>, + A: IntoPy>, { Py2::borrowed_from_gil_ref(&self) .call_method(name, args, kwargs) @@ -588,7 +588,7 @@ impl PyAny { /// ``` pub fn call_method0(&self, name: N) -> PyResult<&PyAny> where - N: IntoPy>, + N: IntoPy>, { Py2::borrowed_from_gil_ref(&self) .call_method0(name) @@ -629,8 +629,8 @@ impl PyAny { /// ``` pub fn call_method1(&self, name: N, args: A) -> PyResult<&PyAny> where - N: IntoPy>, - A: IntoPy>, + N: IntoPy>, + A: IntoPy>, { Py2::borrowed_from_gil_ref(&self) .call_method1(name, args) @@ -762,7 +762,7 @@ impl PyAny { /// } /// /// Python::with_gil(|py| { - /// let class: &PyAny = Py::new(py, Class { i: 0 }).unwrap().into_ref(py); + /// let class: &PyAny = PyDetached::new(py, Class { i: 0 }).unwrap().into_ref(py); /// /// let class_cell: &PyCell = class.downcast()?; /// @@ -1021,7 +1021,7 @@ pub(crate) trait PyAnyMethods<'py> { /// ``` fn hasattr(&self, attr_name: N) -> PyResult where - N: IntoPy>; + N: IntoPy>; /// Retrieves an attribute value. /// @@ -1047,7 +1047,7 @@ pub(crate) trait PyAnyMethods<'py> { /// ``` fn getattr(&self, attr_name: N) -> PyResult> where - N: IntoPy>; + N: IntoPy>; /// Sets an attribute value. /// @@ -1073,7 +1073,7 @@ pub(crate) trait PyAnyMethods<'py> { /// ``` fn setattr(&self, attr_name: N, value: V) -> PyResult<()> where - N: IntoPy>, + N: IntoPy>, V: ToPyObject; /// Deletes an attribute. @@ -1084,7 +1084,7 @@ pub(crate) trait PyAnyMethods<'py> { /// to intern `attr_name`. fn delattr(&self, attr_name: N) -> PyResult<()> where - N: IntoPy>; + N: IntoPy>; /// Returns an [`Ordering`] between `self` and `other`. /// @@ -1277,7 +1277,7 @@ pub(crate) trait PyAnyMethods<'py> { /// ``` fn call( &self, - args: impl IntoPy>, + args: impl IntoPy>, kwargs: Option<&PyDict>, ) -> PyResult>; @@ -1330,7 +1330,7 @@ pub(crate) trait PyAnyMethods<'py> { /// }) /// # } /// ``` - fn call1(&self, args: impl IntoPy>) -> PyResult>; + fn call1(&self, args: impl IntoPy>) -> PyResult>; /// Calls a method on the object. /// @@ -1374,8 +1374,8 @@ pub(crate) trait PyAnyMethods<'py> { kwargs: Option<&PyDict>, ) -> PyResult> where - N: IntoPy>, - A: IntoPy>; + N: IntoPy>, + A: IntoPy>; /// Calls a method on the object without arguments. /// @@ -1410,7 +1410,7 @@ pub(crate) trait PyAnyMethods<'py> { /// ``` fn call_method0(&self, name: N) -> PyResult> where - N: IntoPy>; + N: IntoPy>; /// Calls a method on the object with only positional arguments. /// @@ -1446,8 +1446,8 @@ pub(crate) trait PyAnyMethods<'py> { /// ``` fn call_method1(&self, name: N, args: A) -> PyResult> where - N: IntoPy>, - A: IntoPy>; + N: IntoPy>, + A: IntoPy>; /// Returns whether the object is considered to be true. /// @@ -1542,7 +1542,7 @@ pub(crate) trait PyAnyMethods<'py> { /// } /// /// Python::with_gil(|py| { - /// let class: &PyAny = Py::new(py, Class { i: 0 }).unwrap().into_ref(py); + /// let class: &PyAny = PyDetached::new(py, Class { i: 0 }).unwrap().into_ref(py); /// /// let class_cell: &PyCell = class.downcast()?; /// @@ -1692,7 +1692,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { fn hasattr(&self, attr_name: N) -> PyResult where - N: IntoPy>, + N: IntoPy>, { // PyObject_HasAttr suppresses all exceptions, which was the behaviour of `hasattr` in Python 2. // Use an implementation which suppresses only AttributeError, which is consistent with `hasattr` in Python 3. @@ -1709,7 +1709,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { fn getattr(&self, attr_name: N) -> PyResult> where - N: IntoPy>, + N: IntoPy>, { fn inner<'py>( any: &Py2<'py, PyAny>, @@ -1727,7 +1727,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { fn setattr(&self, attr_name: N, value: V) -> PyResult<()> where - N: IntoPy>, + N: IntoPy>, V: ToPyObject, { fn inner( @@ -1750,7 +1750,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { fn delattr(&self, attr_name: N) -> PyResult<()> where - N: IntoPy>, + N: IntoPy>, { fn inner(any: &Py2<'_, PyAny>, attr_name: Py2<'_, PyString>) -> PyResult<()> { err::error_on_minusone(any.py(), unsafe { @@ -1865,7 +1865,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { fn call( &self, - args: impl IntoPy>, + args: impl IntoPy>, kwargs: Option<&PyDict>, ) -> PyResult> { fn inner<'py>( @@ -1903,7 +1903,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { } } - fn call1(&self, args: impl IntoPy>) -> PyResult> { + fn call1(&self, args: impl IntoPy>) -> PyResult> { self.call(args, None) } @@ -1914,8 +1914,8 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { kwargs: Option<&PyDict>, ) -> PyResult> where - N: IntoPy>, - A: IntoPy>, + N: IntoPy>, + A: IntoPy>, { self.getattr(name) .and_then(|method| method.call(args, kwargs)) @@ -1923,7 +1923,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { fn call_method0(&self, name: N) -> PyResult> where - N: IntoPy>, + N: IntoPy>, { cfg_if::cfg_if! { if #[cfg(all(Py_3_9, not(any(Py_LIMITED_API, PyPy))))] { @@ -1942,8 +1942,8 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { fn call_method1(&self, name: N, args: A) -> PyResult> where - N: IntoPy>, - A: IntoPy>, + N: IntoPy>, + A: IntoPy>, { self.call_method(name, args, None) } @@ -2362,7 +2362,7 @@ class SimpleClass: } Python::with_gil(|py| { - let obj = Py::new(py, GetattrFail).unwrap(); + let obj = PyDetached::new(py, GetattrFail).unwrap(); let obj = obj.as_ref(py).as_ref(); assert!(obj diff --git a/src/types/bytearray.rs b/src/types/bytearray.rs index e8873ccb727..fa455a7b59d 100644 --- a/src/types/bytearray.rs +++ b/src/types/bytearray.rs @@ -1,5 +1,5 @@ use crate::err::{PyErr, PyResult}; -use crate::{ffi, AsPyPointer, Py, PyAny, Python}; +use crate::{ffi, AsPyPointer, PyAny, PyDetached, Python}; use std::os::raw::c_char; use std::slice; @@ -51,7 +51,8 @@ impl PyByteArray { let pyptr = ffi::PyByteArray_FromStringAndSize(std::ptr::null(), len as ffi::Py_ssize_t); // Check for an allocation error and return it - let pypybytearray: Py = Py::from_owned_ptr_or_err(py, pyptr)?; + let pypybytearray: PyDetached = + PyDetached::from_owned_ptr_or_err(py, pyptr)?; let buffer: *mut u8 = ffi::PyByteArray_AsString(pyptr).cast(); debug_assert!(!buffer.is_null()); // Zero-initialise the uninitialised bytearray diff --git a/src/types/bytes.rs b/src/types/bytes.rs index 1df82d2bf08..085a3e34bc9 100644 --- a/src/types/bytes.rs +++ b/src/types/bytes.rs @@ -1,4 +1,4 @@ -use crate::{ffi, FromPyObject, IntoPy, Py, PyAny, PyResult, Python, ToPyObject}; +use crate::{ffi, FromPyObject, IntoPy, PyAny, PyDetached, PyResult, Python, ToPyObject}; use std::borrow::Cow; use std::ops::Index; use std::os::raw::c_char; @@ -57,7 +57,7 @@ impl PyBytes { unsafe { let pyptr = ffi::PyBytes_FromStringAndSize(std::ptr::null(), len as ffi::Py_ssize_t); // Check for an allocation error and return it - let pypybytes: Py = Py::from_owned_ptr_or_err(py, pyptr)?; + let pypybytes: PyDetached = PyDetached::from_owned_ptr_or_err(py, pyptr)?; let buffer: *mut u8 = ffi::PyBytes_AsString(pyptr).cast(); debug_assert!(!buffer.is_null()); // Zero-initialise the uninitialised bytestring @@ -97,7 +97,7 @@ impl PyBytes { } } -impl Py { +impl PyDetached { /// Gets the Python bytes as a byte slice. Because Python bytes are /// immutable, the result may be used for as long as the reference to /// `self` is held, including when the GIL is released. @@ -141,13 +141,13 @@ impl<'source> FromPyObject<'source> for Cow<'source, [u8]> { } impl ToPyObject for Cow<'_, [u8]> { - fn to_object(&self, py: Python<'_>) -> Py { + fn to_object(&self, py: Python<'_>) -> PyDetached { PyBytes::new(py, self.as_ref()).into() } } -impl IntoPy> for Cow<'_, [u8]> { - fn into_py(self, py: Python<'_>) -> Py { +impl IntoPy> for Cow<'_, [u8]> { + fn into_py(self, py: Python<'_>) -> PyDetached { self.to_object(py) } } diff --git a/src/types/capsule.rs b/src/types/capsule.rs index f97320eb474..d598c343695 100644 --- a/src/types/capsule.rs +++ b/src/types/capsule.rs @@ -309,7 +309,7 @@ mod tests { use libc::c_void; use crate::prelude::PyModule; - use crate::{types::PyCapsule, Py, PyResult, Python}; + use crate::{types::PyCapsule, PyDetached, PyResult, Python}; use std::ffi::CString; use std::sync::mpsc::{channel, Sender}; @@ -347,7 +347,7 @@ mod tests { x } - let cap: Py = Python::with_gil(|py| { + let cap: PyDetached = Python::with_gil(|py| { let name = CString::new("foo").unwrap(); let cap = PyCapsule::new(py, foo as fn(u32) -> u32, Some(name)).unwrap(); cap.into() @@ -408,7 +408,7 @@ mod tests { #[test] fn test_vec_storage() { - let cap: Py = Python::with_gil(|py| { + let cap: PyDetached = Python::with_gil(|py| { let name = CString::new("foo").unwrap(); let stuff: Vec = vec![1, 2, 3, 4]; @@ -427,7 +427,7 @@ mod tests { fn test_vec_context() { let context: Vec = vec![1, 2, 3, 4]; - let cap: Py = Python::with_gil(|py| { + let cap: PyDetached = Python::with_gil(|py| { let name = CString::new("foo").unwrap(); let cap = PyCapsule::new(py, 0, Some(name)).unwrap(); cap.set_context(Box::into_raw(Box::new(&context)) as _) diff --git a/src/types/datetime.rs b/src/types/datetime.rs index 1f9db92a877..e5bece6a5ec 100644 --- a/src/types/datetime.rs +++ b/src/types/datetime.rs @@ -21,7 +21,7 @@ use crate::ffi::{ }; use crate::instance::PyNativeType; use crate::types::PyTuple; -use crate::{AsPyPointer, IntoPy, Py, PyAny, Python}; +use crate::{AsPyPointer, IntoPy, PyAny, PyDetached, Python}; use std::os::raw::c_int; #[cfg(feature = "chrono")] use std::ptr; @@ -312,7 +312,7 @@ impl PyDateTime { timestamp: f64, tzinfo: Option<&PyTzInfo>, ) -> PyResult<&'p PyDateTime> { - let args: Py = (timestamp, tzinfo).into_py(py); + let args: PyDetached = (timestamp, tzinfo).into_py(py); // safety ensure API is loaded let _api = ensure_datetime_api(py); diff --git a/src/types/frozenset.rs b/src/types/frozenset.rs index bbcd7102fac..e7ce000045d 100644 --- a/src/types/frozenset.rs +++ b/src/types/frozenset.rs @@ -2,7 +2,7 @@ use crate::types::PyIterator; use crate::{ err::{self, PyErr, PyResult}, - Py, PyObject, + PyDetached, PyObject, }; use crate::{ffi, PyAny, Python, ToPyObject}; @@ -201,14 +201,14 @@ pub use impl_::*; pub(crate) fn new_from_iter( py: Python<'_>, elements: impl IntoIterator, -) -> PyResult> { +) -> PyResult> { fn inner( py: Python<'_>, elements: &mut dyn Iterator, - ) -> PyResult> { - let set: Py = unsafe { - // We create the `Py` pointer because its Drop cleans up the set if user code panics. - Py::from_owned_ptr_or_err(py, ffi::PyFrozenSet_New(std::ptr::null_mut()))? + ) -> PyResult> { + let set: PyDetached = unsafe { + // We create the `PyDetached` pointer because its Drop cleans up the set if user code panics. + PyDetached::from_owned_ptr_or_err(py, ffi::PyFrozenSet_New(std::ptr::null_mut()))? }; let ptr = set.as_ptr(); diff --git a/src/types/function.rs b/src/types/function.rs index b4492b58c65..9f9c33a55e2 100644 --- a/src/types/function.rs +++ b/src/types/function.rs @@ -108,7 +108,7 @@ impl PyCFunction { py_or_module: PyFunctionArguments<'py>, ) -> PyResult<&'py Self> { let (py, module) = py_or_module.into_py_and_maybe_module(); - let (mod_ptr, module_name): (_, Option>) = if let Some(m) = module { + let (mod_ptr, module_name): (_, Option>) = if let Some(m) = module { let mod_ptr = m.as_ptr(); (mod_ptr, Some(m.name()?.into_py(py))) } else { @@ -122,7 +122,7 @@ impl PyCFunction { let module_name_ptr = module_name .as_ref() - .map_or(std::ptr::null_mut(), Py::as_ptr); + .map_or(std::ptr::null_mut(), PyDetached::as_ptr); unsafe { py.from_owned_ptr_or_err::(ffi::PyCFunction_NewEx( diff --git a/src/types/iterator.rs b/src/types/iterator.rs index 13c4e4bab43..1b663d852ba 100644 --- a/src/types/iterator.rs +++ b/src/types/iterator.rs @@ -108,7 +108,7 @@ mod tests { use crate::exceptions::PyTypeError; use crate::gil::GILPool; use crate::types::{PyDict, PyList}; - use crate::{Py, PyAny, Python, ToPyObject}; + use crate::{PyAny, PyDetached, Python, ToPyObject}; #[test] fn vec_iter() { @@ -218,7 +218,8 @@ def fibonacci(target): fn iterator_try_from() { Python::with_gil(|py| { - let obj: Py = vec![10, 20].to_object(py).as_ref(py).iter().unwrap().into(); + let obj: PyDetached = + vec![10, 20].to_object(py).as_ref(py).iter().unwrap().into(); let iter: &PyIterator = obj.downcast(py).unwrap(); assert!(obj.is(iter)); }); @@ -243,7 +244,7 @@ def fibonacci(target): // Regression test for 2913 Python::with_gil(|py| { - let downcaster = Py::new(py, Downcaster { failed: None }).unwrap(); + let downcaster = PyDetached::new(py, Downcaster { failed: None }).unwrap(); crate::py_run!( py, downcaster, diff --git a/src/types/list.rs b/src/types/list.rs index 71261ba6baa..f2c8c552b46 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -5,7 +5,7 @@ use crate::err::{self, PyResult}; use crate::ffi::{self, Py_ssize_t}; use crate::internal_tricks::get_ssize_index; use crate::types::{PySequence, PyTuple}; -use crate::{Py, PyAny, PyObject, Python, ToPyObject}; +use crate::{PyAny, PyDetached, PyObject, Python, ToPyObject}; /// Represents a Python `list`. #[repr(transparent)] @@ -18,7 +18,7 @@ pyobject_native_type_core!(PyList, pyobject_native_static_type_object!(ffi::PyLi pub(crate) fn new_from_iter( py: Python<'_>, elements: &mut dyn ExactSizeIterator, -) -> Py { +) -> PyDetached { unsafe { // PyList_New checks for overflow but has a bad error message, so we check ourselves let len: Py_ssize_t = elements @@ -28,10 +28,10 @@ pub(crate) fn new_from_iter( let ptr = ffi::PyList_New(len); - // We create the `Py` pointer here for two reasons: + // We create the `PyDetached` pointer here for two reasons: // - panics if the ptr is null // - its Drop cleans up the list if user code or the asserts panic. - let list: Py = Py::from_owned_ptr(py, ptr); + let list: PyDetached = PyDetached::from_owned_ptr(py, ptr); let mut counter: Py_ssize_t = 0; @@ -857,7 +857,7 @@ mod tests { #[cfg(feature = "macros")] #[test] fn bad_clone_mem_leaks() { - use crate::{Py, PyAny}; + use crate::{PyAny, PyDetached}; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; static NEEDS_DESTRUCTING_COUNT: AtomicUsize = AtomicUsize::new(0); @@ -882,7 +882,7 @@ mod tests { } impl ToPyObject for Bad { - fn to_object(&self, py: Python<'_>) -> Py { + fn to_object(&self, py: Python<'_>) -> PyDetached { self.to_owned().into_py(py) } } diff --git a/src/types/mapping.rs b/src/types/mapping.rs index e837ef911e9..06d3bb87cf8 100644 --- a/src/types/mapping.rs +++ b/src/types/mapping.rs @@ -2,7 +2,7 @@ use crate::err::{PyDowncastError, PyResult}; use crate::sync::GILOnceCell; use crate::type_object::PyTypeInfo; use crate::types::{PyAny, PyDict, PySequence, PyType}; -use crate::{ffi, Py, PyNativeType, PyTypeCheck, Python, ToPyObject}; +use crate::{ffi, PyDetached, PyNativeType, PyTypeCheck, Python, ToPyObject}; /// Represents a reference to a Python object supporting the mapping protocol. #[repr(transparent)] @@ -110,7 +110,7 @@ impl PyMapping { } } -static MAPPING_ABC: GILOnceCell> = GILOnceCell::new(); +static MAPPING_ABC: GILOnceCell> = GILOnceCell::new(); fn get_mapping_abc(py: Python<'_>) -> PyResult<&PyType> { MAPPING_ABC diff --git a/src/types/mod.rs b/src/types/mod.rs index 0174edc7be8..0760e2e2fb3 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -158,18 +158,18 @@ macro_rules! pyobject_native_type_named ( } } - impl<$($generics,)*> $crate::IntoPy<$crate::Py<$name>> for &'_ $name { + impl<$($generics,)*> $crate::IntoPy<$crate::PyDetached<$name>> for &'_ $name { #[inline] - fn into_py(self, py: $crate::Python<'_>) -> $crate::Py<$name> { - unsafe { $crate::Py::from_borrowed_ptr(py, self.as_ptr()) } + fn into_py(self, py: $crate::Python<'_>) -> $crate::PyDetached<$name> { + unsafe { $crate::PyDetached::from_borrowed_ptr(py, self.as_ptr()) } } } - impl<$($generics,)*> ::std::convert::From<&'_ $name> for $crate::Py<$name> { + impl<$($generics,)*> ::std::convert::From<&'_ $name> for $crate::PyDetached<$name> { #[inline] fn from(other: &$name) -> Self { use $crate::PyNativeType; - unsafe { $crate::Py::from_borrowed_ptr(other.py(), other.as_ptr()) } + unsafe { $crate::PyDetached::from_borrowed_ptr(other.py(), other.as_ptr()) } } } diff --git a/src/types/module.rs b/src/types/module.rs index 701a9131307..228cc73f7fb 100644 --- a/src/types/module.rs +++ b/src/types/module.rs @@ -4,7 +4,7 @@ use crate::exceptions; use crate::ffi; use crate::pyclass::PyClass; use crate::types::{PyAny, PyCFunction, PyDict, PyList, PyString}; -use crate::{IntoPy, Py, PyObject, Python}; +use crate::{IntoPy, PyDetached, PyObject, Python}; use std::ffi::{CStr, CString}; use std::str; @@ -63,9 +63,9 @@ impl PyModule { /// ``` pub fn import(py: Python<'_>, name: N) -> PyResult<&PyModule> where - N: IntoPy>, + N: IntoPy>, { - let name: Py = name.into_py(py); + let name: PyDetached = name.into_py(py); unsafe { py.from_owned_ptr_or_err(ffi::PyImport_Import(name.as_ptr())) } } diff --git a/src/types/sequence.rs b/src/types/sequence.rs index e3b76c12152..6a99e4c69e0 100644 --- a/src/types/sequence.rs +++ b/src/types/sequence.rs @@ -9,7 +9,7 @@ use crate::py_result_ext::PyResultExt; use crate::sync::GILOnceCell; use crate::type_object::PyTypeInfo; use crate::types::{PyAny, PyList, PyString, PyTuple, PyType}; -use crate::{ffi, FromPyObject, Py, PyNativeType, PyTypeCheck, Python, ToPyObject}; +use crate::{ffi, FromPyObject, PyDetached, PyNativeType, PyTypeCheck, Python, ToPyObject}; /// Represents a reference to a Python object supporting the sequence protocol. #[repr(transparent)] @@ -523,7 +523,7 @@ where Ok(v) } -static SEQUENCE_ABC: GILOnceCell> = GILOnceCell::new(); +static SEQUENCE_ABC: GILOnceCell> = GILOnceCell::new(); fn get_sequence_abc(py: Python<'_>) -> PyResult<&PyType> { SEQUENCE_ABC diff --git a/src/types/set.rs b/src/types/set.rs index 68b89d656f3..a774cc4b5db 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -2,7 +2,7 @@ use crate::types::PyIterator; use crate::{ err::{self, PyErr, PyResult}, - Py, + PyDetached, }; use crate::{ffi, PyAny, PyObject, Python, ToPyObject}; use std::ptr; @@ -248,11 +248,14 @@ pub use impl_::*; pub(crate) fn new_from_iter( py: Python<'_>, elements: impl IntoIterator, -) -> PyResult> { - fn inner(py: Python<'_>, elements: &mut dyn Iterator) -> PyResult> { - let set: Py = unsafe { - // We create the `Py` pointer because its Drop cleans up the set if user code panics. - Py::from_owned_ptr_or_err(py, ffi::PySet_New(std::ptr::null_mut()))? +) -> PyResult> { + fn inner( + py: Python<'_>, + elements: &mut dyn Iterator, + ) -> PyResult> { + let set: PyDetached = unsafe { + // We create the `PyDetached` pointer because its Drop cleans up the set if user code panics. + PyDetached::from_owned_ptr_or_err(py, ffi::PySet_New(std::ptr::null_mut()))? }; let ptr = set.as_ptr(); diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 0165061a7a1..8abdf67bc3a 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -8,7 +8,8 @@ use crate::internal_tricks::get_ssize_index; use crate::types::PyList; use crate::types::PySequence; use crate::{ - exceptions, FromPyObject, IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject, + exceptions, FromPyObject, IntoPy, PyAny, PyDetached, PyErr, PyObject, PyResult, Python, + ToPyObject, }; #[inline] @@ -16,7 +17,7 @@ use crate::{ fn new_from_iter( py: Python<'_>, elements: &mut dyn ExactSizeIterator, -) -> Py { +) -> PyDetached { unsafe { // PyTuple_New checks for overflow but has a bad error message, so we check ourselves let len: Py_ssize_t = elements @@ -28,7 +29,7 @@ fn new_from_iter( // - Panics if the ptr is null // - Cleans up the tuple if `convert` or the asserts panic - let tup: Py = Py::from_owned_ptr(py, ptr); + let tup: PyDetached = PyDetached::from_owned_ptr(py, ptr); let mut counter: Py_ssize_t = 0; @@ -320,8 +321,8 @@ fn type_output() -> TypeInfo { } } - impl <$($T: IntoPy),+> IntoPy> for ($($T,)+) { - fn into_py(self, py: Python<'_>) -> Py { + impl <$($T: IntoPy),+> IntoPy> for ($($T,)+) { + fn into_py(self, py: Python<'_>) -> PyDetached { array_into_tuple(py, [$(self.$n.into_py(py)),+]) } @@ -353,10 +354,10 @@ fn type_input() -> TypeInfo { } }); -fn array_into_tuple(py: Python<'_>, array: [PyObject; N]) -> Py { +fn array_into_tuple(py: Python<'_>, array: [PyObject; N]) -> PyDetached { unsafe { let ptr = ffi::PyTuple_New(N.try_into().expect("0 < N <= 12")); - let tup = Py::from_owned_ptr(py, ptr); + let tup = PyDetached::from_owned_ptr(py, ptr); for (index, obj) in array.into_iter().enumerate() { #[cfg(not(any(Py_LIMITED_API, PyPy)))] ffi::PyTuple_SET_ITEM(ptr, index as ffi::Py_ssize_t, obj.into_ptr()); @@ -859,7 +860,7 @@ mod tests { #[cfg(feature = "macros")] #[test] fn bad_clone_mem_leaks() { - use crate::{IntoPy, Py}; + use crate::{IntoPy, PyDetached}; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; static NEEDS_DESTRUCTING_COUNT: AtomicUsize = AtomicUsize::new(0); @@ -885,7 +886,7 @@ mod tests { } impl ToPyObject for Bad { - fn to_object(&self, py: Python<'_>) -> Py { + fn to_object(&self, py: Python<'_>) -> PyDetached { self.to_owned().into_py(py) } } @@ -927,7 +928,7 @@ mod tests { #[cfg(feature = "macros")] #[test] fn bad_clone_mem_leaks_2() { - use crate::{IntoPy, Py}; + use crate::{IntoPy, PyDetached}; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; static NEEDS_DESTRUCTING_COUNT: AtomicUsize = AtomicUsize::new(0); @@ -953,7 +954,7 @@ mod tests { } impl ToPyObject for Bad { - fn to_object(&self, py: Python<'_>) -> Py { + fn to_object(&self, py: Python<'_>) -> PyDetached { self.to_owned().into_py(py) } } @@ -962,7 +963,7 @@ mod tests { NEEDS_DESTRUCTING_COUNT.store(4, SeqCst); Python::with_gil(|py| { std::panic::catch_unwind(|| { - let _tuple: Py = s.to_object(py); + let _tuple: PyDetached = s.to_object(py); }) .unwrap_err(); }); diff --git a/tests/test_buffer.rs b/tests/test_buffer.rs index 12d1756fd92..52ca97ef1ee 100644 --- a/tests/test_buffer.rs +++ b/tests/test_buffer.rs @@ -87,7 +87,7 @@ impl TestBufferErrors { #[test] fn test_get_buffer_errors() { Python::with_gil(|py| { - let instance = Py::new( + let instance = PyDetached::new( py, TestBufferErrors { buf: vec![0, 1, 2, 3], diff --git a/tests/test_buffer_protocol.rs b/tests/test_buffer_protocol.rs index 4d5dc69f942..bf60ba5cc89 100644 --- a/tests/test_buffer_protocol.rs +++ b/tests/test_buffer_protocol.rs @@ -49,7 +49,7 @@ fn test_buffer() { let drop_called = Arc::new(AtomicBool::new(false)); Python::with_gil(|py| { - let instance = Py::new( + let instance = PyDetached::new( py, TestBufferClass { vec: vec![b' ', b'2', b'3'], @@ -121,7 +121,7 @@ fn test_releasebuffer_unraisable_error() { Python::with_gil(|py| { let capture = UnraisableCapture::install(py); - let instance = Py::new(py, ReleaseBufferError {}).unwrap(); + let instance = PyDetached::new(py, ReleaseBufferError {}).unwrap(); let env = [("ob", instance.clone())].into_py_dict(py); assert!(capture.borrow(py).capture.is_none()); diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index 3ad1352748c..1c7b3e43bd7 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -42,7 +42,7 @@ fn test_bytearray_vec_conversion() { #[test] fn test_py_as_bytes() { - let pyobj: pyo3::Py = + let pyobj: pyo3::PyDetached = Python::with_gil(|py| pyo3::types::PyBytes::new(py, b"abc").into_py(py)); let data = Python::with_gil(|py| pyobj.as_bytes(py)); diff --git a/tests/test_class_attributes.rs b/tests/test_class_attributes.rs index 0ff0dd6d9d8..3b79c4a62ef 100644 --- a/tests/test_class_attributes.rs +++ b/tests/test_class_attributes.rs @@ -48,8 +48,8 @@ impl Foo { } #[classattr] - fn a_foo_with_py(py: Python<'_>) -> Py { - Py::new(py, Foo { x: 1 }).unwrap() + fn a_foo_with_py(py: Python<'_>) -> PyDetached { + PyDetached::new(py, Foo { x: 1 }).unwrap() } } diff --git a/tests/test_class_basics.rs b/tests/test_class_basics.rs index bbf37a2d66b..1d79851f427 100644 --- a/tests/test_class_basics.rs +++ b/tests/test_class_basics.rs @@ -230,7 +230,7 @@ impl UnsendableChild { fn test_unsendable() -> PyResult<()> { let obj = Python::with_gil(|py| -> PyResult<_> { - let obj: Py = PyType::new::(py).call1((5,))?.extract()?; + let obj: PyDetached = PyType::new::(py).call1((5,))?.extract()?; // Accessing the value inside this thread should not panic let caught_panic = @@ -312,7 +312,7 @@ impl ClassWithFromPyWithMethods { #[test] fn test_pymethods_from_py_with() { Python::with_gil(|py| { - let instance = Py::new(py, ClassWithFromPyWithMethods {}).unwrap(); + let instance = PyDetached::new(py, ClassWithFromPyWithMethods {}).unwrap(); py_run!( py, @@ -339,7 +339,7 @@ fn test_tuple_struct_class() { py_assert!(py, typeobj, "typeobj.__name__ == 'TupleClass'"); - let instance = Py::new(py, TupleClass(5)).unwrap(); + let instance = PyDetached::new(py, TupleClass(5)).unwrap(); py_run!( py, instance, @@ -522,7 +522,7 @@ fn access_frozen_class_without_gil() { value: AtomicUsize, } - let py_counter: Py = Python::with_gil(|py| { + let py_counter: PyDetached = Python::with_gil(|py| { let counter = FrozenCounter { value: AtomicUsize::new(0), }; @@ -564,7 +564,7 @@ fn drop_unsendable_elsewhere() { let dropped = Arc::new(AtomicBool::new(false)); - let unsendable = Py::new( + let unsendable = PyDetached::new( py, Unsendable { dropped: dropped.clone(), diff --git a/tests/test_class_conversion.rs b/tests/test_class_conversion.rs index 81a3d7bfbfd..223177ff3f2 100644 --- a/tests/test_class_conversion.rs +++ b/tests/test_class_conversion.rs @@ -18,7 +18,7 @@ fn test_cloneable_pyclass() { let c = Cloneable { x: 10 }; Python::with_gil(|py| { - let py_c = Py::new(py, c.clone()).unwrap().to_object(py); + let py_c = PyDetached::new(py, c.clone()).unwrap().to_object(py); let c2: Cloneable = py_c.extract(py).unwrap(); assert_eq!(c, c2); @@ -58,7 +58,7 @@ impl SubClass { #[pyclass] struct PolymorphicContainer { #[pyo3(get, set)] - inner: Py, + inner: PyDetached, } #[test] @@ -67,7 +67,7 @@ fn test_polymorphic_container_stores_base_class() { let p = PyCell::new( py, PolymorphicContainer { - inner: Py::new(py, BaseClass::default()).unwrap(), + inner: PyDetached::new(py, BaseClass::default()).unwrap(), }, ) .unwrap() @@ -83,7 +83,7 @@ fn test_polymorphic_container_stores_sub_class() { let p = PyCell::new( py, PolymorphicContainer { - inner: Py::new(py, BaseClass::default()).unwrap(), + inner: PyDetached::new(py, BaseClass::default()).unwrap(), }, ) .unwrap() @@ -110,7 +110,7 @@ fn test_polymorphic_container_does_not_accept_other_types() { let p = PyCell::new( py, PolymorphicContainer { - inner: Py::new(py, BaseClass::default()).unwrap(), + inner: PyDetached::new(py, BaseClass::default()).unwrap(), }, ) .unwrap() diff --git a/tests/test_class_new.rs b/tests/test_class_new.rs index 8cb426861db..a72c6237d9f 100644 --- a/tests/test_class_new.rs +++ b/tests/test_class_new.rs @@ -215,8 +215,8 @@ struct NewExisting { #[pymethods] impl NewExisting { #[new] - fn new(py: pyo3::Python<'_>, val: usize) -> pyo3::Py { - static PRE_BUILT: GILOnceCell<[pyo3::Py; 2]> = GILOnceCell::new(); + fn new(py: pyo3::Python<'_>, val: usize) -> pyo3::PyDetached { + static PRE_BUILT: GILOnceCell<[pyo3::PyDetached; 2]> = GILOnceCell::new(); let existing = PRE_BUILT.get_or_init(py, || { [ pyo3::PyCell::new(py, NewExisting { num: 0 }) diff --git a/tests/test_coroutine.rs b/tests/test_coroutine.rs index 8acea3ea3e8..dbba23ac9a0 100644 --- a/tests/test_coroutine.rs +++ b/tests/test_coroutine.rs @@ -48,9 +48,9 @@ fn test_coroutine_qualname() { Self } // TODO use &self when possible - async fn my_method(_self: Py) {} + async fn my_method(_self: PyDetached) {} #[classmethod] - async fn my_classmethod(_cls: Py) {} + async fn my_classmethod(_cls: PyDetached) {} #[staticmethod] async fn my_staticmethod() {} } @@ -256,7 +256,7 @@ fn test_async_method_receiver() { Python::with_gil(|gil| { let test = r#" import asyncio - + obj = Counter() coro1 = obj.get() coro2 = obj.get() diff --git a/tests/test_default_impls.rs b/tests/test_default_impls.rs index 526f88e8f82..12031d344ea 100644 --- a/tests/test_default_impls.rs +++ b/tests/test_default_impls.rs @@ -14,7 +14,7 @@ enum TestDefaultRepr { #[test] fn test_default_slot_exists() { Python::with_gil(|py| { - let test_object = Py::new(py, TestDefaultRepr::Var).unwrap(); + let test_object = PyDetached::new(py, TestDefaultRepr::Var).unwrap(); py_assert!( py, test_object, @@ -38,7 +38,7 @@ impl OverrideSlot { #[test] fn test_override_slot() { Python::with_gil(|py| { - let test_object = Py::new(py, OverrideSlot::Var).unwrap(); + let test_object = PyDetached::new(py, OverrideSlot::Var).unwrap(); py_assert!(py, test_object, "repr(test_object) == 'overridden'"); }) } diff --git a/tests/test_enum.rs b/tests/test_enum.rs index 33e94c241c7..8fc2069f4fe 100644 --- a/tests/test_enum.rs +++ b/tests/test_enum.rs @@ -17,7 +17,7 @@ pub enum MyEnum { fn test_enum_class_attr() { Python::with_gil(|py| { let my_enum = py.get_type::(); - let var = Py::new(py, MyEnum::Variant).unwrap(); + let var = PyDetached::new(py, MyEnum::Variant).unwrap(); py_assert!(py, my_enum var, "my_enum.Variant == var"); }) } @@ -55,9 +55,9 @@ fn test_enum_arg() { #[test] fn test_enum_eq_enum() { Python::with_gil(|py| { - let var1 = Py::new(py, MyEnum::Variant).unwrap(); - let var2 = Py::new(py, MyEnum::Variant).unwrap(); - let other_var = Py::new(py, MyEnum::OtherVariant).unwrap(); + let var1 = PyDetached::new(py, MyEnum::Variant).unwrap(); + let var2 = PyDetached::new(py, MyEnum::Variant).unwrap(); + let other_var = PyDetached::new(py, MyEnum::OtherVariant).unwrap(); py_assert!(py, var1 var2, "var1 == var2"); py_assert!(py, var1 other_var, "var1 != other_var"); py_assert!(py, var1 var2, "(var1 != var2) == False"); @@ -67,7 +67,7 @@ fn test_enum_eq_enum() { #[test] fn test_enum_eq_incomparable() { Python::with_gil(|py| { - let var1 = Py::new(py, MyEnum::Variant).unwrap(); + let var1 = PyDetached::new(py, MyEnum::Variant).unwrap(); py_assert!(py, var1, "(var1 == 'foo') == False"); py_assert!(py, var1, "(var1 != 'foo') == True"); }) @@ -84,8 +84,8 @@ fn test_custom_discriminant() { Python::with_gil(|py| { #[allow(non_snake_case)] let CustomDiscriminant = py.get_type::(); - let one = Py::new(py, CustomDiscriminant::One).unwrap(); - let two = Py::new(py, CustomDiscriminant::Two).unwrap(); + let one = PyDetached::new(py, CustomDiscriminant::One).unwrap(); + let two = PyDetached::new(py, CustomDiscriminant::Two).unwrap(); py_run!(py, CustomDiscriminant one two, r#" assert CustomDiscriminant.One == one assert CustomDiscriminant.Two == two @@ -97,9 +97,9 @@ fn test_custom_discriminant() { #[test] fn test_enum_to_int() { Python::with_gil(|py| { - let one = Py::new(py, CustomDiscriminant::One).unwrap(); + let one = PyDetached::new(py, CustomDiscriminant::One).unwrap(); py_assert!(py, one, "int(one) == 1"); - let v = Py::new(py, MyEnum::Variant).unwrap(); + let v = PyDetached::new(py, MyEnum::Variant).unwrap(); let v_value = MyEnum::Variant as isize; py_run!(py, v v_value, "int(v) == v_value"); }) @@ -108,7 +108,7 @@ fn test_enum_to_int() { #[test] fn test_enum_compare_int() { Python::with_gil(|py| { - let one = Py::new(py, CustomDiscriminant::One).unwrap(); + let one = PyDetached::new(py, CustomDiscriminant::One).unwrap(); py_run!( py, one, @@ -130,7 +130,7 @@ enum SmallEnum { #[test] fn test_enum_compare_int_no_throw_when_overflow() { Python::with_gil(|py| { - let v = Py::new(py, SmallEnum::V).unwrap(); + let v = PyDetached::new(py, SmallEnum::V).unwrap(); py_assert!(py, v, "v != 1<<30") }) } @@ -146,7 +146,7 @@ enum BigEnum { fn test_big_enum_no_overflow() { Python::with_gil(|py| { let usize_max = usize::MAX; - let v = Py::new(py, BigEnum::V).unwrap(); + let v = PyDetached::new(py, BigEnum::V).unwrap(); py_assert!(py, usize_max v, "v == usize_max"); py_assert!(py, usize_max v, "int(v) == usize_max"); }) @@ -172,7 +172,7 @@ pub enum RenameEnum { #[test] fn test_rename_enum_repr_correct() { Python::with_gil(|py| { - let var1 = Py::new(py, RenameEnum::Variant).unwrap(); + let var1 = PyDetached::new(py, RenameEnum::Variant).unwrap(); py_assert!(py, var1, "repr(var1) == 'MyEnum.Variant'"); }) } @@ -187,7 +187,7 @@ pub enum RenameVariantEnum { #[test] fn test_rename_variant_repr_correct() { Python::with_gil(|py| { - let var1 = Py::new(py, RenameVariantEnum::Variant).unwrap(); + let var1 = PyDetached::new(py, RenameVariantEnum::Variant).unwrap(); py_assert!(py, var1, "repr(var1) == 'RenameVariantEnum.VARIANT'"); }) } diff --git a/tests/test_field_cfg.rs b/tests/test_field_cfg.rs index bd671641e5b..207e6372c85 100644 --- a/tests/test_field_cfg.rs +++ b/tests/test_field_cfg.rs @@ -21,7 +21,7 @@ struct CfgClass { fn test_cfg() { Python::with_gil(|py| { let cfg = CfgClass { b: 3 }; - let py_cfg = Py::new(py, cfg).unwrap(); + let py_cfg = PyDetached::new(py, cfg).unwrap(); assert!(py_cfg.as_ref(py).getattr("a").is_err()); let b: u32 = py_cfg.as_ref(py).getattr("b").unwrap().extract().unwrap(); assert_eq!(b, 3); diff --git a/tests/test_frompyobject.rs b/tests/test_frompyobject.rs index 47e5ec53e92..3ed245cfa74 100644 --- a/tests/test_frompyobject.rs +++ b/tests/test_frompyobject.rs @@ -57,7 +57,7 @@ fn test_named_fields_struct() { s: "foo".into(), foo: None, }; - let py_c = Py::new(py, pya).unwrap(); + let py_c = PyDetached::new(py, pya).unwrap(); let a: A<'_> = FromPyObject::extract(py_c.as_ref(py)).expect("Failed to extract A from PyA"); assert_eq!(a.s, "foo"); diff --git a/tests/test_gc.rs b/tests/test_gc.rs index 8fd4622f65e..51ffe7e4478 100644 --- a/tests/test_gc.rs +++ b/tests/test_gc.rs @@ -17,18 +17,18 @@ struct ClassWithFreelist {} #[test] fn class_with_freelist() { let ptr = Python::with_gil(|py| { - let inst = Py::new(py, ClassWithFreelist {}).unwrap(); - let _inst2 = Py::new(py, ClassWithFreelist {}).unwrap(); + let inst = PyDetached::new(py, ClassWithFreelist {}).unwrap(); + let _inst2 = PyDetached::new(py, ClassWithFreelist {}).unwrap(); let ptr = inst.as_ptr(); drop(inst); ptr }); Python::with_gil(|py| { - let inst3 = Py::new(py, ClassWithFreelist {}).unwrap(); + let inst3 = PyDetached::new(py, ClassWithFreelist {}).unwrap(); assert_eq!(ptr, inst3.as_ptr()); - let inst4 = Py::new(py, ClassWithFreelist {}).unwrap(); + let inst4 = PyDetached::new(py, ClassWithFreelist {}).unwrap(); assert_ne!(ptr, inst4.as_ptr()) }); } @@ -64,7 +64,7 @@ fn data_is_dropped() { drop_called: Arc::clone(&drop_called2), }, }; - let inst = Py::new(py, data_is_dropped).unwrap(); + let inst = PyDetached::new(py, data_is_dropped).unwrap(); assert!(!drop_called1.load(Ordering::Relaxed)); assert!(!drop_called2.load(Ordering::Relaxed)); drop(inst); @@ -124,8 +124,8 @@ fn gc_integration() { #[pyclass] struct GcNullTraversal { - cycle: Option>, - null: Option>, + cycle: Option>, + null: Option>, } #[pymethods] @@ -145,7 +145,7 @@ impl GcNullTraversal { #[test] fn gc_null_traversal() { Python::with_gil(|py| { - let obj = Py::new( + let obj = PyDetached::new( py, GcNullTraversal { cycle: None, @@ -309,7 +309,7 @@ fn traverse_partial() { let traverse = get_type_traverse(ty).unwrap(); // confirm that traversing errors - let obj = Py::new(py, PartialTraverse::new(py)).unwrap(); + let obj = PyDetached::new(py, PartialTraverse::new(py)).unwrap(); assert_eq!( traverse(obj.as_ptr(), visit_error, std::ptr::null_mut()), -1 @@ -346,7 +346,7 @@ fn traverse_panic() { let traverse = get_type_traverse(ty).unwrap(); // confirm that traversing errors - let obj = Py::new(py, PanickyTraverse::new(py)).unwrap(); + let obj = PyDetached::new(py, PanickyTraverse::new(py)).unwrap(); assert_eq!(traverse(obj.as_ptr(), novisit, std::ptr::null_mut()), -1); }) } @@ -369,7 +369,7 @@ fn tries_gil_in_traverse() { let traverse = get_type_traverse(ty).unwrap(); // confirm that traversing panicks - let obj = Py::new(py, TriesGILInTraverse {}).unwrap(); + let obj = PyDetached::new(py, TriesGILInTraverse {}).unwrap(); assert_eq!(traverse(obj.as_ptr(), novisit, std::ptr::null_mut()), -1); }) } @@ -431,7 +431,7 @@ fn traverse_cannot_be_hijacked() { #[allow(dead_code)] #[pyclass] struct DropDuringTraversal { - cycle: Cell>>, + cycle: Cell>>, dropped: TestDropCall, } @@ -453,7 +453,7 @@ fn drop_during_traversal_with_gil() { let drop_called = Arc::new(AtomicBool::new(false)); Python::with_gil(|py| { - let inst = Py::new( + let inst = PyDetached::new( py, DropDuringTraversal { cycle: Cell::new(None), @@ -484,7 +484,7 @@ fn drop_during_traversal_without_gil() { let drop_called = Arc::new(AtomicBool::new(false)); let inst = Python::with_gil(|py| { - let inst = Py::new( + let inst = PyDetached::new( py, DropDuringTraversal { cycle: Cell::new(None), diff --git a/tests/test_getter_setter.rs b/tests/test_getter_setter.rs index f16ce61166a..e1e812ee443 100644 --- a/tests/test_getter_setter.rs +++ b/tests/test_getter_setter.rs @@ -50,7 +50,7 @@ impl ClassWithProperties { #[test] fn class_with_properties() { Python::with_gil(|py| { - let inst = Py::new(py, ClassWithProperties { num: 10 }).unwrap(); + let inst = PyDetached::new(py, ClassWithProperties { num: 10 }).unwrap(); py_run!(py, inst, "assert inst.get_num() == 10"); py_run!(py, inst, "assert inst.get_num() == inst.DATA"); @@ -87,7 +87,7 @@ impl GetterSetter { #[test] fn getter_setter_autogen() { Python::with_gil(|py| { - let inst = Py::new( + let inst = PyDetached::new( py, GetterSetter { num: 10, @@ -128,7 +128,7 @@ impl RefGetterSetter { fn ref_getter_setter() { // Regression test for #837 Python::with_gil(|py| { - let inst = Py::new(py, RefGetterSetter { num: 10 }).unwrap(); + let inst = PyDetached::new(py, RefGetterSetter { num: 10 }).unwrap(); py_run!(py, inst, "assert inst.num == 10"); py_run!(py, inst, "inst.num = 20; assert inst.num == 20"); @@ -154,7 +154,7 @@ impl TupleClassGetterSetter { #[test] fn tuple_struct_getter_setter() { Python::with_gil(|py| { - let inst = Py::new(py, TupleClassGetterSetter(10)).unwrap(); + let inst = PyDetached::new(py, TupleClassGetterSetter(10)).unwrap(); py_assert!(py, inst, "inst.num == 10"); py_run!(py, inst, "inst.num = 20"); @@ -170,7 +170,7 @@ struct All { #[test] fn get_set_all() { Python::with_gil(|py| { - let inst = Py::new(py, All { num: 10 }).unwrap(); + let inst = PyDetached::new(py, All { num: 10 }).unwrap(); py_run!(py, inst, "assert inst.num == 10"); py_run!(py, inst, "inst.num = 20; assert inst.num == 20"); @@ -186,7 +186,7 @@ struct All2 { #[test] fn get_all_and_set() { Python::with_gil(|py| { - let inst = Py::new(py, All2 { num: 10 }).unwrap(); + let inst = PyDetached::new(py, All2 { num: 10 }).unwrap(); py_run!(py, inst, "assert inst.num == 10"); py_run!(py, inst, "inst.num = 20; assert inst.num == 20"); @@ -205,7 +205,7 @@ fn cell_getter_setter() { cell_inner: Cell::new(10), }; Python::with_gil(|py| { - let inst = Py::new(py, c).unwrap().to_object(py); + let inst = PyDetached::new(py, c).unwrap().to_object(py); let cell = Cell::new(20).to_object(py); py_run!(py, cell, "assert cell == 20"); @@ -232,7 +232,7 @@ fn borrowed_value_with_lifetime_of_self() { } Python::with_gil(|py| { - let inst = Py::new(py, BorrowedValue {}).unwrap().to_object(py); + let inst = PyDetached::new(py, BorrowedValue {}).unwrap().to_object(py); py_run!(py, inst, "assert inst.value == 'value'"); }); diff --git a/tests/test_inheritance.rs b/tests/test_inheritance.rs index d1cfe628ef6..e887dfa2228 100644 --- a/tests/test_inheritance.rs +++ b/tests/test_inheritance.rs @@ -237,7 +237,7 @@ mod inheriting_native_type { #[test] fn inherit_dict_drop() { Python::with_gil(|py| { - let dict_sub = pyo3::Py::new(py, DictWithName::new()).unwrap(); + let dict_sub = pyo3::PyDetached::new(py, DictWithName::new()).unwrap(); assert_eq!(dict_sub.get_refcnt(py), 1); let item = py.eval("object()", None, None).unwrap(); diff --git a/tests/test_mapping.rs b/tests/test_mapping.rs index c029ce27c50..75c0aabcca5 100644 --- a/tests/test_mapping.rs +++ b/tests/test_mapping.rs @@ -119,7 +119,7 @@ fn mapping_is_not_sequence() { let mut index = HashMap::new(); index.insert("Foo".into(), 1); index.insert("Bar".into(), 2); - let m = Py::new(py, Mapping { index }).unwrap(); + let m = PyDetached::new(py, Mapping { index }).unwrap(); PyMapping::register::(py).unwrap(); diff --git a/tests/test_methods.rs b/tests/test_methods.rs index 7919ac0c195..df991e45e13 100644 --- a/tests/test_methods.rs +++ b/tests/test_methods.rs @@ -78,7 +78,7 @@ impl ClassMethod { } #[classmethod] - fn method_owned(cls: Py) -> PyResult { + fn method_owned(cls: PyDetached) -> PyResult { Ok(format!( "{}.method_owned()!", Python::with_gil(|gil| cls.as_ref(gil).name().map(ToString::to_string))? @@ -322,7 +322,7 @@ impl MethSignature { #[test] fn meth_signature() { Python::with_gil(|py| { - let inst = Py::new(py, MethSignature {}).unwrap(); + let inst = PyDetached::new(py, MethSignature {}).unwrap(); py_run!(py, inst, "assert inst.get_optional() == 10"); py_run!(py, inst, "assert inst.get_optional(100) == 100"); @@ -814,7 +814,7 @@ impl CfgStruct { #[test] fn test_cfg_attrs() { Python::with_gil(|py| { - let inst = Py::new(py, CfgStruct {}).unwrap(); + let inst = PyDetached::new(py, CfgStruct {}).unwrap(); #[cfg(unix)] { @@ -1036,7 +1036,7 @@ issue_1506!( } fn issue_1506_custom_receiver( - _slf: Py, + _slf: PyDetached, _py: Python<'_>, _arg: &PyAny, _args: &PyTuple, @@ -1045,7 +1045,7 @@ issue_1506!( } fn issue_1506_custom_receiver_explicit( - _slf: Py, + _slf: PyDetached, _py: Python<'_>, _arg: &PyAny, _args: &PyTuple, @@ -1118,11 +1118,11 @@ fn test_option_pyclass_arg() { Python::with_gil(|py| { let f = wrap_pyfunction!(option_class_arg, py).unwrap(); assert!(f.call0().unwrap().is_none()); - let obj = Py::new(py, SomePyClass {}).unwrap(); + let obj = PyDetached::new(py, SomePyClass {}).unwrap(); assert!(f .call1((obj,)) .unwrap() - .extract::>() + .extract::>() .is_ok()); }) } diff --git a/tests/test_module.rs b/tests/test_module.rs index 2de23b38324..8458f5952d2 100644 --- a/tests/test_module.rs +++ b/tests/test_module.rs @@ -350,7 +350,7 @@ fn pyfunction_with_module(module: &PyModule) -> PyResult<&str> { #[pyfunction] #[pyo3(pass_module)] -fn pyfunction_with_module_owned(module: Py) -> PyResult { +fn pyfunction_with_module_owned(module: PyDetached) -> PyResult { Python::with_gil(|gil| module.as_ref(gil).name().map(Into::into)) } diff --git a/tests/test_no_imports.rs b/tests/test_no_imports.rs index 4f04282702e..56796d454a0 100644 --- a/tests/test_no_imports.rs +++ b/tests/test_no_imports.rs @@ -65,7 +65,7 @@ impl BasicClass { } #[staticmethod] - fn staticmethod(py: pyo3::Python<'_>, v: usize) -> pyo3::Py { + fn staticmethod(py: pyo3::Python<'_>, v: usize) -> pyo3::PyDetached { use pyo3::IntoPy; v.to_string().into_py(py) } diff --git a/tests/test_proto_methods.rs b/tests/test_proto_methods.rs index 6e6d499afa3..ba099d44f36 100644 --- a/tests/test_proto_methods.rs +++ b/tests/test_proto_methods.rs @@ -65,7 +65,7 @@ impl ExampleClass { } fn make_example(py: Python<'_>) -> &PyCell { - Py::new( + PyDetached::new( py, ExampleClass { value: 5, @@ -178,14 +178,14 @@ impl LenOverflow { #[test] fn len_overflow() { Python::with_gil(|py| { - let inst = Py::new(py, LenOverflow).unwrap(); + let inst = PyDetached::new(py, LenOverflow).unwrap(); py_expect_exception!(py, inst, "len(inst)", PyOverflowError); }); } #[pyclass] pub struct Mapping { - values: Py, + values: PyDetached, } #[pymethods] @@ -213,7 +213,7 @@ fn mapping() { Python::with_gil(|py| { PyMapping::register::(py).unwrap(); - let inst = Py::new( + let inst = PyDetached::new( py, Mapping { values: PyDict::new(py).into(), @@ -321,7 +321,7 @@ fn sequence() { Python::with_gil(|py| { PySequence::register::(py).unwrap(); - let inst = Py::new(py, Sequence { values: vec![] }).unwrap(); + let inst = PyDetached::new(py, Sequence { values: vec![] }).unwrap(); let sequence: &PySequence = inst.as_ref(py).downcast().unwrap(); @@ -382,7 +382,7 @@ impl Iterator { #[test] fn iterator() { Python::with_gil(|py| { - let inst = Py::new( + let inst = PyDetached::new( py, Iterator { iter: Box::new(5..8), @@ -410,11 +410,11 @@ struct NotCallable; #[test] fn callable() { Python::with_gil(|py| { - let c = Py::new(py, Callable).unwrap(); + let c = PyDetached::new(py, Callable).unwrap(); py_assert!(py, c, "callable(c)"); py_assert!(py, c, "c(7) == 42"); - let nc = Py::new(py, NotCallable).unwrap(); + let nc = PyDetached::new(py, NotCallable).unwrap(); py_assert!(py, nc, "not callable(nc)"); }); } @@ -517,7 +517,7 @@ impl Contains { #[test] fn contains() { Python::with_gil(|py| { - let c = Py::new(py, Contains {}).unwrap(); + let c = PyDetached::new(py, Contains {}).unwrap(); py_run!(py, c, "assert 1 in c"); py_run!(py, c, "assert -1 not in c"); py_expect_exception!(py, c, "assert 'wrong type' not in c", PyTypeError); @@ -547,7 +547,7 @@ impl GetItem { #[test] fn test_getitem() { Python::with_gil(|py| { - let ob = Py::new(py, GetItem {}).unwrap(); + let ob = PyDetached::new(py, GetItem {}).unwrap(); py_assert!(py, ob, "ob[1] == 'int'"); py_assert!(py, ob, "ob[100:200:1] == 'slice'"); @@ -697,13 +697,13 @@ asyncio.run(main()) #[pyclass] struct AsyncIterator { - future: Option>, + future: Option>, } #[pymethods] impl AsyncIterator { #[new] - fn new(future: Py) -> Self { + fn new(future: PyDetached) -> Self { Self { future: Some(future), } @@ -713,7 +713,7 @@ impl AsyncIterator { slf } - fn __anext__(&mut self) -> Option> { + fn __anext__(&mut self) -> Option> { self.future.take() } } @@ -835,10 +835,10 @@ fn test_hash_opt_out() { // By default Python provides a hash implementation, which can be disabled by setting __hash__ // to None. Python::with_gil(|py| { - let empty = Py::new(py, EmptyClass).unwrap(); + let empty = PyDetached::new(py, EmptyClass).unwrap(); py_assert!(py, empty, "hash(empty) is not None"); - let not_hashable = Py::new(py, NotHashable).unwrap(); + let not_hashable = PyDetached::new(py, NotHashable).unwrap(); py_expect_exception!(py, not_hashable, "hash(not_hashable)", PyTypeError); }) } @@ -882,10 +882,10 @@ impl NoContains { #[test] fn test_contains_opt_out() { Python::with_gil(|py| { - let defaulted_contains = Py::new(py, DefaultedContains).unwrap(); + let defaulted_contains = PyDetached::new(py, DefaultedContains).unwrap(); py_assert!(py, defaulted_contains, "'a' in defaulted_contains"); - let no_contains = Py::new(py, NoContains).unwrap(); + let no_contains = PyDetached::new(py, NoContains).unwrap(); py_expect_exception!(py, no_contains, "'a' in no_contains", PyTypeError); }) } diff --git a/tests/test_pyfunction.rs b/tests/test_pyfunction.rs index a2f44be6bbd..f7731f7efb2 100644 --- a/tests/test_pyfunction.rs +++ b/tests/test_pyfunction.rs @@ -503,8 +503,8 @@ fn test_return_value_borrows_from_arguments() { Python::with_gil(|py| { let function = wrap_pyfunction!(return_value_borrows_from_arguments, py).unwrap(); - let key = Py::new(py, Key("key".to_owned())).unwrap(); - let value = Py::new(py, Value(42)).unwrap(); + let key = PyDetached::new(py, Key("key".to_owned())).unwrap(); + let value = PyDetached::new(py, Value(42)).unwrap(); py_assert!(py, function key value, "function(key, value) == { \"key\": 42 }"); }); diff --git a/tests/test_pyself.rs b/tests/test_pyself.rs index ed922d3e2b0..9986d57f701 100644 --- a/tests/test_pyself.rs +++ b/tests/test_pyself.rs @@ -25,7 +25,7 @@ impl Reader { fn clone_ref_with_py<'py>(slf: &'py PyCell, _py: Python<'py>) -> &'py PyCell { slf } - fn get_iter(slf: &PyCell, keys: Py) -> Iter { + fn get_iter(slf: &PyCell, keys: PyDetached) -> Iter { Iter { reader: slf.into(), keys, @@ -34,10 +34,10 @@ impl Reader { } fn get_iter_and_reset( mut slf: PyRefMut<'_, Self>, - keys: Py, + keys: PyDetached, py: Python<'_>, ) -> PyResult { - let reader = Py::new(py, slf.clone())?; + let reader = PyDetached::new(py, slf.clone())?; slf.inner.clear(); Ok(Iter { reader, @@ -50,8 +50,8 @@ impl Reader { #[pyclass] #[derive(Debug)] struct Iter { - reader: Py, - keys: Py, + reader: PyDetached, + keys: PyDetached, idx: usize, } diff --git a/tests/test_sequence.rs b/tests/test_sequence.rs index b11e4a6929d..b36431d7b79 100644 --- a/tests/test_sequence.rs +++ b/tests/test_sequence.rs @@ -73,7 +73,7 @@ impl ByteSequence { Self { elements } } - fn __inplace_concat__(mut slf: PyRefMut<'_, Self>, other: &Self) -> Py { + fn __inplace_concat__(mut slf: PyRefMut<'_, Self>, other: &Self) -> PyDetached { slf.elements.extend_from_slice(&other.elements); slf.into() } @@ -90,7 +90,7 @@ impl ByteSequence { } } - fn __inplace_repeat__(mut slf: PyRefMut<'_, Self>, count: isize) -> PyResult> { + fn __inplace_repeat__(mut slf: PyRefMut<'_, Self>, count: isize) -> PyResult> { if count >= 0 { let mut elements = Vec::with_capacity(slf.elements.len() * count as usize); for _ in 0..count { diff --git a/tests/test_serde.rs b/tests/test_serde.rs index f1d5bee4bee..ae7ad363c9a 100644 --- a/tests/test_serde.rs +++ b/tests/test_serde.rs @@ -14,8 +14,8 @@ mod test_serde { #[derive(Debug, Clone, Serialize, Deserialize)] struct User { username: String, - group: Option>, - friends: Vec>, + group: Option>, + friends: Vec>, } #[test] @@ -31,11 +31,11 @@ mod test_serde { }; let user = Python::with_gil(|py| { - let py_friend1 = Py::new(py, friend1).expect("failed to create friend 1"); - let py_friend2 = Py::new(py, friend2).expect("failed to create friend 2"); + let py_friend1 = PyDetached::new(py, friend1).expect("failed to create friend 1"); + let py_friend2 = PyDetached::new(py, friend2).expect("failed to create friend 2"); let friends = vec![py_friend1, py_friend2]; - let py_group = Py::new( + let py_group = PyDetached::new( py, Group { name: "group name".into(), diff --git a/tests/test_unsendable_dict.rs b/tests/test_unsendable_dict.rs index a39aa1ab714..22fda9b73b9 100644 --- a/tests/test_unsendable_dict.rs +++ b/tests/test_unsendable_dict.rs @@ -18,7 +18,7 @@ impl UnsendableDictClass { #[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)] fn test_unsendable_dict() { Python::with_gil(|py| { - let inst = Py::new(py, UnsendableDictClass {}).unwrap(); + let inst = PyDetached::new(py, UnsendableDictClass {}).unwrap(); py_run!(py, inst, "assert inst.__dict__ == {}"); }); } @@ -38,7 +38,7 @@ impl UnsendableDictClassWithWeakRef { #[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)] fn test_unsendable_dict_with_weakref() { Python::with_gil(|py| { - let inst = Py::new(py, UnsendableDictClassWithWeakRef {}).unwrap(); + let inst = PyDetached::new(py, UnsendableDictClassWithWeakRef {}).unwrap(); py_run!(py, inst, "assert inst.__dict__ == {}"); py_run!( py, diff --git a/tests/test_various.rs b/tests/test_various.rs index 076d2ba2cb5..e57b9259616 100644 --- a/tests/test_various.rs +++ b/tests/test_various.rs @@ -27,8 +27,8 @@ impl MutRefArg { #[test] fn mut_ref_arg() { Python::with_gil(|py| { - let inst1 = Py::new(py, MutRefArg { n: 0 }).unwrap(); - let inst2 = Py::new(py, MutRefArg { n: 0 }).unwrap(); + let inst1 = PyDetached::new(py, MutRefArg { n: 0 }).unwrap(); + let inst2 = PyDetached::new(py, MutRefArg { n: 0 }).unwrap(); py_run!(py, inst1 inst2, "inst1.set_other(inst2)"); let inst2 = inst2.as_ref(py).borrow(); diff --git a/tests/ui/invalid_closure.rs b/tests/ui/invalid_closure.rs index b724f31b97e..aec17f3fe15 100644 --- a/tests/ui/invalid_closure.rs +++ b/tests/ui/invalid_closure.rs @@ -2,7 +2,7 @@ use pyo3::prelude::*; use pyo3::types::{PyCFunction, PyDict, PyTuple}; fn main() { - let fun: Py = Python::with_gil(|py| { + let fun: PyDetached = Python::with_gil(|py| { let local_data = vec![0, 1, 2, 3, 4]; let ref_: &[u8] = &local_data; @@ -10,7 +10,9 @@ fn main() { println!("This is five: {:?}", ref_.len()); Ok(()) }; - PyCFunction::new_closure(py, None, None, closure_fn).unwrap().into() + PyCFunction::new_closure(py, None, None, closure_fn) + .unwrap() + .into() }); Python::with_gil(|py| { diff --git a/tests/ui/invalid_closure.stderr b/tests/ui/invalid_closure.stderr index 90240e5db26..9ade4fa1ff1 100644 --- a/tests/ui/invalid_closure.stderr +++ b/tests/ui/invalid_closure.stderr @@ -6,7 +6,8 @@ error[E0597]: `local_data` does not live long enough 7 | let ref_: &[u8] = &local_data; | ^^^^^^^^^^^ borrowed value does not live long enough ... -13 | PyCFunction::new_closure(py, None, None, closure_fn).unwrap().into() +13 | PyCFunction::new_closure(py, None, None, closure_fn) | ---------------------------------------------------- argument requires that `local_data` is borrowed for `'static` -14 | }); +... +16 | }); | - `local_data` dropped here while still borrowed diff --git a/tests/ui/invalid_frozen_pyclass_borrow.rs b/tests/ui/invalid_frozen_pyclass_borrow.rs index 1f18eab6170..2f0fc362ca8 100644 --- a/tests/ui/invalid_frozen_pyclass_borrow.rs +++ b/tests/ui/invalid_frozen_pyclass_borrow.rs @@ -11,7 +11,7 @@ impl Foo { fn mut_method(&mut self) {} } -fn borrow_mut_fails(foo: Py, py: Python) { +fn borrow_mut_fails(foo: PyDetached, py: Python) { let borrow = foo.as_ref(py).borrow_mut(); } @@ -21,11 +21,11 @@ struct MutableBase; #[pyclass(frozen, extends = MutableBase)] struct ImmutableChild; -fn borrow_mut_of_child_fails(child: Py, py: Python) { +fn borrow_mut_of_child_fails(child: PyDetached, py: Python) { let borrow = child.as_ref(py).borrow_mut(); } -fn py_get_of_mutable_class_fails(class: Py) { +fn py_get_of_mutable_class_fails(class: PyDetached) { class.get(); } diff --git a/tests/ui/invalid_frozen_pyclass_borrow.stderr b/tests/ui/invalid_frozen_pyclass_borrow.stderr index 5e09d512ae7..2bca15680a2 100644 --- a/tests/ui/invalid_frozen_pyclass_borrow.stderr +++ b/tests/ui/invalid_frozen_pyclass_borrow.stderr @@ -52,14 +52,14 @@ error[E0271]: type mismatch resolving `::Frozen == True` 29 | class.get(); | ^^^ expected `True`, found `False` | -note: required by a bound in `pyo3::Py::::get` +note: required by a bound in `pyo3::PyDetached::::get` --> src/instance.rs | | pub fn get(&self) -> &T | --- required by a bound in this associated function | where | T: PyClass + Sync, - | ^^^^^^^^^^^^^ required by this bound in `Py::::get` + | ^^^^^^^^^^^^^ required by this bound in `PyDetached::::get` error[E0271]: type mismatch resolving `::Frozen == True` --> tests/ui/invalid_frozen_pyclass_borrow.rs:33:11 diff --git a/tests/ui/missing_intopy.stderr b/tests/ui/missing_intopy.stderr index 26b32b3e742..b03564ee8da 100644 --- a/tests/ui/missing_intopy.stderr +++ b/tests/ui/missing_intopy.stderr @@ -1,18 +1,18 @@ -error[E0277]: the trait bound `Blah: IntoPy>` is not satisfied +error[E0277]: the trait bound `Blah: IntoPy>` is not satisfied --> tests/ui/missing_intopy.rs:3:1 | 3 | #[pyo3::pyfunction] - | ^^^^^^^^^^^^^^^^^^^ the trait `IntoPy>` is not implemented for `Blah` + | ^^^^^^^^^^^^^^^^^^^ the trait `IntoPy>` is not implemented for `Blah` | = help: the following other types implement trait `IntoPy`: - >> - >> - >> - >> - >> - >> - >> - >> + >> + >> + >> + >> + >> + >> + >> + >> and $N others = note: required for `Blah` to implement `OkWrap` = note: this error originates in the attribute macro `pyo3::pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/wrong_aspyref_lifetimes.rs b/tests/ui/wrong_aspyref_lifetimes.rs index 5cd8a2d3cb6..35dbe011cc1 100644 --- a/tests/ui/wrong_aspyref_lifetimes.rs +++ b/tests/ui/wrong_aspyref_lifetimes.rs @@ -1,7 +1,7 @@ -use pyo3::{types::PyDict, Py, Python}; +use pyo3::{types::PyDict, PyDetached, Python}; fn main() { - let dict: Py = Python::with_gil(|py| PyDict::new(py).into()); + let dict: PyDetached = Python::with_gil(|py| PyDict::new(py).into()); // 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));