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