1 | use super::any::PyAnyMethods; |
2 | use crate::{ffi, instance::Bound, IntoPyObject, PyAny, Python}; |
3 | use std::convert::Infallible; |
4 | |
5 | /// Represents a Python `int` object. |
6 | /// |
7 | /// Values of this type are accessed via PyO3's smart pointers, e.g. as |
8 | /// [`Py<PyInt>`][crate::Py] or [`Bound<'py, PyInt>`][crate::Bound]. |
9 | /// |
10 | /// You can usually avoid directly working with this type |
11 | /// by using [`ToPyObject`](crate::conversion::ToPyObject) |
12 | /// and [`extract`](super::PyAnyMethods::extract) |
13 | /// with the primitive Rust integer types. |
14 | #[repr (transparent)] |
15 | pub struct PyInt(PyAny); |
16 | |
17 | pyobject_native_type_core!(PyInt, pyobject_native_static_type_object!(ffi::PyLong_Type), #checkfunction=ffi::PyLong_Check); |
18 | |
19 | /// Deprecated alias for [`PyInt`]. |
20 | #[deprecated (since = "0.23.0" , note = "use `PyInt` instead" )] |
21 | pub type PyLong = PyInt; |
22 | |
23 | impl PyInt { |
24 | /// Creates a new Python int object. |
25 | /// |
26 | /// Panics if out of memory. |
27 | pub fn new<'a, T>(py: Python<'a>, i: T) -> Bound<'a, PyInt> |
28 | where |
29 | T: IntoPyObject<'a, Target = PyInt, Output = Bound<'a, PyInt>, Error = Infallible>, |
30 | { |
31 | match T::into_pyobject(self:i, py) { |
32 | Ok(v: Bound<'a, PyInt>) => v, |
33 | Err(never: Infallible) => match never {}, |
34 | } |
35 | } |
36 | } |
37 | |
38 | macro_rules! int_compare { |
39 | ($rust_type: ty) => { |
40 | impl PartialEq<$rust_type> for Bound<'_, PyInt> { |
41 | #[inline] |
42 | fn eq(&self, other: &$rust_type) -> bool { |
43 | if let Ok(value) = self.extract::<$rust_type>() { |
44 | value == *other |
45 | } else { |
46 | false |
47 | } |
48 | } |
49 | } |
50 | impl PartialEq<Bound<'_, PyInt>> for $rust_type { |
51 | #[inline] |
52 | fn eq(&self, other: &Bound<'_, PyInt>) -> bool { |
53 | if let Ok(value) = other.extract::<$rust_type>() { |
54 | value == *self |
55 | } else { |
56 | false |
57 | } |
58 | } |
59 | } |
60 | }; |
61 | } |
62 | |
63 | int_compare!(i8); |
64 | int_compare!(u8); |
65 | int_compare!(i16); |
66 | int_compare!(u16); |
67 | int_compare!(i32); |
68 | int_compare!(u32); |
69 | int_compare!(i64); |
70 | int_compare!(u64); |
71 | int_compare!(i128); |
72 | int_compare!(u128); |
73 | int_compare!(isize); |
74 | int_compare!(usize); |
75 | |
76 | #[cfg (test)] |
77 | mod tests { |
78 | use super::*; |
79 | use crate::{IntoPyObject, Python}; |
80 | |
81 | #[test ] |
82 | fn test_partial_eq() { |
83 | Python::with_gil(|py| { |
84 | let v_i8 = 123i8; |
85 | let v_u8 = 123i8; |
86 | let v_i16 = 123i16; |
87 | let v_u16 = 123u16; |
88 | let v_i32 = 123i32; |
89 | let v_u32 = 123u32; |
90 | let v_i64 = 123i64; |
91 | let v_u64 = 123u64; |
92 | let v_i128 = 123i128; |
93 | let v_u128 = 123u128; |
94 | let v_isize = 123isize; |
95 | let v_usize = 123usize; |
96 | let obj = 123_i64.into_pyobject(py).unwrap(); |
97 | assert_eq!(v_i8, obj); |
98 | assert_eq!(obj, v_i8); |
99 | |
100 | assert_eq!(v_u8, obj); |
101 | assert_eq!(obj, v_u8); |
102 | |
103 | assert_eq!(v_i16, obj); |
104 | assert_eq!(obj, v_i16); |
105 | |
106 | assert_eq!(v_u16, obj); |
107 | assert_eq!(obj, v_u16); |
108 | |
109 | assert_eq!(v_i32, obj); |
110 | assert_eq!(obj, v_i32); |
111 | |
112 | assert_eq!(v_u32, obj); |
113 | assert_eq!(obj, v_u32); |
114 | |
115 | assert_eq!(v_i64, obj); |
116 | assert_eq!(obj, v_i64); |
117 | |
118 | assert_eq!(v_u64, obj); |
119 | assert_eq!(obj, v_u64); |
120 | |
121 | assert_eq!(v_i128, obj); |
122 | assert_eq!(obj, v_i128); |
123 | |
124 | assert_eq!(v_u128, obj); |
125 | assert_eq!(obj, v_u128); |
126 | |
127 | assert_eq!(v_isize, obj); |
128 | assert_eq!(obj, v_isize); |
129 | |
130 | assert_eq!(v_usize, obj); |
131 | assert_eq!(obj, v_usize); |
132 | |
133 | let big_num = (u8::MAX as u16) + 1; |
134 | let big_obj = big_num.into_pyobject(py).unwrap(); |
135 | |
136 | for x in 0u8..=u8::MAX { |
137 | assert_ne!(x, big_obj); |
138 | assert_ne!(big_obj, x); |
139 | } |
140 | }); |
141 | } |
142 | |
143 | #[test ] |
144 | fn test_display_int() { |
145 | Python::with_gil(|py| { |
146 | let s = PyInt::new(py, 42u8); |
147 | assert_eq!(format!("{}" , s), "42" ); |
148 | |
149 | let s = PyInt::new(py, 43i32); |
150 | assert_eq!(format!("{}" , s), "43" ); |
151 | |
152 | let s = PyInt::new(py, 44usize); |
153 | assert_eq!(format!("{}" , s), "44" ); |
154 | }) |
155 | } |
156 | } |
157 | |