| 1 | //! Various types defined by the Python interpreter such as `int`, `str` and `tuple`. |
| 2 | |
| 3 | pub use self::any::{PyAny, PyAnyMethods}; |
| 4 | pub use self::boolobject::{PyBool, PyBoolMethods}; |
| 5 | pub use self::bytearray::{PyByteArray, PyByteArrayMethods}; |
| 6 | pub use self::bytes::{PyBytes, PyBytesMethods}; |
| 7 | pub use self::capsule::{PyCapsule, PyCapsuleMethods}; |
| 8 | #[cfg (all(not(Py_LIMITED_API), not(PyPy), not(GraalPy)))] |
| 9 | pub use self::code::PyCode; |
| 10 | pub use self::complex::{PyComplex, PyComplexMethods}; |
| 11 | #[cfg (not(Py_LIMITED_API))] |
| 12 | #[allow (deprecated)] |
| 13 | pub use self::datetime::{ |
| 14 | timezone_utc, timezone_utc_bound, PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, |
| 15 | PyTime, PyTimeAccess, PyTzInfo, PyTzInfoAccess, |
| 16 | }; |
| 17 | pub use self::dict::{IntoPyDict, PyDict, PyDictMethods}; |
| 18 | #[cfg (not(any(PyPy, GraalPy)))] |
| 19 | pub use self::dict::{PyDictItems, PyDictKeys, PyDictValues}; |
| 20 | pub use self::ellipsis::PyEllipsis; |
| 21 | pub use self::float::{PyFloat, PyFloatMethods}; |
| 22 | #[cfg (all(not(Py_LIMITED_API), not(PyPy), not(GraalPy)))] |
| 23 | pub use self::frame::PyFrame; |
| 24 | pub use self::frozenset::{PyFrozenSet, PyFrozenSetBuilder, PyFrozenSetMethods}; |
| 25 | pub use self::function::PyCFunction; |
| 26 | #[cfg (all(not(Py_LIMITED_API), not(all(PyPy, not(Py_3_8)))))] |
| 27 | pub use self::function::PyFunction; |
| 28 | #[cfg (Py_3_9)] |
| 29 | pub use self::genericalias::PyGenericAlias; |
| 30 | pub use self::iterator::PyIterator; |
| 31 | pub use self::list::{PyList, PyListMethods}; |
| 32 | pub use self::mapping::{PyMapping, PyMappingMethods}; |
| 33 | pub use self::mappingproxy::PyMappingProxy; |
| 34 | pub use self::memoryview::PyMemoryView; |
| 35 | pub use self::module::{PyModule, PyModuleMethods}; |
| 36 | pub use self::none::PyNone; |
| 37 | pub use self::notimplemented::PyNotImplemented; |
| 38 | #[allow (deprecated)] |
| 39 | pub use self::num::{PyInt, PyLong}; |
| 40 | #[cfg (not(any(PyPy, GraalPy)))] |
| 41 | pub use self::pysuper::PySuper; |
| 42 | pub use self::sequence::{PySequence, PySequenceMethods}; |
| 43 | pub use self::set::{PySet, PySetMethods}; |
| 44 | pub use self::slice::{PySlice, PySliceIndices, PySliceMethods}; |
| 45 | #[cfg (not(Py_LIMITED_API))] |
| 46 | pub use self::string::PyStringData; |
| 47 | #[allow (deprecated)] |
| 48 | pub use self::string::{PyString, PyStringMethods, PyUnicode}; |
| 49 | pub use self::traceback::{PyTraceback, PyTracebackMethods}; |
| 50 | pub use self::tuple::{PyTuple, PyTupleMethods}; |
| 51 | pub use self::typeobject::{PyType, PyTypeMethods}; |
| 52 | pub use self::weakref::{PyWeakref, PyWeakrefMethods, PyWeakrefProxy, PyWeakrefReference}; |
| 53 | |
| 54 | /// Iteration over Python collections. |
| 55 | /// |
| 56 | /// When working with a Python collection, one approach is to convert it to a Rust collection such |
| 57 | /// as `Vec` or `HashMap`. However this is a relatively expensive operation. If you just want to |
| 58 | /// visit all their items, consider iterating over the collections directly: |
| 59 | /// |
| 60 | /// # Examples |
| 61 | /// |
| 62 | /// ```rust |
| 63 | /// use pyo3::prelude::*; |
| 64 | /// use pyo3::types::PyDict; |
| 65 | /// use pyo3::ffi::c_str; |
| 66 | /// |
| 67 | /// # pub fn main() -> PyResult<()> { |
| 68 | /// Python::with_gil(|py| { |
| 69 | /// let dict = py.eval(c_str!("{'a':'b', 'c':'d'}" ), None, None)?.downcast_into::<PyDict>()?; |
| 70 | /// |
| 71 | /// for (key, value) in &dict { |
| 72 | /// println!("key: {}, value: {}" , key, value); |
| 73 | /// } |
| 74 | /// |
| 75 | /// Ok(()) |
| 76 | /// }) |
| 77 | /// # } |
| 78 | /// ``` |
| 79 | /// |
| 80 | /// If PyO3 detects that the collection is mutated during iteration, it will panic. |
| 81 | /// |
| 82 | /// These iterators use Python's C-API directly. However in certain cases, like when compiling for |
| 83 | /// the Limited API and PyPy, the underlying structures are opaque and that may not be possible. |
| 84 | /// In these cases the iterators are implemented by forwarding to [`PyIterator`]. |
| 85 | pub mod iter { |
| 86 | pub use super::dict::BoundDictIterator; |
| 87 | pub use super::frozenset::BoundFrozenSetIterator; |
| 88 | pub use super::list::BoundListIterator; |
| 89 | pub use super::set::BoundSetIterator; |
| 90 | pub use super::tuple::{BorrowedTupleIterator, BoundTupleIterator}; |
| 91 | } |
| 92 | |
| 93 | /// Python objects that have a base type. |
| 94 | /// |
| 95 | /// This marks types that can be upcast into a [`PyAny`] and used in its place. |
| 96 | /// This essentially includes every Python object except [`PyAny`] itself. |
| 97 | /// |
| 98 | /// This is used to provide the [`Deref<Target = Bound<'_, PyAny>>`](std::ops::Deref) |
| 99 | /// implementations for [`Bound<'_, T>`](crate::Bound). |
| 100 | /// |
| 101 | /// Users should not need to implement this trait directly. It's implementation |
| 102 | /// is provided by the [`#[pyclass]`](macro@crate::pyclass) attribute. |
| 103 | /// |
| 104 | /// ## Note |
| 105 | /// This is needed because the compiler currently tries to figure out all the |
| 106 | /// types in a deref-chain before starting to look for applicable method calls. |
| 107 | /// So we need to prevent [`Bound<'_, PyAny`](crate::Bound) dereferencing to |
| 108 | /// itself in order to avoid running into the recursion limit. This trait is |
| 109 | /// used to exclude this from our blanket implementation. See [this Rust |
| 110 | /// issue][1] for more details. If the compiler limitation gets resolved, this |
| 111 | /// trait will be removed. |
| 112 | /// |
| 113 | /// [1]: https://github.com/rust-lang/rust/issues/19509 |
| 114 | pub trait DerefToPyAny { |
| 115 | // Empty. |
| 116 | } |
| 117 | |
| 118 | // Implementations core to all native types except for PyAny (because they don't |
| 119 | // make sense on PyAny / have different implementations). |
| 120 | #[doc (hidden)] |
| 121 | #[macro_export ] |
| 122 | macro_rules! pyobject_native_type_named ( |
| 123 | ($name:ty $(;$generics:ident)*) => { |
| 124 | impl $crate::types::DerefToPyAny for $name {} |
| 125 | }; |
| 126 | ); |
| 127 | |
| 128 | #[doc (hidden)] |
| 129 | #[macro_export ] |
| 130 | macro_rules! pyobject_native_static_type_object( |
| 131 | ($typeobject:expr) => { |
| 132 | |_py| { |
| 133 | #[allow(unused_unsafe)] // https://github.com/rust-lang/rust/pull/125834 |
| 134 | unsafe { ::std::ptr::addr_of_mut!($typeobject) } |
| 135 | } |
| 136 | }; |
| 137 | ); |
| 138 | |
| 139 | #[doc (hidden)] |
| 140 | #[macro_export ] |
| 141 | macro_rules! pyobject_native_type_info( |
| 142 | ($name:ty, $typeobject:expr, $module:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => { |
| 143 | unsafe impl<$($generics,)*> $crate::type_object::PyTypeInfo for $name { |
| 144 | const NAME: &'static str = stringify!($name); |
| 145 | const MODULE: ::std::option::Option<&'static str> = $module; |
| 146 | |
| 147 | #[inline] |
| 148 | #[allow(clippy::redundant_closure_call)] |
| 149 | fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject { |
| 150 | $typeobject(py) |
| 151 | } |
| 152 | |
| 153 | $( |
| 154 | #[inline] |
| 155 | fn is_type_of(obj: &$crate::Bound<'_, $crate::PyAny>) -> bool { |
| 156 | #[allow(unused_unsafe)] |
| 157 | unsafe { $checkfunction(obj.as_ptr()) > 0 } |
| 158 | } |
| 159 | )? |
| 160 | } |
| 161 | |
| 162 | impl $name { |
| 163 | #[doc(hidden)] |
| 164 | pub const _PYO3_DEF: $crate::impl_::pymodule::AddTypeToModule<Self> = $crate::impl_::pymodule::AddTypeToModule::new(); |
| 165 | } |
| 166 | }; |
| 167 | ); |
| 168 | |
| 169 | /// Declares all of the boilerplate for Python types. |
| 170 | #[doc (hidden)] |
| 171 | #[macro_export ] |
| 172 | macro_rules! pyobject_native_type_core { |
| 173 | ($name:ty, $typeobject:expr, #module=$module:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => { |
| 174 | $crate::pyobject_native_type_named!($name $(;$generics)*); |
| 175 | $crate::pyobject_native_type_info!($name, $typeobject, $module $(, #checkfunction=$checkfunction)? $(;$generics)*); |
| 176 | }; |
| 177 | ($name:ty, $typeobject:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => { |
| 178 | $crate::pyobject_native_type_core!($name, $typeobject, #module=::std::option::Option::Some("builtins" ) $(, #checkfunction=$checkfunction)? $(;$generics)*); |
| 179 | }; |
| 180 | } |
| 181 | |
| 182 | #[doc (hidden)] |
| 183 | #[macro_export ] |
| 184 | macro_rules! pyobject_subclassable_native_type { |
| 185 | ($name:ty, $layout:path $(;$generics:ident)*) => { |
| 186 | #[cfg(not(Py_LIMITED_API))] |
| 187 | impl<$($generics,)*> $crate::impl_::pyclass::PyClassBaseType for $name { |
| 188 | type LayoutAsBase = $crate::impl_::pycell::PyClassObjectBase<$layout>; |
| 189 | type BaseNativeType = $name; |
| 190 | type Initializer = $crate::impl_::pyclass_init::PyNativeTypeInitializer<Self>; |
| 191 | type PyClassMutability = $crate::pycell::impl_::ImmutableClass; |
| 192 | } |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | #[doc (hidden)] |
| 197 | #[macro_export ] |
| 198 | macro_rules! pyobject_native_type_sized { |
| 199 | ($name:ty, $layout:path $(;$generics:ident)*) => { |
| 200 | unsafe impl $crate::type_object::PyLayout<$name> for $layout {} |
| 201 | impl $crate::type_object::PySizedLayout<$name> for $layout {} |
| 202 | }; |
| 203 | } |
| 204 | |
| 205 | /// Declares all of the boilerplate for Python types which can be inherited from (because the exact |
| 206 | /// Python layout is known). |
| 207 | #[doc (hidden)] |
| 208 | #[macro_export ] |
| 209 | macro_rules! pyobject_native_type { |
| 210 | ($name:ty, $layout:path, $typeobject:expr $(, #module=$module:expr)? $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => { |
| 211 | $crate::pyobject_native_type_core!($name, $typeobject $(, #module=$module)? $(, #checkfunction=$checkfunction)? $(;$generics)*); |
| 212 | // To prevent inheriting native types with ABI3 |
| 213 | #[cfg(not(Py_LIMITED_API))] |
| 214 | $crate::pyobject_native_type_sized!($name, $layout $(;$generics)*); |
| 215 | }; |
| 216 | } |
| 217 | |
| 218 | pub(crate) mod any; |
| 219 | pub(crate) mod boolobject; |
| 220 | pub(crate) mod bytearray; |
| 221 | pub(crate) mod bytes; |
| 222 | pub(crate) mod capsule; |
| 223 | #[cfg (all(not(Py_LIMITED_API), not(PyPy), not(GraalPy)))] |
| 224 | mod code; |
| 225 | pub(crate) mod complex; |
| 226 | #[cfg (not(Py_LIMITED_API))] |
| 227 | pub(crate) mod datetime; |
| 228 | #[cfg (all(Py_LIMITED_API, any(feature = "chrono" , feature = "jiff-02" )))] |
| 229 | pub(crate) mod datetime_abi3; |
| 230 | pub(crate) mod dict; |
| 231 | mod ellipsis; |
| 232 | pub(crate) mod float; |
| 233 | #[cfg (all(not(Py_LIMITED_API), not(PyPy), not(GraalPy)))] |
| 234 | mod frame; |
| 235 | pub(crate) mod frozenset; |
| 236 | mod function; |
| 237 | #[cfg (Py_3_9)] |
| 238 | pub(crate) mod genericalias; |
| 239 | pub(crate) mod iterator; |
| 240 | pub(crate) mod list; |
| 241 | pub(crate) mod mapping; |
| 242 | pub(crate) mod mappingproxy; |
| 243 | mod memoryview; |
| 244 | pub(crate) mod module; |
| 245 | mod none; |
| 246 | mod notimplemented; |
| 247 | mod num; |
| 248 | #[cfg (not(any(PyPy, GraalPy)))] |
| 249 | mod pysuper; |
| 250 | pub(crate) mod sequence; |
| 251 | pub(crate) mod set; |
| 252 | pub(crate) mod slice; |
| 253 | pub(crate) mod string; |
| 254 | pub(crate) mod traceback; |
| 255 | pub(crate) mod tuple; |
| 256 | pub(crate) mod typeobject; |
| 257 | pub(crate) mod weakref; |
| 258 | |