Use a full path for `#[new]` method which is also `#[classmethod]`.

This commit is contained in:
Kang Seonghoon 2023-05-29 10:20:12 +09:00
parent d930bc14d9
commit c2d4e8ad1f
2 changed files with 26 additions and 1 deletions

View File

@ -506,7 +506,9 @@ impl<'a> FnSpec<'a> {
let (arg_convert, args) = impl_arg_params(self, cls, &py, false)?;
let call = match &self.tp {
FnType::FnNew => quote! { #rust_name(#(#args),*) },
FnType::FnNewClass => quote! { #rust_name(PyType::from_type_ptr(#py, subtype), #(#args),*) },
FnType::FnNewClass => {
quote! { #rust_name(_pyo3::types::PyType::from_type_ptr(#py, subtype), #(#args),*) }
}
x => panic!("Only `FnNew` or `FnNewClass` may use the `TpNew` calling convention. Got: {:?}", x),
};
quote! {

View File

@ -121,3 +121,26 @@ fn test_basic() {
pyo3::py_run!(py, *d, "b += a; assert (b.v, b.s) == (19, 'foobar!')");
});
}
#[pyo3::pyclass]
struct NewClassMethod {
#[pyo3(get)]
cls: pyo3::PyObject,
}
#[pyo3::pymethods]
impl NewClassMethod {
#[new]
#[classmethod]
fn new(cls: &pyo3::types::PyType) -> Self {
Self { cls: cls.into() }
}
}
#[test]
fn test_new_class_method() {
pyo3::Python::with_gil(|py| {
let cls = py.get_type::<NewClassMethod>();
pyo3::py_run!(py, cls, "assert cls().cls is cls");
});
}