@@ -27,7 +27,7 @@ use std::{
27
27
str:: FromStr ,
28
28
} ;
29
29
30
- pub ( crate ) fn extract_value ( any : & PyAny ) -> PyResult < Value > {
30
+ pub ( crate ) fn extract_value ( any : & Bound < PyAny > ) -> PyResult < Value > {
31
31
if let Ok ( s) = any. extract :: < String > ( ) {
32
32
return Ok ( Value :: Str ( s) ) ;
33
33
}
@@ -42,7 +42,7 @@ pub(crate) fn extract_value(any: &PyAny) -> PyResult<Value> {
42
42
}
43
43
if let Ok ( datetime) = any. extract :: < NaiveDateTime > ( ) {
44
44
return Ok ( Value :: Date ( tv:: DateTime :: from_timestamp_secs (
45
- datetime. timestamp ( ) ,
45
+ datetime. and_utc ( ) . timestamp ( ) ,
46
46
) ) ) ;
47
47
}
48
48
if let Ok ( facet) = any. extract :: < Facet > ( ) {
@@ -52,23 +52,24 @@ pub(crate) fn extract_value(any: &PyAny) -> PyResult<Value> {
52
52
return Ok ( Value :: Bytes ( b) ) ;
53
53
}
54
54
if let Ok ( dict) = any. downcast :: < PyDict > ( ) {
55
- if let Ok ( json) = pythonize:: depythonize ( dict) {
55
+ if let Ok ( json) = pythonize:: depythonize_bound ( dict. clone ( ) . into_any ( ) )
56
+ {
56
57
return Ok ( Value :: Object ( json) ) ;
57
58
}
58
59
}
59
60
Err ( to_pyerr ( format ! ( "Value unsupported {any:?}" ) ) )
60
61
}
61
62
62
63
pub ( crate ) fn extract_value_for_type (
63
- any : & PyAny ,
64
+ any : & Bound < PyAny > ,
64
65
tv_type : tv:: schema:: Type ,
65
66
field_name : & str ,
66
67
) -> PyResult < Value > {
67
68
// Helper function to create `PyErr`s returned by this function.
68
69
fn to_pyerr_for_type < ' a , E : std:: error:: Error > (
69
70
type_name : & ' a str ,
70
71
field_name : & ' a str ,
71
- any : & ' a PyAny ,
72
+ any : & ' a Bound < PyAny > ,
72
73
) -> impl Fn ( E ) -> PyErr + ' a {
73
74
move |_| {
74
75
to_pyerr ( format ! (
@@ -104,7 +105,9 @@ pub(crate) fn extract_value_for_type(
104
105
. extract :: < NaiveDateTime > ( )
105
106
. map_err ( to_pyerr_for_type ( "DateTime" , field_name, any) ) ?;
106
107
107
- Value :: Date ( tv:: DateTime :: from_timestamp_secs ( datetime. timestamp ( ) ) )
108
+ Value :: Date ( tv:: DateTime :: from_timestamp_secs (
109
+ datetime. and_utc ( ) . timestamp ( ) ,
110
+ ) )
108
111
}
109
112
tv:: schema:: Type :: Facet => Value :: Facet (
110
113
any. extract :: < Facet > ( )
@@ -124,9 +127,11 @@ pub(crate) fn extract_value_for_type(
124
127
125
128
Value :: Object (
126
129
any. downcast :: < PyDict > ( )
127
- . map ( |dict| pythonize:: depythonize ( dict) )
128
- . map_err ( to_pyerr_for_type ( "Json" , field_name, any) ) ?
129
- . map_err ( to_pyerr_for_type ( "Json" , field_name, any) ) ?,
130
+ . map_err ( to_pyerr_for_type ( "Json" , field_name, any) )
131
+ . and_then ( |dict| {
132
+ pythonize:: depythonize_bound ( dict. clone ( ) . into_any ( ) )
133
+ . map_err ( to_pyerr_for_type ( "Json" , field_name, any) )
134
+ } ) ?,
130
135
)
131
136
}
132
137
tv:: schema:: Type :: IpAddr => {
@@ -147,16 +152,16 @@ pub(crate) fn extract_value_for_type(
147
152
Ok ( value)
148
153
}
149
154
150
- fn extract_value_single_or_list ( any : & PyAny ) -> PyResult < Vec < Value > > {
155
+ fn extract_value_single_or_list ( any : & Bound < PyAny > ) -> PyResult < Vec < Value > > {
151
156
if let Ok ( values) = any. downcast :: < PyList > ( ) {
152
- values. iter ( ) . map ( extract_value) . collect ( )
157
+ values. iter ( ) . map ( |v| extract_value ( & v ) ) . collect ( )
153
158
} else {
154
159
Ok ( vec ! [ extract_value( any) ?] )
155
160
}
156
161
}
157
162
158
163
fn extract_value_single_or_list_for_type (
159
- any : & PyAny ,
164
+ any : & Bound < PyAny > ,
160
165
field_type : & tv:: schema:: FieldType ,
161
166
field_name : & str ,
162
167
) -> PyResult < Vec < Value > > {
@@ -179,7 +184,11 @@ fn extract_value_single_or_list_for_type(
179
184
values
180
185
. iter ( )
181
186
. map ( |any| {
182
- extract_value_for_type ( any, field_type. value_type ( ) , field_name)
187
+ extract_value_for_type (
188
+ & any,
189
+ field_type. value_type ( ) ,
190
+ field_name,
191
+ )
183
192
} )
184
193
. collect ( )
185
194
} else {
@@ -195,7 +204,7 @@ fn object_to_py(
195
204
py : Python ,
196
205
obj : & BTreeMap < String , Value > ,
197
206
) -> PyResult < PyObject > {
198
- let dict = PyDict :: new ( py) ;
207
+ let dict = PyDict :: new_bound ( py) ;
199
208
for ( k, v) in obj. iter ( ) {
200
209
dict. set_item ( k, value_to_py ( py, v) ?) ?;
201
210
}
@@ -216,7 +225,7 @@ fn value_to_py(py: Python, value: &Value) -> PyResult<PyObject> {
216
225
}
217
226
Value :: Date ( d) => {
218
227
let utc = d. into_utc ( ) ;
219
- PyDateTime :: new (
228
+ PyDateTime :: new_bound (
220
229
py,
221
230
utc. year ( ) ,
222
231
utc. month ( ) as u8 ,
@@ -538,7 +547,7 @@ impl Document {
538
547
/// [`extend()`], or `add_<type>()` functions.
539
548
#[ new]
540
549
#[ pyo3( signature = ( * * kwargs) ) ]
541
- fn new ( kwargs : Option < & PyDict > ) -> PyResult < Self > {
550
+ fn new ( kwargs : Option < & Bound < PyDict > > ) -> PyResult < Self > {
542
551
let mut document = Document :: default ( ) ;
543
552
if let Some ( field_dict) = kwargs {
544
553
document. extend ( field_dict, None ) ?;
@@ -548,7 +557,7 @@ impl Document {
548
557
549
558
fn extend (
550
559
& mut self ,
551
- py_dict : & PyDict ,
560
+ py_dict : & Bound < PyDict > ,
552
561
schema : Option < & Schema > ,
553
562
) -> PyResult < ( ) > {
554
563
Document :: extract_py_values_from_dict (
@@ -560,7 +569,7 @@ impl Document {
560
569
561
570
#[ staticmethod]
562
571
fn from_dict (
563
- py_dict : & PyDict ,
572
+ py_dict : & Bound < PyDict > ,
564
573
schema : Option < & Schema > ,
565
574
) -> PyResult < Document > {
566
575
let mut field_values: BTreeMap < String , Vec < Value > > = BTreeMap :: new ( ) ;
@@ -581,7 +590,7 @@ impl Document {
581
590
/// For this reason, the dictionary, will associate
582
591
/// a list of value for every field.
583
592
fn to_dict ( & self , py : Python ) -> PyResult < PyObject > {
584
- let dict = PyDict :: new ( py) ;
593
+ let dict = PyDict :: new_bound ( py) ;
585
594
for ( key, values) in & self . field_values {
586
595
let values_py: Vec < PyObject > = values
587
596
. iter ( )
@@ -642,7 +651,7 @@ impl Document {
642
651
/// Args:
643
652
/// field_name (str): The field name for which we are adding the date.
644
653
/// value (datetime): The date that will be added to the document.
645
- fn add_date ( & mut self , field_name : String , value : & PyDateTime ) {
654
+ fn add_date ( & mut self , field_name : String , value : & Bound < PyDateTime > ) {
646
655
let datetime = Utc
647
656
. with_ymd_and_hms (
648
657
value. get_year ( ) ,
@@ -685,15 +694,21 @@ impl Document {
685
694
/// to the document.
686
695
///
687
696
/// Raises a ValueError if the JSON is invalid.
688
- fn add_json ( & mut self , field_name : String , value : & PyAny ) -> PyResult < ( ) > {
697
+ fn add_json (
698
+ & mut self ,
699
+ field_name : String ,
700
+ value : & Bound < PyAny > ,
701
+ ) -> PyResult < ( ) > {
689
702
type JsonMap = serde_json:: Map < String , serde_json:: Value > ;
690
703
691
704
if let Ok ( json_str) = value. extract :: < & str > ( ) {
692
705
let json_map: JsonMap =
693
706
serde_json:: from_str ( json_str) . map_err ( to_pyerr) ?;
694
707
self . add_value ( field_name, json_map) ;
695
708
Ok ( ( ) )
696
- } else if let Ok ( json_map) = pythonize:: depythonize :: < JsonMap > ( value) {
709
+ } else if let Ok ( json_map) =
710
+ pythonize:: depythonize_bound :: < JsonMap > ( value. clone ( ) )
711
+ {
697
712
self . add_value ( field_name, json_map) ;
698
713
Ok ( ( ) )
699
714
} else {
@@ -760,7 +775,7 @@ impl Document {
760
775
self . clone ( )
761
776
}
762
777
763
- fn __deepcopy__ ( & self , _memo : & PyDict ) -> Self {
778
+ fn __deepcopy__ ( & self , _memo : & Bound < PyDict > ) -> Self {
764
779
self . clone ( )
765
780
}
766
781
@@ -778,21 +793,21 @@ impl Document {
778
793
}
779
794
780
795
#[ staticmethod]
781
- fn _internal_from_pythonized ( serialized : & PyAny ) -> PyResult < Self > {
782
- pythonize:: depythonize ( serialized) . map_err ( to_pyerr)
796
+ fn _internal_from_pythonized ( serialized : & Bound < PyAny > ) -> PyResult < Self > {
797
+ pythonize:: depythonize_bound ( serialized. clone ( ) ) . map_err ( to_pyerr)
783
798
}
784
799
785
800
fn __reduce__ < ' a > (
786
801
slf : PyRef < ' a , Self > ,
787
802
py : Python < ' a > ,
788
- ) -> PyResult < & ' a PyTuple > {
803
+ ) -> PyResult < Bound < ' a , PyTuple > > {
789
804
let serialized = pythonize:: pythonize ( py, & * slf) . map_err ( to_pyerr) ?;
790
805
791
- Ok ( PyTuple :: new (
806
+ Ok ( PyTuple :: new_bound (
792
807
py,
793
808
[
794
809
slf. into_py ( py) . getattr ( py, "_internal_from_pythonized" ) ?,
795
- PyTuple :: new ( py, [ serialized] ) . to_object ( py) ,
810
+ PyTuple :: new_bound ( py, [ serialized] ) . to_object ( py) ,
796
811
] ,
797
812
) )
798
813
}
@@ -810,7 +825,7 @@ impl Document {
810
825
}
811
826
812
827
fn extract_py_values_from_dict (
813
- py_dict : & PyDict ,
828
+ py_dict : & Bound < PyDict > ,
814
829
schema : Option < & Schema > ,
815
830
out_field_values : & mut BTreeMap < String , Vec < Value > > ,
816
831
) -> PyResult < ( ) > {
@@ -847,12 +862,12 @@ impl Document {
847
862
848
863
let value_list = if let Some ( field_type) = field_type {
849
864
extract_value_single_or_list_for_type (
850
- key_value. get_item ( 1 ) ?,
865
+ & key_value. get_item ( 1 ) ?,
851
866
field_type,
852
867
key. as_str ( ) ,
853
868
) ?
854
869
} else {
855
- extract_value_single_or_list ( key_value. get_item ( 1 ) ?) ?
870
+ extract_value_single_or_list ( & key_value. get_item ( 1 ) ?) ?
856
871
} ;
857
872
858
873
out_field_values. insert ( key, value_list) ;
0 commit comments