@@ -71,6 +71,38 @@ impl<'py, 'bound> Depythonizer<'py, 'bound> {
7171 fn dict_access ( & self ) -> Result < PyMappingAccess < ' py > > {
7272 PyMappingAccess :: new ( self . input . downcast ( ) ?)
7373 }
74+
75+ fn deserialize_any_int < ' de , V > ( & self , int : & Bound < ' _ , PyInt > , visitor : V ) -> Result < V :: Value >
76+ where
77+ V : de:: Visitor < ' de > ,
78+ {
79+ if let Ok ( x) = int. extract :: < u128 > ( ) {
80+ if let Ok ( x) = u8:: try_from ( x) {
81+ visitor. visit_u8 ( x)
82+ } else if let Ok ( x) = u16:: try_from ( x) {
83+ visitor. visit_u16 ( x)
84+ } else if let Ok ( x) = u32:: try_from ( x) {
85+ visitor. visit_u32 ( x)
86+ } else if let Ok ( x) = u64:: try_from ( x) {
87+ visitor. visit_u64 ( x)
88+ } else {
89+ visitor. visit_u128 ( x)
90+ }
91+ } else {
92+ let x: i128 = int. extract ( ) ?;
93+ if let Ok ( x) = i8:: try_from ( x) {
94+ visitor. visit_i8 ( x)
95+ } else if let Ok ( x) = i16:: try_from ( x) {
96+ visitor. visit_i16 ( x)
97+ } else if let Ok ( x) = i32:: try_from ( x) {
98+ visitor. visit_i32 ( x)
99+ } else if let Ok ( x) = i64:: try_from ( x) {
100+ visitor. visit_i64 ( x)
101+ } else {
102+ visitor. visit_i128 ( x)
103+ }
104+ }
105+ }
74106}
75107
76108macro_rules! deserialize_type {
@@ -99,8 +131,8 @@ impl<'a, 'py, 'de, 'bound> de::Deserializer<'de> for &'a mut Depythonizer<'py, '
99131 self . deserialize_unit ( visitor)
100132 } else if obj. is_instance_of :: < PyBool > ( ) {
101133 self . deserialize_bool ( visitor)
102- } else if obj. is_instance_of :: < PyInt > ( ) {
103- self . deserialize_i64 ( visitor)
134+ } else if let Ok ( x ) = obj. downcast :: < PyInt > ( ) {
135+ self . deserialize_any_int ( x , visitor)
104136 } else if obj. is_instance_of :: < PyList > ( ) || obj. is_instance_of :: < PyTuple > ( ) {
105137 self . deserialize_tuple ( obj. len ( ) ?, visitor)
106138 } else if obj. is_instance_of :: < PyDict > ( ) {
@@ -151,10 +183,12 @@ impl<'a, 'py, 'de, 'bound> de::Deserializer<'de> for &'a mut Depythonizer<'py, '
151183 deserialize_type ! ( deserialize_i16 => visit_i16) ;
152184 deserialize_type ! ( deserialize_i32 => visit_i32) ;
153185 deserialize_type ! ( deserialize_i64 => visit_i64) ;
186+ deserialize_type ! ( deserialize_i128 => visit_i128) ;
154187 deserialize_type ! ( deserialize_u8 => visit_u8) ;
155188 deserialize_type ! ( deserialize_u16 => visit_u16) ;
156189 deserialize_type ! ( deserialize_u32 => visit_u32) ;
157190 deserialize_type ! ( deserialize_u64 => visit_u64) ;
191+ deserialize_type ! ( deserialize_u128 => visit_u128) ;
158192 deserialize_type ! ( deserialize_f32 => visit_f32) ;
159193 deserialize_type ! ( deserialize_f64 => visit_f64) ;
160194
@@ -459,7 +493,7 @@ mod test {
459493 use super :: * ;
460494 use crate :: error:: ErrorImpl ;
461495 use maplit:: hashmap;
462- use pyo3:: Python ;
496+ use pyo3:: { IntoPy , Python } ;
463497 use serde_json:: { json, Value as JsonValue } ;
464498
465499 fn test_de < T > ( code : & str , expected : & T , expected_json : & JsonValue )
@@ -749,4 +783,21 @@ mod test {
749783 let code = "{'name': 'SomeFoo', 'bar': {'value': 13, 'variant': {'Tuple': [-1.5, 8]}}}" ;
750784 test_de ( code, & expected, & expected_json) ;
751785 }
786+
787+ #[ test]
788+ fn test_int_limits ( ) {
789+ Python :: with_gil ( |py| {
790+ // serde_json::Value supports u64 and i64 as maxiumum sizes
791+ let _: serde_json:: Value = depythonize ( & u64:: MAX . into_py ( py) . into_bound ( py) ) . unwrap ( ) ;
792+ let _: serde_json:: Value = depythonize ( & u64:: MIN . into_py ( py) . into_bound ( py) ) . unwrap ( ) ;
793+ let _: serde_json:: Value = depythonize ( & i64:: MAX . into_py ( py) . into_bound ( py) ) . unwrap ( ) ;
794+ let _: serde_json:: Value = depythonize ( & i64:: MIN . into_py ( py) . into_bound ( py) ) . unwrap ( ) ;
795+
796+ let _: u128 = depythonize ( & u128:: MAX . into_py ( py) . into_bound ( py) ) . unwrap ( ) ;
797+ let _: i128 = depythonize ( & u128:: MIN . into_py ( py) . into_bound ( py) ) . unwrap ( ) ;
798+
799+ let _: i128 = depythonize ( & i128:: MAX . into_py ( py) . into_bound ( py) ) . unwrap ( ) ;
800+ let _: i128 = depythonize ( & i128:: MIN . into_py ( py) . into_bound ( py) ) . unwrap ( ) ;
801+ } ) ;
802+ }
752803}
0 commit comments