/src/ffi/methodobject.rs

https://github.com/PyO3/pyo3 · Rust · 138 lines · 103 code · 21 blank · 14 comment · 2 complexity · 7ee2127dbba62fb4bb0f49b9177443d3 MD5 · raw file

  1. use crate::ffi::object::{PyObject, PyTypeObject, Py_TYPE};
  2. use std::mem;
  3. use std::os::raw::{c_char, c_int};
  4. #[cfg_attr(windows, link(name = "pythonXY"))]
  5. extern "C" {
  6. #[cfg_attr(PyPy, link_name = "PyPyCFunction_Type")]
  7. pub static mut PyCFunction_Type: PyTypeObject;
  8. }
  9. #[inline]
  10. pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
  11. (Py_TYPE(op) == &mut PyCFunction_Type) as c_int
  12. }
  13. pub type PyCFunction =
  14. unsafe extern "C" fn(slf: *mut PyObject, args: *mut PyObject) -> *mut PyObject;
  15. #[cfg(all(Py_3_8, not(Py_LIMITED_API)))]
  16. #[cfg_attr(Py_3_8, link_name = "_PyObject_Vectorcall")]
  17. pub type PyObject_Vectorcall = unsafe extern "C" fn(
  18. slf: *mut PyObject,
  19. // positional and keyword arguments
  20. args: *const *mut PyObject,
  21. // number of position arguments in args, after which values are kwargs
  22. nargs: crate::ffi::pyport::Py_ssize_t,
  23. // tuple of kwargs, if given, or null
  24. kwnames: *mut PyObject,
  25. ) -> *mut PyObject;
  26. #[cfg(all(Py_3_8, not(Py_LIMITED_API)))]
  27. #[cfg_attr(Py_3_8, link_name = "PyVectorcall_Call")]
  28. pub type PyVectorcall_Call = unsafe extern "C" fn(
  29. obj: *mut PyObject,
  30. tuple: *mut PyObject,
  31. dict: *mut PyObject,
  32. ) -> *mut PyObject;
  33. #[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
  34. const PY_VECTORCALL_ARGUMENTS_OFFSET: crate::ffi::pyport::Py_ssize_t =
  35. 1 << (8 * std::mem::size_of::<usize>() - 1);
  36. #[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
  37. #[inline(always)]
  38. pub unsafe fn PyVectorcall_NARGS(
  39. n: crate::ffi::pyport::Py_ssize_t,
  40. ) -> crate::ffi::pyport::Py_ssize_t {
  41. n & !PY_VECTORCALL_ARGUMENTS_OFFSET
  42. }
  43. #[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
  44. pub type _PyCFunctionFast = unsafe extern "C" fn(
  45. slf: *mut PyObject,
  46. args: *mut *mut PyObject,
  47. nargs: crate::ffi::pyport::Py_ssize_t,
  48. kwnames: *mut PyObject,
  49. ) -> *mut PyObject;
  50. pub type PyCFunctionWithKeywords = unsafe extern "C" fn(
  51. slf: *mut PyObject,
  52. args: *mut PyObject,
  53. kwds: *mut PyObject,
  54. ) -> *mut PyObject;
  55. extern "C" {
  56. #[cfg_attr(PyPy, link_name = "PyPyCFunction_GetFunction")]
  57. pub fn PyCFunction_GetFunction(f: *mut PyObject) -> Option<PyCFunction>;
  58. pub fn PyCFunction_GetSelf(f: *mut PyObject) -> *mut PyObject;
  59. pub fn PyCFunction_GetFlags(f: *mut PyObject) -> c_int;
  60. pub fn PyCFunction_Call(
  61. f: *mut PyObject,
  62. args: *mut PyObject,
  63. kwds: *mut PyObject,
  64. ) -> *mut PyObject;
  65. }
  66. #[repr(C)]
  67. #[derive(Copy, Clone)]
  68. pub struct PyMethodDef {
  69. pub ml_name: *const c_char,
  70. pub ml_meth: Option<PyCFunction>,
  71. pub ml_flags: c_int,
  72. pub ml_doc: *const c_char,
  73. }
  74. pub const PyMethodDef_INIT: PyMethodDef = PyMethodDef {
  75. ml_name: ::std::ptr::null(),
  76. ml_meth: None,
  77. ml_flags: 0,
  78. ml_doc: ::std::ptr::null(),
  79. };
  80. impl Default for PyMethodDef {
  81. fn default() -> PyMethodDef {
  82. unsafe { mem::zeroed() }
  83. }
  84. }
  85. extern "C" {
  86. #[cfg_attr(PyPy, link_name = "PyPyCFunction_NewEx")]
  87. pub fn PyCFunction_NewEx(
  88. ml: *mut PyMethodDef,
  89. slf: *mut PyObject,
  90. module: *mut PyObject,
  91. ) -> *mut PyObject;
  92. #[cfg_attr(PyPy, link_name = "PyPyCFunction_NewEx")]
  93. pub fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject;
  94. }
  95. /* Flag passed to newmethodobject */
  96. pub const METH_VARARGS: c_int = 0x0001;
  97. pub const METH_KEYWORDS: c_int = 0x0002;
  98. /* METH_NOARGS and METH_O must not be combined with the flags above. */
  99. pub const METH_NOARGS: c_int = 0x0004;
  100. pub const METH_O: c_int = 0x0008;
  101. /* METH_CLASS and METH_STATIC are a little different; these control
  102. the construction of methods for a class. These cannot be used for
  103. functions in modules. */
  104. pub const METH_CLASS: c_int = 0x0010;
  105. pub const METH_STATIC: c_int = 0x0020;
  106. /* METH_COEXIST allows a method to be entered eventhough a slot has
  107. already filled the entry. When defined, the flag allows a separate
  108. method, "__contains__" for example, to coexist with a defined
  109. slot like sq_contains. */
  110. pub const METH_COEXIST: c_int = 0x0040;
  111. /* METH_FASTCALL indicates the PEP 590 Vectorcall calling format. It may
  112. be specified alone or with METH_KEYWORDS. */
  113. #[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
  114. pub const METH_FASTCALL: c_int = 0x0080;
  115. extern "C" {
  116. pub fn PyCFunction_ClearFreeList() -> c_int;
  117. }