1pub mod gc;
20
21#[doc(hidden)]
22pub mod members;
23
24#[allow(clippy::module_inception)]
25mod py_class;
26
27#[cfg(feature = "python27-sys")]
28#[rustfmt::skip]
29mod py_class_impl2;
30
31#[cfg(feature = "python3-sys")]
32#[rustfmt::skip]
33mod py_class_impl3;
34
35#[doc(hidden)]
36pub mod slots;
37
38use std::{cell, mem, ptr};
39
40use crate::err::{self, PyResult};
41use crate::ffi;
42use crate::objects::{PyModule, PyObject, PyType};
43use crate::python::{self, Python, PythonObject};
44
45#[derive(Debug)]
47pub enum CompareOp {
48 Lt = ffi::Py_LT as isize,
49 Le = ffi::Py_LE as isize,
50 Eq = ffi::Py_EQ as isize,
51 Ne = ffi::Py_NE as isize,
52 Gt = ffi::Py_GT as isize,
53 Ge = ffi::Py_GE as isize,
54}
55
56pub trait PythonObjectFromPyClassMacro: python::PythonObjectWithTypeObject {
60 fn initialize(py: Python, module_name: Option<&str>) -> PyResult<PyType>;
64
65 fn add_to_module(py: Python, module: &PyModule) -> PyResult<()>;
67}
68
69#[inline]
70#[doc(hidden)]
71pub fn data_offset<T>(base_size: usize) -> usize {
72 let align = mem::align_of::<T>();
73 (base_size + align - 1) / align * align
75}
76
77#[inline]
78#[doc(hidden)]
79pub fn data_new_size<T>(base_size: usize) -> usize {
80 data_offset::<T>(base_size) + mem::size_of::<T>()
81}
82
83#[inline]
84#[doc(hidden)]
85pub unsafe fn data_get<'a, T>(_py: Python<'a>, obj: &'a PyObject, offset: usize) -> &'a T {
86 let ptr = (obj.as_ptr() as *const u8).add(offset) as *const T;
87 &*ptr
88}
89
90#[inline]
91#[doc(hidden)]
92pub unsafe fn data_init<'a, T>(_py: Python<'a>, obj: &'a PyObject, offset: usize, value: T)
93where
94 T: Send + 'static,
95{
96 let ptr = (obj.as_ptr() as *mut u8).add(offset) as *mut T;
97 ptr::write(ptr, value)
98}
99
100#[inline]
101#[doc(hidden)]
102pub unsafe fn data_drop<T>(_py: Python<'_>, obj: *mut ffi::PyObject, offset: usize) {
103 let ptr = (obj as *mut u8).add(offset) as *mut T;
104 ptr::drop_in_place(ptr)
105}
106
107#[inline]
108#[doc(hidden)]
109pub fn is_ready(_py: Python, ty: &ffi::PyTypeObject) -> bool {
110 (ty.tp_flags & ffi::Py_TPFLAGS_READY) != 0
111}
112
113pub trait BaseObject: PythonObject {
115 fn size() -> usize;
117
118 type InitType;
119
120 unsafe fn alloc(py: Python, ty: &PyType, init_val: Self::InitType) -> PyResult<PyObject>;
125
126 unsafe fn dealloc(py: Python, obj: *mut ffi::PyObject);
130}
131
132impl BaseObject for PyObject {
133 #[inline]
134 fn size() -> usize {
135 mem::size_of::<ffi::PyObject>()
136 }
137
138 type InitType = ();
139
140 unsafe fn alloc(py: Python, ty: &PyType, _init_val: ()) -> PyResult<PyObject> {
141 let ptr = ffi::PyType_GenericAlloc(ty.as_type_ptr(), 0);
142 err::result_from_owned_ptr(py, ptr)
144 }
145
146 unsafe fn dealloc(_py: Python, obj: *mut ffi::PyObject) {
147 let ty = ffi::Py_TYPE(obj);
151 if ffi::PyType_IS_GC(ty) != 0 {
152 ffi::PyObject_GC_Del(obj as *mut libc::c_void);
153 } else {
154 ffi::PyObject_Free(obj as *mut libc::c_void);
155 }
156 if ffi::PyType_HasFeature(ty, ffi::Py_TPFLAGS_HEAPTYPE) != 0 {
159 ffi::Py_DECREF(ty as *mut ffi::PyObject);
160 }
161 }
162}