pyo3/types/pysuper.rs
1use crate::instance::Bound;
2use crate::types::any::PyAnyMethods;
3use crate::types::PyType;
4use crate::PyTypeInfo;
5use crate::{PyAny, PyResult};
6
7/// Represents a Python `super` object.
8///
9/// Values of this type are accessed via PyO3's smart pointers, e.g. as
10/// [`Py<PySuper>`][crate::Py] or [`Bound<'py, PySuper>`][Bound].
11#[repr(transparent)]
12pub struct PySuper(PyAny);
13
14#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
15pyobject_native_type_core!(
16 PySuper,
17 pyobject_native_static_type_object!(crate::ffi::PySuper_Type),
18 "builtins",
19 "super"
20);
21
22#[cfg(any(Py_LIMITED_API, PyPy, GraalPy))]
23pyobject_native_type_core!(
24 PySuper,
25 |py| {
26 use crate::sync::PyOnceLock;
27 use crate::types::{PyType, PyTypeMethods};
28 use crate::Py;
29 static TYPE: PyOnceLock<Py<PyType>> = PyOnceLock::new();
30 TYPE.import(py, "builtins", "super").unwrap().as_type_ptr()
31 },
32 "builtins",
33 "super"
34);
35
36impl PySuper {
37 /// Constructs a new super object. More read about super object: [docs](https://docs.python.org/3/library/functions.html#super)
38 ///
39 /// # Examples
40 ///
41 /// ```rust,no_run
42 /// use pyo3::prelude::*;
43 ///
44 /// #[pyclass(subclass)]
45 /// struct BaseClass {
46 /// val1: usize,
47 /// }
48 ///
49 /// #[pymethods]
50 /// impl BaseClass {
51 /// #[new]
52 /// fn new() -> Self {
53 /// BaseClass { val1: 10 }
54 /// }
55 ///
56 /// pub fn method(&self) -> usize {
57 /// self.val1
58 /// }
59 /// }
60 ///
61 /// #[pyclass(extends=BaseClass)]
62 /// struct SubClass {}
63 ///
64 /// #[pymethods]
65 /// impl SubClass {
66 /// #[new]
67 /// fn new() -> (Self, BaseClass) {
68 /// (SubClass {}, BaseClass::new())
69 /// }
70 ///
71 /// fn method<'py>(self_: &Bound<'py, Self>) -> PyResult<Bound<'py, PyAny>> {
72 /// let super_ = self_.py_super()?;
73 /// super_.call_method("method", (), None)
74 /// }
75 /// }
76 /// ```
77 pub fn new<'py>(
78 ty: &Bound<'py, PyType>,
79 obj: &Bound<'py, PyAny>,
80 ) -> PyResult<Bound<'py, PySuper>> {
81 PySuper::type_object(ty.py()).call1((ty, obj)).map(|any| {
82 // Safety: super() always returns instance of super
83 unsafe { any.cast_into_unchecked() }
84 })
85 }
86}