Skip to main content

pyo3_ffi/cpython/
methodobject.rs

1use crate::object::*;
2#[cfg(not(GraalPy))]
3use crate::{PyCFunctionObject, PyMethodDefPointer, METH_METHOD, METH_STATIC};
4use std::ffi::c_int;
5
6#[cfg(not(GraalPy))]
7pub struct PyCMethodObject {
8    pub func: PyCFunctionObject,
9    pub mm_class: *mut PyTypeObject,
10}
11
12extern_libpython! {
13    pub static mut PyCMethod_Type: PyTypeObject;
14}
15
16#[inline]
17pub unsafe fn PyCMethod_CheckExact(op: *mut PyObject) -> c_int {
18    (Py_TYPE(op) == &raw mut PyCMethod_Type) as c_int
19}
20
21#[inline]
22pub unsafe fn PyCMethod_Check(op: *mut PyObject) -> c_int {
23    PyObject_TypeCheck(op, &raw mut PyCMethod_Type)
24}
25
26#[cfg(not(GraalPy))]
27#[inline]
28pub unsafe fn PyCFunction_GET_FUNCTION(func: *mut PyObject) -> PyMethodDefPointer {
29    debug_assert_eq!(PyCMethod_Check(func), 1);
30
31    let func = func.cast::<PyCFunctionObject>();
32    (*(*func).m_ml).ml_meth
33}
34
35#[cfg(not(GraalPy))]
36#[inline]
37pub unsafe fn PyCFunction_GET_SELF(func: *mut PyObject) -> *mut PyObject {
38    debug_assert_eq!(PyCMethod_Check(func), 1);
39
40    let func = func.cast::<PyCFunctionObject>();
41    if (*(*func).m_ml).ml_flags & METH_STATIC != 0 {
42        std::ptr::null_mut()
43    } else {
44        (*func).m_self
45    }
46}
47
48#[cfg(not(GraalPy))]
49#[inline]
50pub unsafe fn PyCFunction_GET_FLAGS(func: *mut PyObject) -> c_int {
51    debug_assert_eq!(PyCMethod_Check(func), 1);
52
53    let func = func.cast::<PyCFunctionObject>();
54    (*(*func).m_ml).ml_flags
55}
56
57#[cfg(not(GraalPy))]
58#[inline]
59pub unsafe fn PyCFunction_GET_CLASS(func: *mut PyObject) -> *mut PyTypeObject {
60    debug_assert_eq!(PyCMethod_Check(func), 1);
61
62    let func = func.cast::<PyCFunctionObject>();
63    if (*(*func).m_ml).ml_flags & METH_METHOD != 0 {
64        let func = func.cast::<PyCMethodObject>();
65        (*func).mm_class
66    } else {
67        std::ptr::null_mut()
68    }
69}
⚠️ Internal Docs ⚠️ Not Public API 👉 Official Docs Here