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::()); + }) +}