python3_sys/
methodobject.rs

1use core::{mem, ptr};
2use libc::{c_char, c_int};
3
4use crate::object::{PyObject, PyTypeObject, Py_TYPE};
5
6#[cfg_attr(windows, link(name = "pythonXY"))]
7extern "C" {
8    pub static mut PyCFunction_Type: PyTypeObject;
9}
10
11#[inline(always)]
12pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
13    (Py_TYPE(op) == &mut PyCFunction_Type) as c_int
14}
15
16pub type PyCFunction =
17    unsafe extern "C" fn(slf: *mut PyObject, args: *mut PyObject) -> *mut PyObject;
18
19#[cfg(all(Py_3_6, not(Py_LIMITED_API), not(Py_3_7)))]
20pub type _PyCFunctionFast = unsafe extern "C" fn(
21    slf: *mut PyObject,
22    args: *mut *mut PyObject,
23    nargs: crate::pyport::Py_ssize_t,
24    kwnames: *mut PyObject,
25) -> *mut PyObject;
26
27#[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
28pub type _PyCFunctionFast = unsafe extern "C" fn(
29    slf: *mut PyObject,
30    args: *const *mut PyObject,
31    nargs: crate::pyport::Py_ssize_t,
32) -> *mut PyObject;
33
34pub type PyCFunctionWithKeywords = unsafe extern "C" fn(
35    slf: *mut PyObject,
36    args: *mut PyObject,
37    kwds: *mut PyObject,
38) -> *mut PyObject;
39
40#[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
41pub type _PyCFunctionFastWithKeywords = unsafe extern "C" fn(
42    slf: *mut PyObject,
43    args: *const *mut PyObject,
44    nargs: crate::pyport::Py_ssize_t,
45    kwnames: *mut PyObject,
46) -> *mut PyObject;
47
48#[cfg(not(Py_3_9))]
49pub type PyNoArgsFunction = unsafe extern "C" fn(slf: *mut PyObject) -> *mut PyObject;
50
51#[cfg_attr(windows, link(name = "pythonXY"))]
52extern "C" {
53    pub fn PyCFunction_GetFunction(f: *mut PyObject) -> Option<PyCFunction>;
54    pub fn PyCFunction_GetSelf(f: *mut PyObject) -> *mut PyObject;
55    pub fn PyCFunction_GetFlags(f: *mut PyObject) -> c_int;
56    #[deprecated(since = "0.5.2", note = "Deprecated since Python 3.9")]
57    pub fn PyCFunction_Call(
58        f: *mut PyObject,
59        args: *mut PyObject,
60        kwds: *mut PyObject,
61    ) -> *mut PyObject;
62}
63
64#[repr(C)]
65#[derive(Copy)]
66pub struct PyMethodDef {
67    pub ml_name: *const c_char,
68    pub ml_meth: Option<PyCFunction>,
69    pub ml_flags: c_int,
70    pub ml_doc: *const c_char,
71}
72
73impl Clone for PyMethodDef {
74    #[inline]
75    fn clone(&self) -> PyMethodDef {
76        *self
77    }
78}
79impl Default for PyMethodDef {
80    fn default() -> PyMethodDef {
81        unsafe { mem::zeroed() }
82    }
83}
84
85#[inline(always)]
86pub unsafe fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject {
87    PyCFunction_NewEx(ml, slf, ptr::null_mut())
88}
89
90#[cfg_attr(windows, link(name = "pythonXY"))]
91extern "C" {
92    pub fn PyCFunction_NewEx(
93        arg1: *mut PyMethodDef,
94        arg2: *mut PyObject,
95        arg3: *mut PyObject,
96    ) -> *mut PyObject;
97
98    #[cfg(Py_3_9)]
99    pub fn PyCMethod_New(
100        arg1: *mut PyMethodDef,
101        arg2: *mut PyObject,
102        arg3: *mut PyObject,
103        arg4: *mut PyTypeObject,
104    ) -> *mut PyObject;
105}
106
107/* Flag passed to newmethodobject */
108pub const METH_VARARGS: c_int = 0x0001;
109pub const METH_KEYWORDS: c_int = 0x0002;
110/* METH_NOARGS and METH_O must not be combined with the flags above. */
111pub const METH_NOARGS: c_int = 0x0004;
112pub const METH_O: c_int = 0x0008;
113
114/* METH_CLASS and METH_STATIC are a little different; these control
115the construction of methods for a class.  These cannot be used for
116functions in modules. */
117pub const METH_CLASS: c_int = 0x0010;
118pub const METH_STATIC: c_int = 0x0020;
119
120/* METH_COEXIST allows a method to be entered eventhough a slot has
121already filled the entry.  When defined, the flag allows a separate
122method, "__contains__" for example, to coexist with a defined
123slot like sq_contains. */
124
125pub const METH_COEXIST: c_int = 0x0040;
126
127#[cfg(any(Py_3_10, all(Py_3_6, not(Py_LIMITED_API))))]
128pub const METH_FASTCALL: c_int = 0x0080;
129
130// METH_STACKLESS: This bit is preserved for Stackless Python
131
132#[cfg(all(Py_3_9))]
133pub const METH_METHOD: c_int = 0x0200;
134
135#[cfg(not(Py_3_9))]
136#[cfg_attr(windows, link(name = "pythonXY"))]
137extern "C" {
138    pub fn PyCFunction_ClearFreeList() -> c_int;
139}