1 | //! Various types defined by the Python interpreter such as `int`, `str` and `tuple`. |
2 | |
3 | pub use self::any::PyAny; |
4 | pub use self::boolobject::PyBool; |
5 | pub use self::bytearray::PyByteArray; |
6 | pub use self::bytes::PyBytes; |
7 | pub use self::capsule::PyCapsule; |
8 | #[cfg (not(Py_LIMITED_API))] |
9 | pub use self::code::PyCode; |
10 | pub use self::complex::PyComplex; |
11 | #[cfg (not(Py_LIMITED_API))] |
12 | pub use self::datetime::{ |
13 | timezone_utc, PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime, PyTimeAccess, |
14 | PyTzInfo, PyTzInfoAccess, |
15 | }; |
16 | pub use self::dict::{IntoPyDict, PyDict}; |
17 | #[cfg (not(PyPy))] |
18 | pub use self::dict::{PyDictItems, PyDictKeys, PyDictValues}; |
19 | pub use self::ellipsis::PyEllipsis; |
20 | pub use self::floatob::PyFloat; |
21 | #[cfg (all(not(Py_LIMITED_API), not(PyPy)))] |
22 | pub use self::frame::PyFrame; |
23 | pub use self::frozenset::{PyFrozenSet, PyFrozenSetBuilder}; |
24 | pub use self::function::PyCFunction; |
25 | #[cfg (all(not(Py_LIMITED_API), not(PyPy)))] |
26 | pub use self::function::PyFunction; |
27 | pub use self::iterator::PyIterator; |
28 | pub use self::list::PyList; |
29 | pub use self::mapping::PyMapping; |
30 | pub use self::module::PyModule; |
31 | pub use self::none::PyNone; |
32 | pub use self::notimplemented::PyNotImplemented; |
33 | pub use self::num::PyLong; |
34 | pub use self::num::PyLong as PyInt; |
35 | #[cfg (not(PyPy))] |
36 | pub use self::pysuper::PySuper; |
37 | pub use self::sequence::PySequence; |
38 | pub use self::set::PySet; |
39 | pub use self::slice::{PySlice, PySliceIndices}; |
40 | #[cfg (not(Py_LIMITED_API))] |
41 | pub use self::string::PyStringData; |
42 | pub use self::string::{PyString, PyString as PyUnicode}; |
43 | pub use self::traceback::PyTraceback; |
44 | pub use self::tuple::PyTuple; |
45 | pub use self::typeobject::PyType; |
46 | |
47 | /// Iteration over Python collections. |
48 | /// |
49 | /// When working with a Python collection, one approach is to convert it to a Rust collection such |
50 | /// as `Vec` or `HashMap`. However this is a relatively expensive operation. If you just want to |
51 | /// visit all their items, consider iterating over the collections directly: |
52 | /// |
53 | /// # Examples |
54 | /// |
55 | /// ```rust |
56 | /// use pyo3::prelude::*; |
57 | /// use pyo3::types::PyDict; |
58 | /// |
59 | /// # pub fn main() -> PyResult<()> { |
60 | /// Python::with_gil(|py| { |
61 | /// let dict: &PyDict = py.eval("{'a':'b', 'c':'d'}" , None, None)?.downcast()?; |
62 | /// |
63 | /// for (key, value) in dict { |
64 | /// println!("key: {}, value: {}" , key, value); |
65 | /// } |
66 | /// |
67 | /// Ok(()) |
68 | /// }) |
69 | /// # } |
70 | /// ``` |
71 | /// |
72 | /// If PyO3 detects that the collection is mutated during iteration, it will panic. |
73 | /// |
74 | /// These iterators use Python's C-API directly. However in certain cases, like when compiling for |
75 | /// the Limited API and PyPy, the underlying structures are opaque and that may not be possible. |
76 | /// In these cases the iterators are implemented by forwarding to [`PyIterator`]. |
77 | pub mod iter { |
78 | pub use super::dict::PyDictIterator; |
79 | pub use super::frozenset::PyFrozenSetIterator; |
80 | pub use super::set::PySetIterator; |
81 | pub use super::tuple::PyTupleIterator; |
82 | } |
83 | |
84 | // Implementations core to all native types |
85 | #[doc (hidden)] |
86 | #[macro_export ] |
87 | macro_rules! pyobject_native_type_base( |
88 | ($name:ty $(;$generics:ident)* ) => { |
89 | unsafe impl<$($generics,)*> $crate::PyNativeType for $name {} |
90 | |
91 | impl<$($generics,)*> ::std::fmt::Debug for $name { |
92 | fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) |
93 | -> ::std::result::Result<(), ::std::fmt::Error> |
94 | { |
95 | let s = self.repr().or(::std::result::Result::Err(::std::fmt::Error))?; |
96 | f.write_str(&s.to_string_lossy()) |
97 | } |
98 | } |
99 | |
100 | impl<$($generics,)*> ::std::fmt::Display for $name { |
101 | fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) |
102 | -> ::std::result::Result<(), ::std::fmt::Error> |
103 | { |
104 | match self.str() { |
105 | ::std::result::Result::Ok(s) => return f.write_str(&s.to_string_lossy()), |
106 | ::std::result::Result::Err(err) => err.write_unraisable(self.py(), ::std::option::Option::Some(self)), |
107 | } |
108 | |
109 | match self.get_type().name() { |
110 | ::std::result::Result::Ok(name) => ::std::write!(f, "<unprintable {} object>" , name), |
111 | ::std::result::Result::Err(_err) => f.write_str("<unprintable object>" ), |
112 | } |
113 | } |
114 | } |
115 | |
116 | impl<$($generics,)*> $crate::ToPyObject for $name |
117 | { |
118 | #[inline] |
119 | fn to_object(&self, py: $crate::Python<'_>) -> $crate::PyObject { |
120 | unsafe { $crate::PyObject::from_borrowed_ptr(py, self.as_ptr()) } |
121 | } |
122 | } |
123 | }; |
124 | ); |
125 | |
126 | // Implementations core to all native types except for PyAny (because they don't |
127 | // make sense on PyAny / have different implementations). |
128 | #[doc (hidden)] |
129 | #[macro_export ] |
130 | macro_rules! pyobject_native_type_named ( |
131 | ($name:ty $(;$generics:ident)*) => { |
132 | $crate::pyobject_native_type_base!($name $(;$generics)*); |
133 | |
134 | impl<$($generics,)*> ::std::convert::AsRef<$crate::PyAny> for $name { |
135 | #[inline] |
136 | fn as_ref(&self) -> &$crate::PyAny { |
137 | &self.0 |
138 | } |
139 | } |
140 | |
141 | impl<$($generics,)*> ::std::ops::Deref for $name { |
142 | type Target = $crate::PyAny; |
143 | |
144 | #[inline] |
145 | fn deref(&self) -> &$crate::PyAny { |
146 | &self.0 |
147 | } |
148 | } |
149 | |
150 | unsafe impl<$($generics,)*> $crate::AsPyPointer for $name { |
151 | /// Gets the underlying FFI pointer, returns a borrowed pointer. |
152 | #[inline] |
153 | fn as_ptr(&self) -> *mut $crate::ffi::PyObject { |
154 | self.0.as_ptr() |
155 | } |
156 | } |
157 | |
158 | impl<$($generics,)*> $crate::IntoPy<$crate::Py<$name>> for &'_ $name { |
159 | #[inline] |
160 | fn into_py(self, py: $crate::Python<'_>) -> $crate::Py<$name> { |
161 | unsafe { $crate::Py::from_borrowed_ptr(py, self.as_ptr()) } |
162 | } |
163 | } |
164 | |
165 | impl<$($generics,)*> ::std::convert::From<&'_ $name> for $crate::Py<$name> { |
166 | #[inline] |
167 | fn from(other: &$name) -> Self { |
168 | use $crate::PyNativeType; |
169 | unsafe { $crate::Py::from_borrowed_ptr(other.py(), other.as_ptr()) } |
170 | } |
171 | } |
172 | |
173 | impl<'a, $($generics,)*> ::std::convert::From<&'a $name> for &'a $crate::PyAny { |
174 | fn from(ob: &'a $name) -> Self { |
175 | unsafe{&*(ob as *const $name as *const $crate::PyAny)} |
176 | } |
177 | } |
178 | }; |
179 | ); |
180 | |
181 | #[doc (hidden)] |
182 | #[macro_export ] |
183 | macro_rules! pyobject_native_static_type_object( |
184 | ($typeobject:expr) => { |
185 | |_py| unsafe { ::std::ptr::addr_of_mut!($typeobject) } |
186 | }; |
187 | ); |
188 | |
189 | #[doc (hidden)] |
190 | #[macro_export ] |
191 | macro_rules! pyobject_native_type_info( |
192 | ($name:ty, $typeobject:expr, $module:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => { |
193 | unsafe impl<$($generics,)*> $crate::type_object::PyTypeInfo for $name { |
194 | type AsRefTarget = Self; |
195 | |
196 | const NAME: &'static str = stringify!($name); |
197 | const MODULE: ::std::option::Option<&'static str> = $module; |
198 | |
199 | #[inline] |
200 | #[allow(clippy::redundant_closure_call)] |
201 | fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject { |
202 | $typeobject(py) |
203 | } |
204 | |
205 | $( |
206 | #[inline] |
207 | fn is_type_of(ptr: &$crate::PyAny) -> bool { |
208 | #[allow(unused_unsafe)] |
209 | unsafe { $checkfunction(ptr.as_ptr()) > 0 } |
210 | } |
211 | )? |
212 | } |
213 | }; |
214 | ); |
215 | |
216 | // NOTE: This macro is not included in pyobject_native_type_base! |
217 | // because rust-numpy has a special implementation. |
218 | #[doc (hidden)] |
219 | #[macro_export ] |
220 | macro_rules! pyobject_native_type_extract { |
221 | ($name:ty $(;$generics:ident)*) => { |
222 | impl<'py, $($generics,)*> $crate::FromPyObject<'py> for &'py $name { |
223 | fn extract(obj: &'py $crate::PyAny) -> $crate::PyResult<Self> { |
224 | obj.downcast().map_err(::std::convert::Into::into) |
225 | } |
226 | } |
227 | } |
228 | } |
229 | |
230 | /// Declares all of the boilerplate for Python types. |
231 | #[doc (hidden)] |
232 | #[macro_export ] |
233 | macro_rules! pyobject_native_type_core { |
234 | ($name:ty, $typeobject:expr, #module=$module:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => { |
235 | $crate::pyobject_native_type_named!($name $(;$generics)*); |
236 | $crate::pyobject_native_type_info!($name, $typeobject, $module $(, #checkfunction=$checkfunction)? $(;$generics)*); |
237 | $crate::pyobject_native_type_extract!($name $(;$generics)*); |
238 | }; |
239 | ($name:ty, $typeobject:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => { |
240 | $crate::pyobject_native_type_core!($name, $typeobject, #module=::std::option::Option::Some("builtins" ) $(, #checkfunction=$checkfunction)? $(;$generics)*); |
241 | }; |
242 | } |
243 | |
244 | #[doc (hidden)] |
245 | #[macro_export ] |
246 | macro_rules! pyobject_native_type_sized { |
247 | ($name:ty, $layout:path $(;$generics:ident)*) => { |
248 | unsafe impl $crate::type_object::PyLayout<$name> for $layout {} |
249 | impl $crate::type_object::PySizedLayout<$name> for $layout {} |
250 | impl<$($generics,)*> $crate::impl_::pyclass::PyClassBaseType for $name { |
251 | type LayoutAsBase = $crate::pycell::PyCellBase<$layout>; |
252 | type BaseNativeType = $name; |
253 | type Initializer = $crate::pyclass_init::PyNativeTypeInitializer<Self>; |
254 | type PyClassMutability = $crate::pycell::impl_::ImmutableClass; |
255 | } |
256 | } |
257 | } |
258 | |
259 | /// Declares all of the boilerplate for Python types which can be inherited from (because the exact |
260 | /// Python layout is known). |
261 | #[doc (hidden)] |
262 | #[macro_export ] |
263 | macro_rules! pyobject_native_type { |
264 | ($name:ty, $layout:path, $typeobject:expr $(, #module=$module:expr)? $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => { |
265 | $crate::pyobject_native_type_core!($name, $typeobject $(, #module=$module)? $(, #checkfunction=$checkfunction)? $(;$generics)*); |
266 | // To prevent inheriting native types with ABI3 |
267 | #[cfg(not(Py_LIMITED_API))] |
268 | $crate::pyobject_native_type_sized!($name, $layout $(;$generics)*); |
269 | }; |
270 | } |
271 | |
272 | mod any; |
273 | mod boolobject; |
274 | mod bytearray; |
275 | mod bytes; |
276 | mod capsule; |
277 | #[cfg (not(Py_LIMITED_API))] |
278 | mod code; |
279 | mod complex; |
280 | #[cfg (not(Py_LIMITED_API))] |
281 | mod datetime; |
282 | mod dict; |
283 | mod ellipsis; |
284 | mod floatob; |
285 | #[cfg (all(not(Py_LIMITED_API), not(PyPy)))] |
286 | mod frame; |
287 | mod frozenset; |
288 | mod function; |
289 | mod iterator; |
290 | pub(crate) mod list; |
291 | mod mapping; |
292 | mod module; |
293 | mod none; |
294 | mod notimplemented; |
295 | mod num; |
296 | #[cfg (not(PyPy))] |
297 | mod pysuper; |
298 | mod sequence; |
299 | pub(crate) mod set; |
300 | mod slice; |
301 | mod string; |
302 | mod traceback; |
303 | mod tuple; |
304 | mod typeobject; |
305 | |