pyo3_ffi/cpython/
methodobject.rs

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