Skip to main content

pyforge_ffi/cpython/
methodobject.rs

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