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    /// Deprecated form of `PySuper::new_bound`.
21    #[cfg(feature = "gil-refs")]
22    #[deprecated(
23        since = "0.21.0",
24        note = "`PySuper::new` will be replaced by `PySuper::new_bound` in a future PyO3 version"
25    )]
26    pub fn new<'py>(ty: &'py PyType, obj: &'py PyAny) -> PyResult<&'py PySuper> {
27        use crate::PyNativeType;
28        Self::new_bound(&ty.as_borrowed(), &obj.as_borrowed()).map(Bound::into_gil_ref)
29    }
30
31    /// Constructs a new super object. More read about super object: [docs](https://docs.python.org/3/library/functions.html#super)
32    ///
33    /// # Examples
34    ///
35    /// ```rust
36    /// use pyo3::prelude::*;
37    ///
38    /// #[pyclass(subclass)]
39    /// struct BaseClass {
40    ///     val1: usize,
41    /// }
42    ///
43    /// #[pymethods]
44    /// impl BaseClass {
45    ///     #[new]
46    ///     fn new() -> Self {
47    ///         BaseClass { val1: 10 }
48    ///     }
49    ///
50    ///     pub fn method(&self) -> usize {
51    ///         self.val1
52    ///     }
53    /// }
54    ///
55    /// #[pyclass(extends=BaseClass)]
56    /// struct SubClass {}
57    ///
58    /// #[pymethods]
59    /// impl SubClass {
60    ///     #[new]
61    ///     fn new() -> (Self, BaseClass) {
62    ///         (SubClass {}, BaseClass::new())
63    ///     }
64    ///
65    ///     fn method<'py>(self_: &Bound<'py, Self>) -> PyResult<Bound<'py, PyAny>> {
66    ///         let super_ = self_.py_super()?;
67    ///         super_.call_method("method", (), None)
68    ///     }
69    /// }
70    /// ```
71    pub fn new_bound<'py>(
72        ty: &Bound<'py, PyType>,
73        obj: &Bound<'py, PyAny>,
74    ) -> PyResult<Bound<'py, PySuper>> {
75        PySuper::type_object_bound(ty.py())
76            .call1((ty, obj))
77            .map(|any| {
78                // Safety: super() always returns instance of super
79                unsafe { any.downcast_into_unchecked() }
80            })
81    }
82}