pyo3/types/
pysuper.rs

1use crate::instance::Bound;
2use crate::types::any::PyAnyMethods;
3use crate::types::PyType;
4use crate::{ffi, 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
14pyobject_native_type_core!(
15    PySuper,
16    pyobject_native_static_type_object!(ffi::PySuper_Type)
17);
18
19impl PySuper {
20    /// Constructs a new super object. More read about super object: [docs](https://docs.python.org/3/library/functions.html#super)
21    ///
22    /// # Examples
23    ///
24    /// ```rust
25    /// use pyo3::prelude::*;
26    ///
27    /// #[pyclass(subclass)]
28    /// struct BaseClass {
29    ///     val1: usize,
30    /// }
31    ///
32    /// #[pymethods]
33    /// impl BaseClass {
34    ///     #[new]
35    ///     fn new() -> Self {
36    ///         BaseClass { val1: 10 }
37    ///     }
38    ///
39    ///     pub fn method(&self) -> usize {
40    ///         self.val1
41    ///     }
42    /// }
43    ///
44    /// #[pyclass(extends=BaseClass)]
45    /// struct SubClass {}
46    ///
47    /// #[pymethods]
48    /// impl SubClass {
49    ///     #[new]
50    ///     fn new() -> (Self, BaseClass) {
51    ///         (SubClass {}, BaseClass::new())
52    ///     }
53    ///
54    ///     fn method<'py>(self_: &Bound<'py, Self>) -> PyResult<Bound<'py, PyAny>> {
55    ///         let super_ = self_.py_super()?;
56    ///         super_.call_method("method", (), None)
57    ///     }
58    /// }
59    /// ```
60    pub fn new<'py>(
61        ty: &Bound<'py, PyType>,
62        obj: &Bound<'py, PyAny>,
63    ) -> PyResult<Bound<'py, PySuper>> {
64        PySuper::type_object(ty.py()).call1((ty, obj)).map(|any| {
65            // Safety: super() always returns instance of super
66            unsafe { any.downcast_into_unchecked() }
67        })
68    }
69
70    /// Deprecated name for [`PySuper::new`].
71    #[deprecated(since = "0.23.0", note = "renamed to `PySuper::new`")]
72    #[inline]
73    pub fn new_bound<'py>(
74        ty: &Bound<'py, PyType>,
75        obj: &Bound<'py, PyAny>,
76    ) -> PyResult<Bound<'py, PySuper>> {
77        Self::new(ty, obj)
78    }
79}