Added `From<Bound<'py, T>>` impl for `PyClassInitializer<T>`. (#4214)

* Added `From<Bound<'py, T>>` impl for PyClassInitializer<T>.

* Added newsfragment entry.

* Added tests for pyclass constructors returning `Py<Self>` and `Bound<Self>`.

* Fixed tests.

* Updated tests to properly cover the new impl.

---------

Co-authored-by: jrudolph <jrudolph@anl.gov>
This commit is contained in:
JRRudy1 2024-05-27 20:49:52 -05:00 committed by GitHub
parent 388d1760b5
commit 934c663612
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 48 additions and 0 deletions

View File

@ -0,0 +1 @@
Added `From<Bound<'py, T>>` impl for `PyClassInitializer<T>`.

View File

@ -301,6 +301,13 @@ impl<T: PyClass> From<Py<T>> for PyClassInitializer<T> {
} }
} }
impl<'py, T: PyClass> From<Bound<'py, T>> for PyClassInitializer<T> {
#[inline]
fn from(value: Bound<'py, T>) -> PyClassInitializer<T> {
PyClassInitializer::from(value.unbind())
}
}
// Implementation used by proc macros to allow anything convertible to PyClassInitializer<T> to be // Implementation used by proc macros to allow anything convertible to PyClassInitializer<T> to be
// the return value of pyclass #[new] method (optionally wrapped in `Result<U, E>`). // the return value of pyclass #[new] method (optionally wrapped in `Result<U, E>`).
impl<T, U> IntoPyCallbackOutput<PyClassInitializer<T>> for U impl<T, U> IntoPyCallbackOutput<PyClassInitializer<T>> for U

View File

@ -258,3 +258,43 @@ fn test_new_existing() {
assert!(!obj5.is(&obj6)); assert!(!obj5.is(&obj6));
}); });
} }
#[pyclass]
struct NewReturnsPy;
#[pymethods]
impl NewReturnsPy {
#[new]
fn new(py: Python<'_>) -> PyResult<Py<NewReturnsPy>> {
Py::new(py, NewReturnsPy)
}
}
#[test]
fn test_new_returns_py() {
Python::with_gil(|py| {
let type_ = py.get_type_bound::<NewReturnsPy>();
let obj = type_.call0().unwrap();
assert!(obj.is_exact_instance_of::<NewReturnsPy>());
})
}
#[pyclass]
struct NewReturnsBound;
#[pymethods]
impl NewReturnsBound {
#[new]
fn new(py: Python<'_>) -> PyResult<Bound<'_, NewReturnsBound>> {
Bound::new(py, NewReturnsBound)
}
}
#[test]
fn test_new_returns_bound() {
Python::with_gil(|py| {
let type_ = py.get_type_bound::<NewReturnsBound>();
let obj = type_.call0().unwrap();
assert!(obj.is_exact_instance_of::<NewReturnsBound>());
})
}