11use pyo3:: { types:: * , Bound } ;
2- use serde:: de:: { self , IntoDeserializer } ;
2+ use serde:: de:: { self , DeserializeOwned , IntoDeserializer } ;
33use serde:: Deserialize ;
44
55use crate :: error:: { PythonizeError , Result } ;
66
77/// Attempt to convert a Python object to an instance of `T`
8- pub fn depythonize < ' py , ' obj , T > ( obj : & ' obj Bound < ' py , PyAny > ) -> Result < T >
8+ pub fn depythonize < ' a , ' py , T > ( obj : & ' a Bound < ' py , PyAny > ) -> Result < T >
99where
10- T : Deserialize < ' obj > ,
10+ T : Deserialize < ' a > ,
1111{
12- let mut depythonizer = Depythonizer :: from_object ( obj) ;
13- T :: deserialize ( & mut depythonizer)
12+ T :: deserialize ( & mut Depythonizer :: from_object ( obj) )
1413}
1514
1615/// Attempt to convert a Python object to an instance of `T`
1716#[ deprecated( since = "0.22.0" , note = "use `depythonize` instead" ) ]
1817pub fn depythonize_bound < ' py , T > ( obj : Bound < ' py , PyAny > ) -> Result < T >
1918where
20- T : for < ' a > Deserialize < ' a > ,
19+ T : DeserializeOwned ,
2120{
22- let mut depythonizer = Depythonizer :: from_object ( & obj) ;
23- T :: deserialize ( & mut depythonizer)
21+ T :: deserialize ( & mut Depythonizer :: from_object ( & obj) )
2422}
2523
2624/// A structure that deserializes Python objects into Rust values
27- pub struct Depythonizer < ' py , ' bound > {
28- input : & ' bound Bound < ' py , PyAny > ,
25+ pub struct Depythonizer < ' a , ' py > {
26+ input : & ' a Bound < ' py , PyAny > ,
2927}
3028
31- impl < ' py , ' bound > Depythonizer < ' py , ' bound > {
29+ impl < ' a , ' py > Depythonizer < ' a , ' py > {
3230 /// Create a deserializer from a Python object
33- pub fn from_object < ' input > ( input : & ' input Bound < ' py , PyAny > ) -> Depythonizer < ' py , ' input > {
31+ pub fn from_object ( input : & ' a Bound < ' py , PyAny > ) -> Self {
3432 Depythonizer { input }
3533 }
3634
37- fn sequence_access (
38- & self ,
39- expected_len : Option < usize > ,
40- ) -> Result < PySequenceAccess < ' py , ' bound > > {
35+ fn sequence_access ( & self , expected_len : Option < usize > ) -> Result < PySequenceAccess < ' a , ' py > > {
4136 let seq = self . input . downcast :: < PySequence > ( ) ?;
4237 let len = self . input . len ( ) ?;
4338
@@ -97,14 +92,14 @@ macro_rules! deserialize_type {
9792 } ;
9893}
9994
100- impl < ' a , ' py , ' de , ' bound > de:: Deserializer < ' de > for & ' a mut Depythonizer < ' py , ' bound > {
95+ impl < ' de > de:: Deserializer < ' de > for & ' _ mut Depythonizer < ' _ , ' _ > {
10196 type Error = PythonizeError ;
10297
10398 fn deserialize_any < V > ( self , visitor : V ) -> Result < V :: Value >
10499 where
105100 V : de:: Visitor < ' de > ,
106101 {
107- let obj = & self . input ;
102+ let obj = self . input ;
108103
109104 // First check for cases which are cheap to check due to pointer
110105 // comparison or bitflag checks
@@ -307,8 +302,7 @@ impl<'a, 'py, 'de, 'bound> de::Deserializer<'de> for &'a mut Depythonizer<'py, '
307302 . downcast_into :: < PyString > ( )
308303 . map_err ( |_| PythonizeError :: dict_key_not_string ( ) ) ?;
309304 let value = m. get_item ( & variant) ?;
310- let mut de = Depythonizer :: from_object ( & value) ;
311- visitor. visit_enum ( PyEnumAccess :: new ( & mut de, variant) )
305+ visitor. visit_enum ( PyEnumAccess :: new ( & value, variant) )
312306 } else {
313307 Err ( PythonizeError :: invalid_enum_type ( ) )
314308 }
@@ -333,19 +327,19 @@ impl<'a, 'py, 'de, 'bound> de::Deserializer<'de> for &'a mut Depythonizer<'py, '
333327 }
334328}
335329
336- struct PySequenceAccess < ' py , ' bound > {
337- seq : & ' bound Bound < ' py , PySequence > ,
330+ struct PySequenceAccess < ' a , ' py > {
331+ seq : & ' a Bound < ' py , PySequence > ,
338332 index : usize ,
339333 len : usize ,
340334}
341335
342- impl < ' py , ' bound > PySequenceAccess < ' py , ' bound > {
343- fn new ( seq : & ' bound Bound < ' py , PySequence > , len : usize ) -> Self {
336+ impl < ' a , ' py > PySequenceAccess < ' a , ' py > {
337+ fn new ( seq : & ' a Bound < ' py , PySequence > , len : usize ) -> Self {
344338 Self { seq, index : 0 , len }
345339 }
346340}
347341
348- impl < ' de , ' py , ' bound > de:: SeqAccess < ' de > for PySequenceAccess < ' py , ' bound > {
342+ impl < ' de > de:: SeqAccess < ' de > for PySequenceAccess < ' _ , ' _ > {
349343 type Error = PythonizeError ;
350344
351345 fn next_element_seed < T > ( & mut self , seed : T ) -> Result < Option < T :: Value > >
@@ -354,9 +348,9 @@ impl<'de, 'py, 'bound> de::SeqAccess<'de> for PySequenceAccess<'py, 'bound> {
354348 {
355349 if self . index < self . len {
356350 let item = self . seq . get_item ( self . index ) ?;
357- let mut item_de = Depythonizer :: from_object ( & item) ;
358351 self . index += 1 ;
359- seed. deserialize ( & mut item_de) . map ( Some )
352+ seed. deserialize ( & mut Depythonizer :: from_object ( & item) )
353+ . map ( Some )
360354 } else {
361355 Ok ( None )
362356 }
@@ -386,7 +380,7 @@ impl<'py> PyMappingAccess<'py> {
386380 }
387381}
388382
389- impl < ' de , ' py > de:: MapAccess < ' de > for PyMappingAccess < ' py > {
383+ impl < ' de > de:: MapAccess < ' de > for PyMappingAccess < ' _ > {
390384 type Error = PythonizeError ;
391385
392386 fn next_key_seed < K > ( & mut self , seed : K ) -> Result < Option < K :: Value > >
@@ -395,9 +389,9 @@ impl<'de, 'py> de::MapAccess<'de> for PyMappingAccess<'py> {
395389 {
396390 if self . key_idx < self . len {
397391 let item = self . keys . get_item ( self . key_idx ) ?;
398- let mut item_de = Depythonizer :: from_object ( & item) ;
399392 self . key_idx += 1 ;
400- seed. deserialize ( & mut item_de) . map ( Some )
393+ seed. deserialize ( & mut Depythonizer :: from_object ( & item) )
394+ . map ( Some )
401395 } else {
402396 Ok ( None )
403397 }
@@ -408,24 +402,26 @@ impl<'de, 'py> de::MapAccess<'de> for PyMappingAccess<'py> {
408402 V : de:: DeserializeSeed < ' de > ,
409403 {
410404 let item = self . values . get_item ( self . val_idx ) ?;
411- let mut item_de = Depythonizer :: from_object ( & item) ;
412405 self . val_idx += 1 ;
413- seed. deserialize ( & mut item_de )
406+ seed. deserialize ( & mut Depythonizer :: from_object ( & item ) )
414407 }
415408}
416409
417- struct PyEnumAccess < ' a , ' py , ' bound > {
418- de : & ' a mut Depythonizer < ' py , ' bound > ,
410+ struct PyEnumAccess < ' a , ' py > {
411+ de : Depythonizer < ' a , ' py > ,
419412 variant : Bound < ' py , PyString > ,
420413}
421414
422- impl < ' a , ' py , ' bound > PyEnumAccess < ' a , ' py , ' bound > {
423- fn new ( de : & ' a mut Depythonizer < ' py , ' bound > , variant : Bound < ' py , PyString > ) -> Self {
424- Self { de, variant }
415+ impl < ' a , ' py > PyEnumAccess < ' a , ' py > {
416+ fn new ( obj : & ' a Bound < ' py , PyAny > , variant : Bound < ' py , PyString > ) -> Self {
417+ Self {
418+ de : Depythonizer :: from_object ( obj) ,
419+ variant,
420+ }
425421 }
426422}
427423
428- impl < ' a , ' py , ' de , ' bound > de:: EnumAccess < ' de > for PyEnumAccess < ' a , ' py , ' bound > {
424+ impl < ' de > de:: EnumAccess < ' de > for PyEnumAccess < ' _ , ' _ > {
429425 type Error = PythonizeError ;
430426 type Variant = Self ;
431427
@@ -440,7 +436,7 @@ impl<'a, 'py, 'de, 'bound> de::EnumAccess<'de> for PyEnumAccess<'a, 'py, 'bound>
440436 }
441437}
442438
443- impl < ' a , ' py , ' de , ' bound > de:: VariantAccess < ' de > for PyEnumAccess < ' a , ' py , ' bound > {
439+ impl < ' de > de:: VariantAccess < ' de > for PyEnumAccess < ' _ , ' _ > {
444440 type Error = PythonizeError ;
445441
446442 fn unit_variant ( self ) -> Result < ( ) > {
@@ -451,7 +447,7 @@ impl<'a, 'py, 'de, 'bound> de::VariantAccess<'de> for PyEnumAccess<'a, 'py, 'bou
451447 where
452448 T : de:: DeserializeSeed < ' de > ,
453449 {
454- seed. deserialize ( self . de )
450+ seed. deserialize ( & mut { self . de } )
455451 }
456452
457453 fn tuple_variant < V > ( self , len : usize , visitor : V ) -> Result < V :: Value >
@@ -482,14 +478,15 @@ mod test {
482478 T : de:: DeserializeOwned + PartialEq + std:: fmt:: Debug ,
483479 {
484480 Python :: with_gil ( |py| {
485- let locals = PyDict :: new_bound ( py) ;
486- py. run_bound ( & format ! ( "obj = {}" , code) , None , Some ( & locals) )
487- . unwrap ( ) ;
488- let obj = locals. get_item ( "obj" ) . unwrap ( ) . unwrap ( ) ;
481+ let obj = py. eval_bound ( code, None , None ) . unwrap ( ) ;
489482 let actual: T = depythonize ( & obj) . unwrap ( ) ;
490483 assert_eq ! ( & actual, expected) ;
491484 let actual_json: JsonValue = depythonize ( & obj) . unwrap ( ) ;
492485 assert_eq ! ( & actual_json, expected_json) ;
486+
487+ #[ allow( deprecated) ]
488+ let actual: T = depythonize_bound ( obj. clone ( ) ) . unwrap ( ) ;
489+ assert_eq ! ( & actual, expected) ;
493490 } ) ;
494491 }
495492
0 commit comments