| 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 | |