From 934c6636120acf5a7a30e26de5d4358001c1ac5b Mon Sep 17 00:00:00 2001 From: JRRudy1 <31031841+JRRudy1@users.noreply.github.com> Date: Mon, 27 May 2024 20:49:52 -0500 Subject: [PATCH] Added `From>` impl for `PyClassInitializer`. (#4214) * Added `From>` impl for PyClassInitializer. * Added newsfragment entry. * Added tests for pyclass constructors returning `Py` and `Bound`. * Fixed tests. * Updated tests to properly cover the new impl. --------- Co-authored-by: jrudolph --- newsfragments/4214.added.md | 1 + src/pyclass_init.rs | 7 +++++++ tests/test_class_new.rs | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 newsfragments/4214.added.md diff --git a/newsfragments/4214.added.md b/newsfragments/4214.added.md new file mode 100644 index 00000000..943e1e99 --- /dev/null +++ b/newsfragments/4214.added.md @@ -0,0 +1 @@ +Added `From>` impl for `PyClassInitializer`. \ No newline at end of file diff --git a/src/pyclass_init.rs b/src/pyclass_init.rs index 923bc5b7..2e73c151 100644 --- a/src/pyclass_init.rs +++ b/src/pyclass_init.rs @@ -301,6 +301,13 @@ impl From> for PyClassInitializer { } } +impl<'py, T: PyClass> From> for PyClassInitializer { + #[inline] + fn from(value: Bound<'py, T>) -> PyClassInitializer { + PyClassInitializer::from(value.unbind()) + } +} + // Implementation used by proc macros to allow anything convertible to PyClassInitializer to be // the return value of pyclass #[new] method (optionally wrapped in `Result`). impl IntoPyCallbackOutput> for U diff --git a/tests/test_class_new.rs b/tests/test_class_new.rs index 161c60e9..01081d7a 100644 --- a/tests/test_class_new.rs +++ b/tests/test_class_new.rs @@ -258,3 +258,43 @@ fn test_new_existing() { assert!(!obj5.is(&obj6)); }); } + +#[pyclass] +struct NewReturnsPy; + +#[pymethods] +impl NewReturnsPy { + #[new] + fn new(py: Python<'_>) -> PyResult> { + Py::new(py, NewReturnsPy) + } +} + +#[test] +fn test_new_returns_py() { + Python::with_gil(|py| { + let type_ = py.get_type_bound::(); + let obj = type_.call0().unwrap(); + assert!(obj.is_exact_instance_of::()); + }) +} + +#[pyclass] +struct NewReturnsBound; + +#[pymethods] +impl NewReturnsBound { + #[new] + fn new(py: Python<'_>) -> PyResult> { + Bound::new(py, NewReturnsBound) + } +} + +#[test] +fn test_new_returns_bound() { + Python::with_gil(|py| { + let type_ = py.get_type_bound::(); + let obj = type_.call0().unwrap(); + assert!(obj.is_exact_instance_of::()); + }) +}