1
1
use pyo3:: { types:: * , Bound } ;
2
- use serde:: de:: { self , IntoDeserializer } ;
2
+ use serde:: de:: { self , DeserializeOwned , IntoDeserializer } ;
3
3
use serde:: Deserialize ;
4
4
5
5
use crate :: error:: { PythonizeError , Result } ;
6
6
7
7
/// 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 >
9
9
where
10
- T : Deserialize < ' obj > ,
10
+ T : Deserialize < ' a > ,
11
11
{
12
- let mut depythonizer = Depythonizer :: from_object ( obj) ;
13
- T :: deserialize ( & mut depythonizer)
12
+ T :: deserialize ( & mut Depythonizer :: from_object ( obj) )
14
13
}
15
14
16
15
/// Attempt to convert a Python object to an instance of `T`
17
16
#[ deprecated( since = "0.22.0" , note = "use `depythonize` instead" ) ]
18
17
pub fn depythonize_bound < ' py , T > ( obj : Bound < ' py , PyAny > ) -> Result < T >
19
18
where
20
- T : for < ' a > Deserialize < ' a > ,
19
+ T : DeserializeOwned ,
21
20
{
22
- let mut depythonizer = Depythonizer :: from_object ( & obj) ;
23
- T :: deserialize ( & mut depythonizer)
21
+ T :: deserialize ( & mut Depythonizer :: from_object ( & obj) )
24
22
}
25
23
26
24
/// 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 > ,
29
27
}
30
28
31
- impl < ' py , ' bound > Depythonizer < ' py , ' bound > {
29
+ impl < ' a , ' py > Depythonizer < ' a , ' py > {
32
30
/// 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 {
34
32
Depythonizer { input }
35
33
}
36
34
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 > > {
41
36
let seq = self . input . downcast :: < PySequence > ( ) ?;
42
37
let len = self . input . len ( ) ?;
43
38
@@ -97,14 +92,14 @@ macro_rules! deserialize_type {
97
92
} ;
98
93
}
99
94
100
- impl < ' a , ' py , ' de , ' bound > de:: Deserializer < ' de > for & ' a mut Depythonizer < ' py , ' bound > {
95
+ impl < ' de > de:: Deserializer < ' de > for & ' _ mut Depythonizer < ' _ , ' _ > {
101
96
type Error = PythonizeError ;
102
97
103
98
fn deserialize_any < V > ( self , visitor : V ) -> Result < V :: Value >
104
99
where
105
100
V : de:: Visitor < ' de > ,
106
101
{
107
- let obj = & self . input ;
102
+ let obj = self . input ;
108
103
109
104
// First check for cases which are cheap to check due to pointer
110
105
// comparison or bitflag checks
@@ -307,8 +302,7 @@ impl<'a, 'py, 'de, 'bound> de::Deserializer<'de> for &'a mut Depythonizer<'py, '
307
302
. downcast_into :: < PyString > ( )
308
303
. map_err ( |_| PythonizeError :: dict_key_not_string ( ) ) ?;
309
304
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) )
312
306
} else {
313
307
Err ( PythonizeError :: invalid_enum_type ( ) )
314
308
}
@@ -333,19 +327,19 @@ impl<'a, 'py, 'de, 'bound> de::Deserializer<'de> for &'a mut Depythonizer<'py, '
333
327
}
334
328
}
335
329
336
- struct PySequenceAccess < ' py , ' bound > {
337
- seq : & ' bound Bound < ' py , PySequence > ,
330
+ struct PySequenceAccess < ' a , ' py > {
331
+ seq : & ' a Bound < ' py , PySequence > ,
338
332
index : usize ,
339
333
len : usize ,
340
334
}
341
335
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 {
344
338
Self { seq, index : 0 , len }
345
339
}
346
340
}
347
341
348
- impl < ' de , ' py , ' bound > de:: SeqAccess < ' de > for PySequenceAccess < ' py , ' bound > {
342
+ impl < ' de > de:: SeqAccess < ' de > for PySequenceAccess < ' _ , ' _ > {
349
343
type Error = PythonizeError ;
350
344
351
345
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> {
354
348
{
355
349
if self . index < self . len {
356
350
let item = self . seq . get_item ( self . index ) ?;
357
- let mut item_de = Depythonizer :: from_object ( & item) ;
358
351
self . index += 1 ;
359
- seed. deserialize ( & mut item_de) . map ( Some )
352
+ seed. deserialize ( & mut Depythonizer :: from_object ( & item) )
353
+ . map ( Some )
360
354
} else {
361
355
Ok ( None )
362
356
}
@@ -386,7 +380,7 @@ impl<'py> PyMappingAccess<'py> {
386
380
}
387
381
}
388
382
389
- impl < ' de , ' py > de:: MapAccess < ' de > for PyMappingAccess < ' py > {
383
+ impl < ' de > de:: MapAccess < ' de > for PyMappingAccess < ' _ > {
390
384
type Error = PythonizeError ;
391
385
392
386
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> {
395
389
{
396
390
if self . key_idx < self . len {
397
391
let item = self . keys . get_item ( self . key_idx ) ?;
398
- let mut item_de = Depythonizer :: from_object ( & item) ;
399
392
self . key_idx += 1 ;
400
- seed. deserialize ( & mut item_de) . map ( Some )
393
+ seed. deserialize ( & mut Depythonizer :: from_object ( & item) )
394
+ . map ( Some )
401
395
} else {
402
396
Ok ( None )
403
397
}
@@ -408,24 +402,26 @@ impl<'de, 'py> de::MapAccess<'de> for PyMappingAccess<'py> {
408
402
V : de:: DeserializeSeed < ' de > ,
409
403
{
410
404
let item = self . values . get_item ( self . val_idx ) ?;
411
- let mut item_de = Depythonizer :: from_object ( & item) ;
412
405
self . val_idx += 1 ;
413
- seed. deserialize ( & mut item_de )
406
+ seed. deserialize ( & mut Depythonizer :: from_object ( & item ) )
414
407
}
415
408
}
416
409
417
- struct PyEnumAccess < ' a , ' py , ' bound > {
418
- de : & ' a mut Depythonizer < ' py , ' bound > ,
410
+ struct PyEnumAccess < ' a , ' py > {
411
+ de : Depythonizer < ' a , ' py > ,
419
412
variant : Bound < ' py , PyString > ,
420
413
}
421
414
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
+ }
425
421
}
426
422
}
427
423
428
- impl < ' a , ' py , ' de , ' bound > de:: EnumAccess < ' de > for PyEnumAccess < ' a , ' py , ' bound > {
424
+ impl < ' de > de:: EnumAccess < ' de > for PyEnumAccess < ' _ , ' _ > {
429
425
type Error = PythonizeError ;
430
426
type Variant = Self ;
431
427
@@ -440,7 +436,7 @@ impl<'a, 'py, 'de, 'bound> de::EnumAccess<'de> for PyEnumAccess<'a, 'py, 'bound>
440
436
}
441
437
}
442
438
443
- impl < ' a , ' py , ' de , ' bound > de:: VariantAccess < ' de > for PyEnumAccess < ' a , ' py , ' bound > {
439
+ impl < ' de > de:: VariantAccess < ' de > for PyEnumAccess < ' _ , ' _ > {
444
440
type Error = PythonizeError ;
445
441
446
442
fn unit_variant ( self ) -> Result < ( ) > {
@@ -451,7 +447,7 @@ impl<'a, 'py, 'de, 'bound> de::VariantAccess<'de> for PyEnumAccess<'a, 'py, 'bou
451
447
where
452
448
T : de:: DeserializeSeed < ' de > ,
453
449
{
454
- seed. deserialize ( self . de )
450
+ seed. deserialize ( & mut { self . de } )
455
451
}
456
452
457
453
fn tuple_variant < V > ( self , len : usize , visitor : V ) -> Result < V :: Value >
@@ -482,14 +478,15 @@ mod test {
482
478
T : de:: DeserializeOwned + PartialEq + std:: fmt:: Debug ,
483
479
{
484
480
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 ( ) ;
489
482
let actual: T = depythonize ( & obj) . unwrap ( ) ;
490
483
assert_eq ! ( & actual, expected) ;
491
484
let actual_json: JsonValue = depythonize ( & obj) . unwrap ( ) ;
492
485
assert_eq ! ( & actual_json, expected_json) ;
486
+
487
+ #[ allow( deprecated) ]
488
+ let actual: T = depythonize_bound ( obj. clone ( ) ) . unwrap ( ) ;
489
+ assert_eq ! ( & actual, expected) ;
493
490
} ) ;
494
491
}
495
492
0 commit comments