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
use crate::instance::Bound;
use crate::types::any::PyAnyMethods;
use crate::types::PyType;
use crate::PyTypeInfo;
use crate::{PyAny, PyResult};
/// Represents a Python `super` object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PySuper>`][crate::Py] or [`Bound<'py, PySuper>`][Bound].
#[repr(transparent)]
pub struct PySuper(PyAny);
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
pyobject_native_type_core!(
PySuper,
pyobject_native_static_type_object!(crate::ffi::PySuper_Type),
"builtins",
"super"
);
#[cfg(any(Py_LIMITED_API, PyPy, GraalPy))]
pyobject_native_type_core!(
PySuper,
|py| {
use crate::sync::PyOnceLock;
use crate::types::{PyType, PyTypeMethods};
use crate::Py;
static TYPE: PyOnceLock<Py<PyType>> = PyOnceLock::new();
TYPE.import(py, "builtins", "super").unwrap().as_type_ptr()
},
"builtins",
"super"
);
impl PySuper {
/// Constructs a new super object. More read about super object: [docs](https://docs.python.org/3/library/functions.html#super)
///
/// # Examples
///
/// ```rust,no_run
/// use pyo3::prelude::*;
///
/// #[pyclass(subclass)]
/// struct BaseClass {
/// val1: usize,
/// }
///
/// #[pymethods]
/// impl BaseClass {
/// #[new]
/// fn new() -> Self {
/// BaseClass { val1: 10 }
/// }
///
/// pub fn method(&self) -> usize {
/// self.val1
/// }
/// }
///
/// #[pyclass(extends=BaseClass)]
/// struct SubClass {}
///
/// #[pymethods]
/// impl SubClass {
/// #[new]
/// fn new() -> (Self, BaseClass) {
/// (SubClass {}, BaseClass::new())
/// }
///
/// fn method<'py>(self_: &Bound<'py, Self>) -> PyResult<Bound<'py, PyAny>> {
/// let super_ = self_.py_super()?;
/// super_.call_method("method", (), None)
/// }
/// }
/// ```
pub fn new<'py>(
ty: &Bound<'py, PyType>,
obj: &Bound<'py, PyAny>,
) -> PyResult<Bound<'py, PySuper>> {
PySuper::type_object(ty.py()).call1((ty, obj)).map(|any| {
// Safety: super() always returns instance of super
unsafe { any.cast_into_unchecked() }
})
}
}