1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
#![cfg(feature = "macros")]
use pyo3::prelude::*;
#[pyclass(subclass)]
struct Base {
num: u32,
}
#[pymethods]
impl Base {
#[new]
fn new() -> Self {
Self { num: 0 }
}
fn __init__(&mut self) {
self.num += 42
}
}
#[test]
fn test_base_init() {
Python::attach(|py| {
let typeobj = py.get_type::<Base>();
let obj = typeobj.call((), None).unwrap().cast_into::<Base>().unwrap();
// check __init__ was called
assert_eq!(obj.borrow().num, 42);
});
}
#[pyclass(extends=Base)]
struct SubWithoutInit;
#[pymethods]
impl SubWithoutInit {
#[new]
fn new() -> (Self, Base) {
(Self, Base::new())
}
}
#[test]
fn test_subclass_without_init_calls_base_init() {
Python::attach(|py| {
let typeobj = py.get_type::<SubWithoutInit>();
let obj = typeobj
.call((), None)
.unwrap()
.cast_into::<SubWithoutInit>()
.unwrap();
// check Base.__init__ was called
assert_eq!(obj.as_super().borrow().num, 42);
});
}
#[pyclass(extends=Base)]
struct SubWithInit;
#[pymethods]
impl SubWithInit {
#[new]
fn new() -> (Self, Base) {
(Self, Base::new())
}
fn __init__(mut slf: pyo3::PyClassGuardMut<'_, Self>) {
slf.as_super().__init__(); // need to call super __init__ manually
slf.as_super().num += 1;
}
}
#[test]
fn test_subclass_with_init() {
Python::attach(|py| {
let typeobj = py.get_type::<SubWithInit>();
let obj = typeobj
.call((), None)
.unwrap()
.cast_into::<SubWithInit>()
.unwrap();
// check SubWithInit.__init__ was called, and Base.__init__ was only called once (through
// SubWithInit.__init__)
assert_eq!(obj.as_super().borrow().num, 43);
});
}
|