@@ -27,7 +27,7 @@ use crate::tools::py_err;
27
27
use crate :: validators:: { CombinedValidator , Exactness , ValidationState , Validator } ;
28
28
29
29
use super :: input_string:: StringMapping ;
30
- use super :: { py_error_on_minusone, Input } ;
30
+ use super :: { py_error_on_minusone, BorrowInput , Input } ;
31
31
32
32
pub struct ValidationMatch < T > ( T , Exactness ) ;
33
33
@@ -67,7 +67,7 @@ impl<T> ValidationMatch<T> {
67
67
/// This mostly matches python's definition of `Collection`.
68
68
#[ cfg_attr( debug_assertions, derive( Debug ) ) ]
69
69
pub enum GenericIterable < ' a > {
70
- List ( & ' a PyList ) ,
70
+ List ( Py2 < ' a , PyList > ) ,
71
71
Tuple ( & ' a PyTuple ) ,
72
72
Set ( & ' a PySet ) ,
73
73
FrozenSet ( & ' a PyFrozenSet ) ,
@@ -92,33 +92,37 @@ impl<'a, 'py: 'a> GenericIterable<'a> {
92
92
pub fn as_sequence_iterator (
93
93
& self ,
94
94
py : Python < ' py > ,
95
- ) -> PyResult < Box < dyn Iterator < Item = PyResult < & ' a PyAny > > + ' a > > {
95
+ ) -> PyResult < Box < dyn Iterator < Item = PyResult < Py2 < ' a , PyAny > > > + ' a > > {
96
96
match self {
97
- GenericIterable :: List ( iter) => Ok ( Box :: new ( iter. iter ( ) . map ( Ok ) ) ) ,
98
- GenericIterable :: Tuple ( iter) => Ok ( Box :: new ( iter. iter ( ) . map ( Ok ) ) ) ,
99
- GenericIterable :: Set ( iter) => Ok ( Box :: new ( iter. iter ( ) . map ( Ok ) ) ) ,
100
- GenericIterable :: FrozenSet ( iter) => Ok ( Box :: new ( iter. iter ( ) . map ( Ok ) ) ) ,
97
+ GenericIterable :: List ( iter) => Ok ( Box :: new ( iter. clone ( ) . into_iter ( ) . map ( Ok ) ) ) ,
98
+ GenericIterable :: Tuple ( iter) => Ok ( Box :: new ( iter. iter ( ) . map ( Ok ) . map ( pyresult_ref_to_pyresult_py2 ) ) ) ,
99
+ GenericIterable :: Set ( iter) => Ok ( Box :: new ( iter. iter ( ) . map ( Ok ) . map ( pyresult_ref_to_pyresult_py2 ) ) ) ,
100
+ GenericIterable :: FrozenSet ( iter) => Ok ( Box :: new ( iter. iter ( ) . map ( Ok ) . map ( pyresult_ref_to_pyresult_py2 ) ) ) ,
101
101
// Note that this iterates over only the keys, just like doing iter({}) in Python
102
- GenericIterable :: Dict ( iter) => Ok ( Box :: new ( iter. iter ( ) . map ( |( k, _) | Ok ( k) ) ) ) ,
103
- GenericIterable :: DictKeys ( iter) => Ok ( Box :: new ( iter. iter ( ) ?) ) ,
104
- GenericIterable :: DictValues ( iter) => Ok ( Box :: new ( iter. iter ( ) ?) ) ,
105
- GenericIterable :: DictItems ( iter) => Ok ( Box :: new ( iter. iter ( ) ?) ) ,
102
+ GenericIterable :: Dict ( iter) => Ok ( Box :: new (
103
+ iter. iter ( ) . map ( |( k, _) | Ok ( k) ) . map ( pyresult_ref_to_pyresult_py2) ,
104
+ ) ) ,
105
+ GenericIterable :: DictKeys ( iter) => Ok ( Box :: new ( iter. iter ( ) ?. map ( pyresult_ref_to_pyresult_py2) ) ) ,
106
+ GenericIterable :: DictValues ( iter) => Ok ( Box :: new ( iter. iter ( ) ?. map ( pyresult_ref_to_pyresult_py2) ) ) ,
107
+ GenericIterable :: DictItems ( iter) => Ok ( Box :: new ( iter. iter ( ) ?. map ( pyresult_ref_to_pyresult_py2) ) ) ,
106
108
// Note that this iterates over only the keys, just like doing iter({}) in Python
107
- GenericIterable :: Mapping ( iter) => Ok ( Box :: new ( iter. keys ( ) ?. iter ( ) ?) ) ,
108
- GenericIterable :: PyString ( iter) => Ok ( Box :: new ( iter. iter ( ) ?) ) ,
109
- GenericIterable :: Bytes ( iter) => Ok ( Box :: new ( iter. iter ( ) ?) ) ,
110
- GenericIterable :: PyByteArray ( iter) => Ok ( Box :: new ( iter. iter ( ) ?) ) ,
111
- GenericIterable :: Sequence ( iter) => Ok ( Box :: new ( iter. iter ( ) ?) ) ,
112
- GenericIterable :: Iterator ( iter) => Ok ( Box :: new ( iter. iter ( ) ?) ) ,
109
+ GenericIterable :: Mapping ( iter) => Ok ( Box :: new ( iter. keys ( ) ?. iter ( ) ?. map ( pyresult_ref_to_pyresult_py2 ) ) ) ,
110
+ GenericIterable :: PyString ( iter) => Ok ( Box :: new ( iter. iter ( ) ?. map ( pyresult_ref_to_pyresult_py2 ) ) ) ,
111
+ GenericIterable :: Bytes ( iter) => Ok ( Box :: new ( iter. iter ( ) ?. map ( pyresult_ref_to_pyresult_py2 ) ) ) ,
112
+ GenericIterable :: PyByteArray ( iter) => Ok ( Box :: new ( iter. iter ( ) ?. map ( pyresult_ref_to_pyresult_py2 ) ) ) ,
113
+ GenericIterable :: Sequence ( iter) => Ok ( Box :: new ( iter. iter ( ) ?. map ( pyresult_ref_to_pyresult_py2 ) ) ) ,
114
+ GenericIterable :: Iterator ( iter) => Ok ( Box :: new ( iter. iter ( ) ?. map ( pyresult_ref_to_pyresult_py2 ) ) ) ,
113
115
GenericIterable :: JsonArray ( iter) => Ok ( Box :: new ( iter. iter ( ) . map ( move |v| {
114
- let v = v. to_object ( py) ;
115
- Ok ( v. into_ref ( py ) )
116
+ let v = v. to_object ( py) . attach_into ( py ) ;
117
+ Ok ( v)
116
118
} ) ) ) ,
117
119
// Note that this iterates over only the keys, just like doing iter({}) in Python, just for consistency
118
120
GenericIterable :: JsonObject ( iter) => Ok ( Box :: new (
119
- iter. iter ( ) . map ( move |( k, _) | Ok ( k. to_object ( py) . into_ref ( py) ) ) ,
121
+ iter. iter ( ) . map ( move |( k, _) | Ok ( k. to_object ( py) . attach_into ( py) ) ) ,
120
122
) ) ,
121
- GenericIterable :: JsonString ( s) => Ok ( Box :: new ( PyString :: new ( py, s) . iter ( ) ?) ) ,
123
+ GenericIterable :: JsonString ( s) => {
124
+ Ok ( Box :: new ( PyString :: new ( py, s) . iter ( ) ?. map ( pyresult_ref_to_pyresult_py2) ) )
125
+ }
122
126
}
123
127
}
124
128
}
@@ -188,7 +192,7 @@ macro_rules! any_next_error {
188
192
#[ allow( clippy:: too_many_arguments) ]
189
193
fn validate_iter_to_vec < ' a , ' s > (
190
194
py : Python < ' a > ,
191
- iter : impl Iterator < Item = PyResult < & ' a ( impl Input < ' a > + ' a ) > > ,
195
+ iter : impl Iterator < Item = PyResult < impl BorrowInput + ' a > > ,
192
196
capacity : usize ,
193
197
mut max_length_check : MaxLengthCheck < ' a , impl Input < ' a > > ,
194
198
validator : & ' s CombinedValidator ,
@@ -198,7 +202,7 @@ fn validate_iter_to_vec<'a, 's>(
198
202
let mut errors: Vec < ValLineError > = Vec :: new ( ) ;
199
203
for ( index, item_result) in iter. enumerate ( ) {
200
204
let item = item_result. map_err ( |e| any_next_error ! ( py, e, max_length_check. input, index) ) ?;
201
- match validator. validate ( py, item, state) {
205
+ match validator. validate ( py, item. borrow_input ( ) , state) {
202
206
Ok ( item) => {
203
207
max_length_check. incr ( ) ?;
204
208
output. push ( item) ;
@@ -253,7 +257,7 @@ impl BuildSet for &PyFrozenSet {
253
257
fn validate_iter_to_set < ' a , ' s > (
254
258
py : Python < ' a > ,
255
259
set : impl BuildSet ,
256
- iter : impl Iterator < Item = PyResult < & ' a ( impl Input < ' a > + ' a ) > > ,
260
+ iter : impl Iterator < Item = PyResult < impl BorrowInput + ' a > > ,
257
261
input : & ' a ( impl Input < ' a > + ' a ) ,
258
262
field_type : & ' static str ,
259
263
max_length : Option < usize > ,
@@ -263,7 +267,7 @@ fn validate_iter_to_set<'a, 's>(
263
267
let mut errors: Vec < ValLineError > = Vec :: new ( ) ;
264
268
for ( index, item_result) in iter. enumerate ( ) {
265
269
let item = item_result. map_err ( |e| any_next_error ! ( py, e, input, index) ) ?;
266
- match validator. validate ( py, item, state) {
270
+ match validator. validate ( py, item. borrow_input ( ) , state) {
267
271
Ok ( item) => {
268
272
set. build_add ( item) ?;
269
273
if let Some ( max_length) = max_length {
@@ -301,14 +305,14 @@ fn validate_iter_to_set<'a, 's>(
301
305
fn no_validator_iter_to_vec < ' a , ' s > (
302
306
py : Python < ' a > ,
303
307
input : & ' a ( impl Input < ' a > + ' a ) ,
304
- iter : impl Iterator < Item = PyResult < & ' a ( impl Input < ' a > + ' a ) > > ,
308
+ iter : impl Iterator < Item = PyResult < impl BorrowInput + ' a > > ,
305
309
mut max_length_check : MaxLengthCheck < ' a , impl Input < ' a > > ,
306
310
) -> ValResult < Vec < PyObject > > {
307
311
iter. enumerate ( )
308
312
. map ( |( index, result) | {
309
313
let v = result. map_err ( |e| any_next_error ! ( py, e, input, index) ) ?;
310
314
max_length_check. incr ( ) ?;
311
- Ok ( v. to_object ( py) )
315
+ Ok ( v. borrow_input ( ) . to_object ( py) )
312
316
} )
313
317
. collect ( )
314
318
}
@@ -360,7 +364,7 @@ impl<'a> GenericIterable<'a> {
360
364
}
361
365
362
366
match self {
363
- GenericIterable :: List ( collection) => validate ! ( collection. iter ( ) . map( Ok ) ) ,
367
+ GenericIterable :: List ( collection) => validate ! ( collection. clone ( ) . into_iter ( ) . map( Ok ) ) ,
364
368
GenericIterable :: Tuple ( collection) => validate ! ( collection. iter( ) . map( Ok ) ) ,
365
369
GenericIterable :: Set ( collection) => validate ! ( collection. iter( ) . map( Ok ) ) ,
366
370
GenericIterable :: FrozenSet ( collection) => validate ! ( collection. iter( ) . map( Ok ) ) ,
@@ -389,7 +393,7 @@ impl<'a> GenericIterable<'a> {
389
393
}
390
394
391
395
match self {
392
- GenericIterable :: List ( collection) => validate_set ! ( collection. iter ( ) . map( Ok ) ) ,
396
+ GenericIterable :: List ( collection) => validate_set ! ( collection. clone ( ) . into_iter ( ) . map( Ok ) ) ,
393
397
GenericIterable :: Tuple ( collection) => validate_set ! ( collection. iter( ) . map( Ok ) ) ,
394
398
GenericIterable :: Set ( collection) => validate_set ! ( collection. iter( ) . map( Ok ) ) ,
395
399
GenericIterable :: FrozenSet ( collection) => validate_set ! ( collection. iter( ) . map( Ok ) ) ,
@@ -412,7 +416,7 @@ impl<'a> GenericIterable<'a> {
412
416
413
417
match self {
414
418
GenericIterable :: List ( collection) => {
415
- no_validator_iter_to_vec ( py, input, collection. iter ( ) . map ( Ok ) , max_length_check)
419
+ no_validator_iter_to_vec ( py, input, collection. clone ( ) . into_iter ( ) . map ( Ok ) , max_length_check)
416
420
}
417
421
GenericIterable :: Tuple ( collection) => {
418
422
no_validator_iter_to_vec ( py, input, collection. iter ( ) . map ( Ok ) , max_length_check)
@@ -1039,3 +1043,8 @@ impl ToPyObject for Int {
1039
1043
}
1040
1044
}
1041
1045
}
1046
+
1047
+ /// Backwards-compatibility helper while migrating PyO3 API
1048
+ fn pyresult_ref_to_pyresult_py2 ( result : PyResult < & ' _ PyAny > ) -> PyResult < Py2 < ' _ , PyAny > > {
1049
+ result. map ( |any| Py2 :: borrowed_from_gil_ref ( & any) . clone ( ) )
1050
+ }
0 commit comments