Skip to content

Commit 245617a

Browse files
committed
Remove ordinary method specialization
1 parent 77726a5 commit 245617a

File tree

3 files changed

+45
-87
lines changed

3 files changed

+45
-87
lines changed

pyo3-macros-backend/src/pyclass.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -766,9 +766,6 @@ impl<'a> PyClassImplsBuilder<'a> {
766766
visitor(collector.descr_protocol_methods());
767767
visitor(collector.mapping_protocol_methods());
768768
visitor(collector.number_protocol_methods());
769-
770-
// It's collected last so Python ignore them if it found methods with same names.
771-
visitor(collector.py_class_default_impls());
772769
}
773770
fn get_new() -> ::std::option::Option<::pyo3::ffi::newfunc> {
774771
use ::pyo3::class::impl_::*;
@@ -790,6 +787,8 @@ impl<'a> PyClassImplsBuilder<'a> {
790787
// Implementation which uses dtolnay specialization to load all slots.
791788
use ::pyo3::class::impl_::*;
792789
let collector = PyClassImplCollector::<Self>::new();
790+
// This depends on Python implementation detail;
791+
// an old slot entry will be overriden by newer ones.
793792
visitor(collector.py_class_default_slots());
794793
visitor(collector.object_protocol_slots());
795794
visitor(collector.number_protocol_slots());

src/class/impl_.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,9 +629,6 @@ pub trait HasMethodsInventory {
629629
// Methods from #[pyo3(get, set)] on struct fields.
630630
methods_trait!(PyClassDescriptors, py_class_descriptors);
631631

632-
// Methods that PyO3 implemented by default, but can be overridden by the user.
633-
methods_trait!(PyClassDefaultImpls, py_class_default_impls);
634-
635632
// Methods from #[pymethods] if not using inventory.
636633
#[cfg(not(feature = "multiple-pymethods"))]
637634
methods_trait!(PyMethods, py_methods);

tests/test_default_impls.rs

Lines changed: 43 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -5,99 +5,61 @@ use pyo3::py_run;
55

66
mod common;
77

8-
// Tests for PyClassDefaultImpls
8+
// Tests for PyClassDefaultSlots
99
#[pyclass]
10-
struct TestDefaultImpl;
10+
struct TestDefaultSlots;
1111

1212
// generated using `Cargo expand`
1313
// equivalent to
1414
// ```
15-
// impl TestDefaultImpl {
16-
// #[staticmethod]
17-
// fn default() {}
18-
// #[staticmethod]
19-
// fn overriden() -> bool { false }
15+
// impl TestDefaultSlots {{
16+
// fn __str__(&self) -> &'static str {
17+
// "default"
18+
// }
2019
// }
2120
// ```
22-
impl TestDefaultImpl {
23-
fn __pyo3__default() {}
24-
fn __pyo3__overriden() -> bool {
25-
false
21+
impl TestDefaultSlots {
22+
fn __pyo3__str__(&self) -> &'static str {
23+
"default"
2624
}
2725
}
2826

29-
impl pyo3::class::impl_::PyClassDefaultImpls<TestDefaultImpl>
30-
for pyo3::class::impl_::PyClassImplCollector<TestDefaultImpl>
27+
impl ::pyo3::class::impl_::PyClassDefaultSlots<TestDefaultSlots>
28+
for ::pyo3::class::impl_::PyClassImplCollector<TestDefaultSlots>
3129
{
32-
fn py_class_default_impls(self) -> &'static [PyMethodDefType] {
33-
static METHODS: &[::pyo3::class::methods::PyMethodDefType] = &[
34-
::pyo3::class::PyMethodDefType::Static(
35-
::pyo3::class::methods::PyMethodDef::noargs(
36-
"default\u{0}",
37-
::pyo3::class::methods::PyCFunction({
38-
unsafe extern "C" fn __wrap(
39-
_slf: *mut ::pyo3::ffi::PyObject,
40-
_args: *mut ::pyo3::ffi::PyObject,
41-
) -> *mut ::pyo3::ffi::PyObject {
42-
::pyo3::callback::handle_panic(|_py| {
43-
::pyo3::callback::convert(_py, TestDefaultImpl::__pyo3__default())
44-
})
45-
}
46-
__wrap
47-
}),
48-
"\u{0}",
49-
)
50-
.flags(::pyo3::ffi::METH_STATIC),
51-
),
52-
::pyo3::class::PyMethodDefType::Static(
53-
::pyo3::class::methods::PyMethodDef::noargs(
54-
"overriden\u{0}",
55-
::pyo3::class::methods::PyCFunction({
56-
unsafe extern "C" fn __wrap(
57-
_slf: *mut ::pyo3::ffi::PyObject,
58-
_args: *mut ::pyo3::ffi::PyObject,
59-
) -> *mut ::pyo3::ffi::PyObject {
60-
::pyo3::callback::handle_panic(|_py| {
61-
::pyo3::callback::convert(_py, TestDefaultImpl::__pyo3__overriden())
62-
})
63-
}
64-
__wrap
65-
}),
66-
"\u{0}",
67-
)
68-
.flags(::pyo3::ffi::METH_STATIC),
69-
),
70-
];
71-
METHODS
72-
}
73-
}
74-
75-
#[pymethods]
76-
impl TestDefaultImpl {
77-
#[staticmethod]
78-
fn overriden() -> bool {
79-
true
30+
fn py_class_default_slots(self) -> &'static [::pyo3::ffi::PyType_Slot] {
31+
&[{
32+
unsafe extern "C" fn __wrap(
33+
_raw_slf: *mut ::pyo3::ffi::PyObject,
34+
) -> *mut ::pyo3::ffi::PyObject {
35+
let _slf = _raw_slf;
36+
::pyo3::callback::handle_panic(|_py| {
37+
let _cell = _py
38+
.from_borrowed_ptr::<::pyo3::PyAny>(_slf)
39+
.downcast::<::pyo3::PyCell<TestDefaultSlots>>()?;
40+
let _ref = _cell.try_borrow()?;
41+
let _slf = &_ref;
42+
::pyo3::callback::convert(_py, TestDefaultSlots::__pyo3__str__(_slf))
43+
})
44+
}
45+
::pyo3::ffi::PyType_Slot {
46+
slot: ::pyo3::ffi::Py_tp_str,
47+
pfunc: __wrap as ::pyo3::ffi::reprfunc as _,
48+
}
49+
}]
8050
}
8151
}
8252

8353
#[test]
84-
fn test_default_impl_exists() {
85-
Python::with_gil(|py| {
86-
let test_object = Py::new(py, TestDefaultImpl).unwrap();
87-
py_run!(py, test_object, "test_object.default()");
88-
})
89-
}
90-
91-
#[test]
92-
fn test_default_impl_is_overriden() {
54+
fn test_default_slot_exists() {
9355
Python::with_gil(|py| {
94-
let test_object = Py::new(py, TestDefaultImpl).unwrap();
95-
py_assert!(py, test_object, "test_object.overriden() == True");
56+
let test_object = Py::new(py, TestDefaultSlots).unwrap();
57+
py_assert!(py, test_object, "str(test_object) == 'default'");
9658
})
9759
}
9860

9961
#[pyclass]
100-
struct OverrideMagicMethod;
62+
struct OverrideSlot;
10163

10264
// generated using `Cargo expand`
10365
// equivalent to
@@ -108,14 +70,14 @@ struct OverrideMagicMethod;
10870
// }
10971
// }
11072
// ```
111-
impl OverrideMagicMethod {
73+
impl OverrideSlot {
11274
fn __pyo3__str__(&self) -> &'static str {
11375
"default"
11476
}
11577
}
11678

117-
impl ::pyo3::class::impl_::PyClassDefaultSlots<OverrideMagicMethod>
118-
for ::pyo3::class::impl_::PyClassImplCollector<OverrideMagicMethod>
79+
impl ::pyo3::class::impl_::PyClassDefaultSlots<OverrideSlot>
80+
for ::pyo3::class::impl_::PyClassImplCollector<OverrideSlot>
11981
{
12082
fn py_class_default_slots(self) -> &'static [::pyo3::ffi::PyType_Slot] {
12183
&[{
@@ -126,10 +88,10 @@ impl ::pyo3::class::impl_::PyClassDefaultSlots<OverrideMagicMethod>
12688
::pyo3::callback::handle_panic(|_py| {
12789
let _cell = _py
12890
.from_borrowed_ptr::<::pyo3::PyAny>(_slf)
129-
.downcast::<::pyo3::PyCell<OverrideMagicMethod>>()?;
91+
.downcast::<::pyo3::PyCell<OverrideSlot>>()?;
13092
let _ref = _cell.try_borrow()?;
13193
let _slf = &_ref;
132-
::pyo3::callback::convert(_py, OverrideMagicMethod::__pyo3__str__(_slf))
94+
::pyo3::callback::convert(_py, OverrideSlot::__pyo3__str__(_slf))
13395
})
13496
}
13597
::pyo3::ffi::PyType_Slot {
@@ -141,16 +103,16 @@ impl ::pyo3::class::impl_::PyClassDefaultSlots<OverrideMagicMethod>
141103
}
142104

143105
#[pymethods]
144-
impl OverrideMagicMethod {
106+
impl OverrideSlot {
145107
fn __str__(&self) -> &str {
146108
"overriden"
147109
}
148110
}
149111

150112
#[test]
151-
fn test_override_magic_method() {
113+
fn test_override_slot() {
152114
Python::with_gil(|py| {
153-
let test_object = Py::new(py, OverrideMagicMethod).unwrap();
115+
let test_object = Py::new(py, OverrideSlot).unwrap();
154116
py_assert!(py, test_object, "str(test_object) == 'overriden'");
155117
})
156118
}

0 commit comments

Comments
 (0)