From 39d3ceb55158063385ca40a217da58bfcc799e89 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Wed, 17 Apr 2019 18:48:59 +0200 Subject: [PATCH 1/3] Make PyTuple constructors return &PyTuple --- src/conversion.rs | 2 +- src/types/tuple.rs | 11 +++++------ tests/test_gc.rs | 7 ++++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/conversion.rs b/src/conversion.rs index 21c80669bd5..f1438b98a91 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -426,7 +426,7 @@ where /// Converts `()` to an empty Python tuple. impl FromPy<()> for Py { fn from_py(_: (), py: Python) -> Py { - PyTuple::empty(py) + Py::from_py(PyTuple::empty(py), py) } } diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 5f67cf69956..63e956dc455 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -21,7 +21,7 @@ pyobject_native_type!(PyTuple, ffi::PyTuple_Type, ffi::PyTuple_Check); impl PyTuple { /// Construct a new tuple with the given elements. - pub fn new(py: Python, elements: impl IntoIterator) -> Py + pub fn new<'p, T, U>(py: Python<'p>, elements: impl IntoIterator) -> &'p PyTuple where T: ToPyObject, U: ExactSizeIterator, @@ -33,13 +33,13 @@ impl PyTuple { for (i, e) in elements_iter.enumerate() { ffi::PyTuple_SetItem(ptr, i as Py_ssize_t, e.to_object(py).into_ptr()); } - Py::from_owned_ptr_or_panic(ptr) + py.from_owned_ptr(ptr) } } /// Retrieves the empty tuple. - pub fn empty(_py: Python) -> Py { - unsafe { Py::from_owned_ptr_or_panic(ffi::PyTuple_New(0)) } + pub fn empty<'p>(py: Python<'p>) -> &'p PyTuple { + unsafe { py.from_owned_ptr(ffi::PyTuple_New(0)) } } /// Gets the length of the tuple. @@ -264,8 +264,7 @@ mod test { fn test_new() { let gil = Python::acquire_gil(); let py = gil.python(); - let pyob = PyTuple::new(py, &[1, 2, 3]); - let ob = pyob.as_ref(py); + let ob = PyTuple::new(py, &[1, 2, 3]); assert_eq!(3, ob.len()); let ob: &PyAny = ob.into(); assert_eq!((1, 2, 3), ob.extract().unwrap()); diff --git a/tests/test_gc.rs b/tests/test_gc.rs index 7a9d032c408..b3e6a112710 100644 --- a/tests/test_gc.rs +++ b/tests/test_gc.rs @@ -93,8 +93,9 @@ impl Drop for ClassWithDrop { unsafe { let py = Python::assume_gil_acquired(); - let _empty1 = PyTuple::empty(py); - let _empty2: PyObject = PyTuple::empty(py).into(); + let _empty1: Py = FromPy::from_py(PyTuple::empty(py), py); + let _empty2: Py = FromPy::from_py(PyTuple::empty(py), py); + let _empty2: PyObject = _empty2.into(); let _empty3: &PyAny = py.from_owned_ptr(ffi::PyTuple_New(0)); } } @@ -110,7 +111,7 @@ fn create_pointers_in_drop() { { let gil = Python::acquire_gil(); let py = gil.python(); - let empty = PyTuple::empty(py); + let empty: Py = FromPy::from_py(PyTuple::empty(py), py); ptr = empty.as_ptr(); cnt = empty.get_refcnt() - 1; let inst = Py::new(py, ClassWithDrop {}).unwrap(); From 4bf448ecaaab7775797d9ba56a54109e900e67a6 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Sat, 25 May 2019 22:12:33 +0900 Subject: [PATCH 2/3] Complete the PR --- CHANGELOG.md | 1 + src/types/tuple.rs | 5 ++++- tests/test_gc.rs | 8 ++++---- tests/test_various.rs | 7 ++++--- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 879b83f0f6f..c26dc19e019 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * `PySet::new` and `PyFrozenSet::new` now return `PyResult<&Py[Frozen]Set>`; exceptions are raised if the items are not hashable. * Fixed building using `venv` on Windows. + * `PyTuple::new` now returns `&PyTuple` instead of `Py`. ## [0.6.0] - 2018-03-28 diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 63e956dc455..9e259d1a9d6 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -21,7 +21,10 @@ pyobject_native_type!(PyTuple, ffi::PyTuple_Type, ffi::PyTuple_Check); impl PyTuple { /// Construct a new tuple with the given elements. - pub fn new<'p, T, U>(py: Python<'p>, elements: impl IntoIterator) -> &'p PyTuple + pub fn new<'p, T, U>( + py: Python<'p>, + elements: impl IntoIterator, + ) -> &'p PyTuple where T: ToPyObject, U: ExactSizeIterator, diff --git a/tests/test_gc.rs b/tests/test_gc.rs index b3e6a112710..d03906098a5 100644 --- a/tests/test_gc.rs +++ b/tests/test_gc.rs @@ -94,8 +94,7 @@ impl Drop for ClassWithDrop { let py = Python::assume_gil_acquired(); let _empty1: Py = FromPy::from_py(PyTuple::empty(py), py); - let _empty2: Py = FromPy::from_py(PyTuple::empty(py), py); - let _empty2: PyObject = _empty2.into(); + let _empty2 = PyTuple::empty(py).into_object(py); let _empty3: &PyAny = py.from_owned_ptr(ffi::PyTuple_New(0)); } } @@ -111,9 +110,10 @@ fn create_pointers_in_drop() { { let gil = Python::acquire_gil(); let py = gil.python(); - let empty: Py = FromPy::from_py(PyTuple::empty(py), py); + let empty = PyTuple::empty(py).into_object(py); ptr = empty.as_ptr(); - cnt = empty.get_refcnt() - 1; + // substract 2, because `PyTuple::empty(py).into_object(py)` increases the refcnt by 2 + cnt = empty.get_refcnt() - 2; let inst = Py::new(py, ClassWithDrop {}).unwrap(); drop(inst); } diff --git a/tests/test_various.rs b/tests/test_various.rs index 08bb35e676f..9901051ce65 100644 --- a/tests/test_various.rs +++ b/tests/test_various.rs @@ -129,9 +129,10 @@ impl PickleSupport { obj.init({ PickleSupport {} }); } - pub fn __reduce__(slf: PyRef) -> PyResult<(PyObject, Py, PyObject)> { - let gil = Python::acquire_gil(); - let py = gil.python(); + pub fn __reduce__<'py>( + slf: PyRef, + py: Python<'py>, + ) -> PyResult<(PyObject, &'py PyTuple, PyObject)> { let cls = slf.to_object(py).getattr(py, "__class__")?; let dict = slf.to_object(py).getattr(py, "__dict__")?; Ok((cls, PyTuple::empty(py), dict)) From e4287e4e47011aef51316c3073378b4c727bc452 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Sun, 26 May 2019 00:14:36 +0900 Subject: [PATCH 3/3] Fix datetime example --- examples/rustapi_module/src/datetime.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/rustapi_module/src/datetime.rs b/examples/rustapi_module/src/datetime.rs index 13d50180d9d..677eab1fa00 100644 --- a/examples/rustapi_module/src/datetime.rs +++ b/examples/rustapi_module/src/datetime.rs @@ -11,7 +11,7 @@ fn make_date<'p>(py: Python<'p>, year: i32, month: u8, day: u8) -> PyResult<&'p } #[pyfunction] -fn get_date_tuple(py: Python<'_>, d: &PyDate) -> Py { +fn get_date_tuple<'p>(py: Python<'p>, d: &PyDate) -> &'p PyTuple { PyTuple::new( py, &[d.get_year(), d.get_month() as i32, d.get_day() as i32], @@ -65,7 +65,7 @@ fn time_with_fold<'p>( } #[pyfunction] -fn get_time_tuple(py: Python<'_>, dt: &PyTime) -> Py { +fn get_time_tuple<'p>(py: Python<'p>, dt: &PyTime) -> &'p PyTuple { PyTuple::new( py, &[ @@ -79,7 +79,7 @@ fn get_time_tuple(py: Python<'_>, dt: &PyTime) -> Py { #[cfg(Py_3_6)] #[pyfunction] -fn get_time_tuple_fold(py: Python, dt: &PyTime) -> Py { +fn get_time_tuple_fold<'p>(py: Python<'p>, dt: &PyTime) -> &'p PyTuple { PyTuple::new( py, &[ @@ -103,7 +103,7 @@ fn make_delta<'p>( } #[pyfunction] -fn get_delta_tuple(py: Python<'_>, delta: &PyDelta) -> Py { +fn get_delta_tuple<'p>(py: Python<'p>, delta: &PyDelta) -> &'p PyTuple { PyTuple::new( py, &[ @@ -140,7 +140,7 @@ fn make_datetime<'p>( } #[pyfunction] -fn get_datetime_tuple(py: Python<'_>, dt: &PyDateTime) -> Py { +fn get_datetime_tuple<'p>(py: Python<'p>, dt: &PyDateTime) -> &'p PyTuple { PyTuple::new( py, &[ @@ -157,7 +157,7 @@ fn get_datetime_tuple(py: Python<'_>, dt: &PyDateTime) -> Py { #[cfg(Py_3_6)] #[pyfunction] -fn get_datetime_tuple_fold(py: Python, dt: &PyDateTime) -> Py { +fn get_datetime_tuple_fold<'p>(py: Python<'p>, dt: &PyDateTime) -> &'p PyTuple { PyTuple::new( py, &[