cpython/objects/
mod.rs

1// Copyright (c) 2015 Daniel Grunwald
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4// software and associated documentation files (the "Software"), to deal in the Software
5// without restriction, including without limitation the rights to use, copy, modify, merge,
6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7// to whom the Software is furnished to do so, subject to the following conditions:
8//
9// The above copyright notice and this permission notice shall be included in all copies or
10// substantial portions of the Software.
11//
12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17// DEALINGS IN THE SOFTWARE.
18
19#![allow(clippy::transmute_ptr_to_ptr)]
20
21pub use self::module::PyModule;
22pub use self::object::PyObject;
23pub use self::typeobject::PyType;
24
25#[cfg(feature = "python3-sys")]
26pub use self::string::PyString as PyUnicode;
27#[cfg(feature = "python27-sys")]
28pub use self::string::PyUnicode;
29pub use self::string::{PyBytes, PyString, PyStringData};
30
31pub use self::boolobject::PyBool;
32pub use self::capsule::PyCapsule;
33pub use self::dict::PyDict;
34pub use self::iterator::PyIterator;
35pub use self::list::PyList;
36pub use self::none::PyNone;
37#[cfg(feature = "python27-sys")]
38pub use self::num::PyInt;
39#[cfg(feature = "python3-sys")]
40pub use self::num::PyLong as PyInt;
41pub use self::num::{PyFloat, PyLong};
42pub use self::sequence::PySequence;
43pub use self::set::PySet;
44pub use self::tuple::{NoArgs, PyTuple};
45
46#[macro_export]
47macro_rules! pyobject_newtype(
48    ($name: ident) => (
49        $crate::py_impl_to_py_object_for_python_object!($name);
50        $crate::py_impl_from_py_object_for_python_object!($name);
51
52        impl $crate::PythonObject for $name {
53            #[inline]
54            fn as_object(&self) -> &$crate::PyObject {
55                &self.0
56            }
57
58            #[inline]
59            fn into_object(self) -> $crate::PyObject {
60                self.0
61            }
62
63            /// Unchecked downcast from PyObject to Self.
64            /// Undefined behavior if the input object does not have the expected type.
65            #[inline]
66            unsafe fn unchecked_downcast_from(obj: $crate::PyObject) -> Self {
67                $name(obj)
68            }
69
70            /// Unchecked downcast from PyObject to Self.
71            /// Undefined behavior if the input object does not have the expected type.
72            #[inline]
73            unsafe fn unchecked_downcast_borrow_from<'a>(obj: &'a $crate::PyObject) -> &'a Self {
74                std::mem::transmute(obj)
75            }
76        }
77    );
78    ($name: ident, $checkfunction: ident) => (
79        pyobject_newtype!($name);
80
81        impl crate::python::PythonObjectWithCheckedDowncast for $name {
82            #[inline]
83            fn downcast_from<'p>(py: crate::python::Python<'p>, obj: crate::objects::object::PyObject) -> $crate::_detail::Result<$name, crate::python::PythonObjectDowncastError<'p>> {
84                unsafe {
85                    if crate::ffi::$checkfunction(obj.as_ptr()) != 0 {
86                        Ok($name(obj))
87                    } else {
88                        Err(crate::python::PythonObjectDowncastError::new(
89                            py,
90                            stringify!($name),
91                            obj.get_type(py)
92                        ))
93                    }
94                }
95            }
96
97            #[inline]
98            fn downcast_borrow_from<'a, 'p>(py: crate::python::Python<'p>, obj: &'a crate::objects::object::PyObject) -> $crate::_detail::Result<&'a $name, crate::python::PythonObjectDowncastError<'p>> {
99                unsafe {
100                    if crate::ffi::$checkfunction(obj.as_ptr()) != 0 {
101                        Ok(std::mem::transmute(obj))
102                    } else {
103                        Err(crate::python::PythonObjectDowncastError::new(
104                            py,
105                            stringify!($name),
106                            obj.get_type(py)
107                        ))
108                    }
109                }
110            }
111        }
112    );
113    ($name: ident, $checkfunction: ident, $typeobject: ident) => (
114        pyobject_newtype!($name, $checkfunction);
115
116        impl crate::python::PythonObjectWithTypeObject for $name {
117            #[inline]
118            fn type_object(py: crate::python::Python) -> crate::objects::typeobject::PyType {
119                unsafe { crate::objects::typeobject::PyType::from_type_ptr(py, &mut crate::ffi::$typeobject) }
120            }
121        }
122    );
123);
124
125macro_rules! extract(
126    ($obj:ident to $t:ty; $(#[$meta:meta])* $py:ident => $body: block) => {
127        impl <'s> crate::conversion::FromPyObject<'s>
128            for $t
129        {
130            $(#[$meta])*
131            fn extract($py: Python, $obj: &'s PyObject) -> PyResult<Self> {
132                $body
133            }
134        }
135    }
136);
137
138mod boolobject;
139mod capsule;
140mod dict;
141pub mod exc;
142mod iterator;
143mod list;
144mod module;
145mod none;
146mod num;
147mod object;
148mod sequence;
149mod set;
150mod string;
151mod tuple;
152mod typeobject;
153
154#[cfg(feature = "python27-sys")]
155pub mod oldstyle;
156
157mod tests;