Skip to content

Commit f26e07c

Browse files
committed
Replace IntoInitializer<T> with Into<PyClassInitializer<T>>
1 parent b602b4b commit f26e07c

File tree

8 files changed

+23
-48
lines changed

8 files changed

+23
-48
lines changed

guide/src/class.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,8 @@ created from Rust, but not from Python.
189189
For arguments, see the `Method arguments` section below.
190190

191191
### Return type
192-
Generally, `#[new]` method have to return `T: IntoInitializer<Self>` or
193-
`PyResult<T> where T: IntoInitializer<Self>`.
194-
195-
If your `T: PyClass` inherits just `PyAny`, you can return just `Self` or `PyResult<Self>`.
196-
But if it inherits other `U: PyClass`, you have to return tuple `(T, U)` or
197-
`PyClassInitializer<T>`.
192+
Generally, `#[new]` method have to return `T: Into<PyClassInitializer<Self>>` or
193+
`PyResult<T> where T: Into<PyClassInitializer<Self>>`.
198194

199195
For constructors that may fail, you should wrap the return type in a PyResult as well.
200196
Consult the table below to determine which type your constructor should return:
@@ -209,7 +205,7 @@ Consult the table below to determine which type your constructor should return:
209205
By default, `PyAny` is used as the base class. To override this default,
210206
use the `extends` parameter for `pyclass` with the full path to the base class.
211207

212-
For convinience, `(T, U)` implements `IntoInitializer<T>` where `U` is the
208+
For convinience, `(T, U)` implements `Into<PyClassInitializer<T>>` where `U` is the
213209
baseclass of `T`.
214210
But for more deeply nested inheritance, you have to return `PyClassInitializer<T>`
215211
explicitly.
@@ -261,8 +257,7 @@ struct SubSubClass {
261257
impl SubSubClass {
262258
#[new]
263259
fn new() -> PyClassInitializer<Self> {
264-
SubClass::new()
265-
.into_initializer()
260+
PyClassInitializer::from(SubClass::new())
266261
.add_subclass(SubSubClass{val3: 20})
267262
}
268263

pyo3-derive-backend/src/pymethod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ pub fn impl_wrap_new(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream {
174174

175175
#body
176176

177-
match _result.and_then(|init| init.into_initializer().create_shell(_py)) {
177+
match _result.and_then(|init| pyo3::PyClassInitializer::from(init).create_shell(_py)) {
178178
Ok(slf) => slf as _,
179179
Err(e) => e.restore_and_null(_py),
180180
}

src/derive_utils.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::exceptions::TypeError;
99
use crate::init_once;
1010
use crate::instance::PyNativeType;
1111
use crate::pyclass::PyClass;
12-
use crate::pyclass_init::IntoInitializer;
12+
use crate::pyclass_init::PyClassInitializer;
1313
use crate::types::{PyAny, PyDict, PyModule, PyTuple};
1414
use crate::{ffi, GILPool, IntoPy, PyObject, Python};
1515
use std::ptr;
@@ -184,17 +184,17 @@ impl<T: IntoPy<PyObject>> IntoPyResult<T> for PyResult<T> {
184184

185185
/// Variant of IntoPyResult for the specific case of #[new]. In the case of returning (Sub, Base)
186186
/// from #[new], IntoPyResult can't apply because (Sub, Base) doesn't implement IntoPy<PyObject>.
187-
pub trait IntoPyNewResult<T: PyClass, I: IntoInitializer<T>> {
187+
pub trait IntoPyNewResult<T: PyClass, I: Into<PyClassInitializer<T>>> {
188188
fn into_pynew_result(self) -> PyResult<I>;
189189
}
190190

191-
impl<T: PyClass, I: IntoInitializer<T>> IntoPyNewResult<T, I> for I {
191+
impl<T: PyClass, I: Into<PyClassInitializer<T>>> IntoPyNewResult<T, I> for I {
192192
fn into_pynew_result(self) -> PyResult<I> {
193193
Ok(self)
194194
}
195195
}
196196

197-
impl<T: PyClass, I: IntoInitializer<T>> IntoPyNewResult<T, I> for PyResult<I> {
197+
impl<T: PyClass, I: Into<PyClassInitializer<T>>> IntoPyNewResult<T, I> for PyResult<I> {
198198
fn into_pynew_result(self) -> PyResult<I> {
199199
self
200200
}

src/instance.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::gil;
44
use crate::object::PyObject;
55
use crate::objectprotocol::ObjectProtocol;
66
use crate::pyclass::{PyClass, PyClassShell};
7-
use crate::pyclass_init::IntoInitializer;
7+
use crate::pyclass_init::PyClassInitializer;
88
use crate::type_object::{PyObjectLayout, PyTypeInfo};
99
use crate::types::PyAny;
1010
use crate::{ffi, IntoPy};
@@ -36,13 +36,13 @@ unsafe impl<T> Sync for Py<T> {}
3636

3737
impl<T> Py<T> {
3838
/// Create new instance of T and move it under python management
39-
pub fn new(py: Python, value: impl IntoInitializer<T>) -> PyResult<Py<T>>
39+
pub fn new(py: Python, value: impl Into<PyClassInitializer<T>>) -> PyResult<Py<T>>
4040
where
4141
T: PyClass,
4242
<T::BaseType as PyTypeInfo>::ConcreteLayout:
4343
crate::type_object::PyObjectSizedLayout<T::BaseType>,
4444
{
45-
let initializer = value.into_initializer();
45+
let initializer = value.into();
4646
let obj = unsafe { initializer.create_shell(py)? };
4747
let ob = unsafe { Py::from_owned_ptr(obj as _) };
4848
Ok(ob)

src/lib.rs

100755100644
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ pub use crate::instance::{AsPyRef, ManagedPyRef, Py, PyNativeType};
128128
pub use crate::object::PyObject;
129129
pub use crate::objectprotocol::ObjectProtocol;
130130
pub use crate::pyclass::{PyClass, PyClassShell};
131-
pub use crate::pyclass_init::{IntoInitializer, PyClassInitializer};
131+
pub use crate::pyclass_init::PyClassInitializer;
132132
pub use crate::python::{prepare_freethreaded_python, Python};
133133
pub use crate::type_object::{type_flags, PyTypeInfo};
134134

src/prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub use crate::objectprotocol::ObjectProtocol;
1818
pub use crate::python::Python;
1919
pub use crate::{FromPy, FromPyObject, IntoPy, IntoPyPointer, PyTryFrom, PyTryInto, ToPyObject};
2020
// This is only part of the prelude because we need it for the pymodule function
21-
pub use crate::pyclass_init::{IntoInitializer, PyClassInitializer};
21+
pub use crate::pyclass_init::PyClassInitializer;
2222
pub use crate::types::PyModule;
2323
pub use pyo3cls::pymodule;
2424
pub use pyo3cls::{pyclass, pyfunction, pymethods, pyproto};

src/pyclass.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! An experiment module which has all codes related only to #[pyclass]
22
use crate::class::methods::{PyMethodDefType, PyMethodsProtocol};
33
use crate::conversion::{AsPyPointer, FromPyPointer, ToPyObject};
4-
use crate::pyclass_init::IntoInitializer;
4+
use crate::pyclass_init::PyClassInitializer;
55
use crate::pyclass_slots::{PyClassDict, PyClassWeakRef};
66
use crate::type_object::{type_flags, PyObjectLayout, PyObjectSizedLayout, PyTypeObject};
77
use crate::types::PyAny;
@@ -130,26 +130,26 @@ pub struct PyClassShell<T: PyClass> {
130130

131131
impl<T: PyClass> PyClassShell<T> {
132132
/// Make new `PyClassShell` on the Python heap and returns the reference of it.
133-
pub fn new_ref(py: Python, value: impl IntoInitializer<T>) -> PyResult<&Self>
133+
pub fn new_ref(py: Python, value: impl Into<PyClassInitializer<T>>) -> PyResult<&Self>
134134
where
135135
<T::BaseType as PyTypeInfo>::ConcreteLayout:
136136
crate::type_object::PyObjectSizedLayout<T::BaseType>,
137137
{
138138
unsafe {
139-
let initializer = value.into_initializer();
139+
let initializer = value.into();
140140
let self_ = initializer.create_shell(py)?;
141141
FromPyPointer::from_owned_ptr_or_err(py, self_ as _)
142142
}
143143
}
144144

145145
/// Make new `PyClassShell` on the Python heap and returns the mutable reference of it.
146-
pub fn new_mut(py: Python, value: impl IntoInitializer<T>) -> PyResult<&mut Self>
146+
pub fn new_mut(py: Python, value: impl Into<PyClassInitializer<T>>) -> PyResult<&mut Self>
147147
where
148148
<T::BaseType as PyTypeInfo>::ConcreteLayout:
149149
crate::type_object::PyObjectSizedLayout<T::BaseType>,
150150
{
151151
unsafe {
152-
let initializer = value.into_initializer();
152+
let initializer = value.into();
153153
let self_ = initializer.create_shell(py)?;
154154
FromPyPointer::from_owned_ptr_or_err(py, self_ as _)
155155
}

src/pyclass_init.rs

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,34 +109,14 @@ where
109109
}
110110
}
111111

112-
/// An extension of Into which extends the range of possible types from `#[pyclass]`'s `#[new]`.
113-
///
114-
/// In particular it permits for the return type of `#[new]` to be a (SubType, BaseType) pair
115-
/// which will also be initialized.
116-
///
117-
/// It is mainly used in our proc-macro code.
118-
pub trait IntoInitializer<T: PyClass> {
119-
fn into_initializer(self) -> PyClassInitializer<T>;
120-
}
121-
122-
impl<T, U> IntoInitializer<T> for U
123-
where
124-
T: PyClass,
125-
U: Into<PyClassInitializer<T>>,
126-
{
127-
fn into_initializer(self) -> PyClassInitializer<T> {
128-
self.into()
129-
}
130-
}
131-
132-
impl<S, B> IntoInitializer<S> for (S, B)
112+
impl<S, B> From<(S, B)> for PyClassInitializer<S>
133113
where
134114
S: PyClass + PyTypeInfo<BaseType = B>,
135115
B: PyClass + PyTypeInfo<Initializer = PyClassInitializer<B>>,
136116
B::BaseType: PyTypeInfo<Initializer = PyNativeTypeInitializer<B::BaseType>>,
137117
{
138-
fn into_initializer(self) -> PyClassInitializer<S> {
139-
let (sub, base_init) = self;
140-
base_init.into_initializer().add_subclass(sub)
118+
fn from(sub_and_base: (S, B)) -> PyClassInitializer<S> {
119+
let (sub, base) = sub_and_base;
120+
PyClassInitializer::from(base).add_subclass(sub)
141121
}
142122
}

0 commit comments

Comments
 (0)