pyo3/types/
num.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use super::any::PyAnyMethods;

use crate::{ffi, instance::Bound, PyAny};

/// Represents a Python `int` object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyInt>`][crate::Py] or [`Bound<'py, PyInt>`][crate::Bound].
///
/// You can usually avoid directly working with this type
/// by using [`ToPyObject`](crate::conversion::ToPyObject)
/// and [`extract`](super::PyAnyMethods::extract)
/// with the primitive Rust integer types.
#[repr(transparent)]
pub struct PyInt(PyAny);

pyobject_native_type_core!(PyInt, pyobject_native_static_type_object!(ffi::PyLong_Type), #checkfunction=ffi::PyLong_Check);

/// Deprecated alias for [`PyInt`].
#[deprecated(since = "0.23.0", note = "use `PyInt` instead")]
pub type PyLong = PyInt;

macro_rules! int_compare {
    ($rust_type: ty) => {
        impl PartialEq<$rust_type> for Bound<'_, PyInt> {
            #[inline]
            fn eq(&self, other: &$rust_type) -> bool {
                if let Ok(value) = self.extract::<$rust_type>() {
                    value == *other
                } else {
                    false
                }
            }
        }
        impl PartialEq<Bound<'_, PyInt>> for $rust_type {
            #[inline]
            fn eq(&self, other: &Bound<'_, PyInt>) -> bool {
                if let Ok(value) = other.extract::<$rust_type>() {
                    value == *self
                } else {
                    false
                }
            }
        }
    };
}

int_compare!(i8);
int_compare!(u8);
int_compare!(i16);
int_compare!(u16);
int_compare!(i32);
int_compare!(u32);
int_compare!(i64);
int_compare!(u64);
int_compare!(i128);
int_compare!(u128);
int_compare!(isize);
int_compare!(usize);

#[cfg(test)]
mod tests {
    use crate::{IntoPyObject, Python};

    #[test]
    fn test_partial_eq() {
        Python::with_gil(|py| {
            let v_i8 = 123i8;
            let v_u8 = 123i8;
            let v_i16 = 123i16;
            let v_u16 = 123u16;
            let v_i32 = 123i32;
            let v_u32 = 123u32;
            let v_i64 = 123i64;
            let v_u64 = 123u64;
            let v_i128 = 123i128;
            let v_u128 = 123u128;
            let v_isize = 123isize;
            let v_usize = 123usize;
            let obj = 123_i64.into_pyobject(py).unwrap();
            assert_eq!(v_i8, obj);
            assert_eq!(obj, v_i8);

            assert_eq!(v_u8, obj);
            assert_eq!(obj, v_u8);

            assert_eq!(v_i16, obj);
            assert_eq!(obj, v_i16);

            assert_eq!(v_u16, obj);
            assert_eq!(obj, v_u16);

            assert_eq!(v_i32, obj);
            assert_eq!(obj, v_i32);

            assert_eq!(v_u32, obj);
            assert_eq!(obj, v_u32);

            assert_eq!(v_i64, obj);
            assert_eq!(obj, v_i64);

            assert_eq!(v_u64, obj);
            assert_eq!(obj, v_u64);

            assert_eq!(v_i128, obj);
            assert_eq!(obj, v_i128);

            assert_eq!(v_u128, obj);
            assert_eq!(obj, v_u128);

            assert_eq!(v_isize, obj);
            assert_eq!(obj, v_isize);

            assert_eq!(v_usize, obj);
            assert_eq!(obj, v_usize);

            let big_num = (u8::MAX as u16) + 1;
            let big_obj = big_num.into_pyobject(py).unwrap();

            for x in 0u8..=u8::MAX {
                assert_ne!(x, big_obj);
                assert_ne!(big_obj, x);
            }
        });
    }
}