@@ -15,6 +15,7 @@ mod interface;
15
15
mod interface_tests;
16
16
17
17
use std:: collections:: BTreeMap ;
18
+ use std:: convert:: AsRef ;
18
19
use std:: convert:: TryInto ;
19
20
use std:: fmt;
20
21
use std:: sync:: atomic;
@@ -97,14 +98,6 @@ pub fn type_for(py_type: PyType) -> TypeId {
97
98
} )
98
99
}
99
100
100
- pub fn acquire_key_for ( val : Value ) -> Result < Key , Failure > {
101
- key_for ( val) . map_err ( |e| {
102
- let gil = Python :: acquire_gil ( ) ;
103
- let py = gil. python ( ) ;
104
- Failure :: from_py_err ( py, e)
105
- } )
106
- }
107
-
108
101
pub fn key_for ( val : Value ) -> Result < Key , PyErr > {
109
102
with_interns_mut ( |interns| {
110
103
let gil = Python :: acquire_gil ( ) ;
@@ -174,7 +167,7 @@ pub fn store_bool(val: bool) -> Value {
174
167
///
175
168
/// Check if a Python object has the specified field.
176
169
///
177
- pub fn hasattr ( value : & Value , field : & str ) -> bool {
170
+ pub fn hasattr ( value : & PyObject , field : & str ) -> bool {
178
171
let gil = Python :: acquire_gil ( ) ;
179
172
let py = gil. python ( ) ;
180
173
value. hasattr ( py, field) . unwrap ( )
@@ -183,7 +176,7 @@ pub fn hasattr(value: &Value, field: &str) -> bool {
183
176
///
184
177
/// Gets an attribute of the given value as the given type.
185
178
///
186
- fn getattr < T > ( value : & Value , field : & str ) -> Result < T , String >
179
+ fn getattr < T > ( value : & PyObject , field : & str ) -> Result < T , String >
187
180
where
188
181
for < ' a > T : FromPyObject < ' a > ,
189
182
{
@@ -235,27 +228,27 @@ fn collect_iterable(value: &Value) -> Result<Vec<Value>, String> {
235
228
/// Pulls out the value specified by the field name from a given Value
236
229
///
237
230
pub fn project_ignoring_type ( value : & Value , field : & str ) -> Value {
238
- getattr ( value, field) . unwrap ( )
231
+ getattr ( value. as_ref ( ) , field) . unwrap ( )
239
232
}
240
233
241
234
pub fn project_iterable ( value : & Value ) -> Vec < Value > {
242
235
collect_iterable ( value) . unwrap ( )
243
236
}
244
237
245
238
pub fn project_multi ( value : & Value , field : & str ) -> Vec < Value > {
246
- getattr ( value, field) . unwrap ( )
239
+ getattr ( value. as_ref ( ) , field) . unwrap ( )
247
240
}
248
241
249
242
pub fn project_bool ( value : & Value , field : & str ) -> bool {
250
- getattr ( value, field) . unwrap ( )
243
+ getattr ( value. as_ref ( ) , field) . unwrap ( )
251
244
}
252
245
253
246
pub fn project_multi_strs ( value : & Value , field : & str ) -> Vec < String > {
254
- getattr ( value, field) . unwrap ( )
247
+ getattr ( value. as_ref ( ) , field) . unwrap ( )
255
248
}
256
249
257
250
pub fn project_frozendict ( value : & Value , field : & str ) -> BTreeMap < String , String > {
258
- let frozendict = Value :: new ( getattr ( value, field) . unwrap ( ) ) ;
251
+ let frozendict = getattr ( value. as_ref ( ) , field) . unwrap ( ) ;
259
252
let pydict: PyDict = getattr ( & frozendict, "_data" ) . unwrap ( ) ;
260
253
let gil = Python :: acquire_gil ( ) ;
261
254
let py = gil. python ( ) ;
@@ -271,25 +264,25 @@ pub fn project_str(value: &Value, field: &str) -> String {
271
264
// cloning in some cases.
272
265
// TODO: We can't directly extract as a string here, because val_to_str defaults to empty string
273
266
// for None.
274
- val_to_str ( & getattr ( value, field) . unwrap ( ) )
267
+ val_to_str ( & getattr ( value. as_ref ( ) , field) . unwrap ( ) )
275
268
}
276
269
277
270
pub fn project_u64 ( value : & Value , field : & str ) -> u64 {
278
- getattr ( value, field) . unwrap ( )
271
+ getattr ( value. as_ref ( ) , field) . unwrap ( )
279
272
}
280
273
281
274
pub fn project_maybe_u64 ( value : & Value , field : & str ) -> Result < u64 , String > {
282
- getattr ( value, field)
275
+ getattr ( value. as_ref ( ) , field)
283
276
}
284
277
285
278
pub fn project_f64 ( value : & Value , field : & str ) -> f64 {
286
- getattr ( value, field) . unwrap ( )
279
+ getattr ( value. as_ref ( ) , field) . unwrap ( )
287
280
}
288
281
289
282
pub fn project_bytes ( value : & Value , field : & str ) -> Vec < u8 > {
290
283
// TODO: It's possible to view a python bytes as a `&[u8]`, so we could avoid actually
291
284
// cloning in some cases.
292
- getattr ( value, field) . unwrap ( )
285
+ getattr ( value. as_ref ( ) , field) . unwrap ( )
293
286
}
294
287
295
288
pub fn key_to_str ( key : & Key ) -> String {
@@ -327,41 +320,31 @@ pub fn create_exception(msg: &str) -> Value {
327
320
Value :: from ( with_externs ( |py, e| e. call_method ( py, "create_exception" , ( msg, ) , None ) ) . unwrap ( ) )
328
321
}
329
322
330
- pub fn check_for_python_none ( value : Value ) -> Option < Value > {
323
+ pub fn check_for_python_none ( value : PyObject ) -> Option < PyObject > {
331
324
let gil = Python :: acquire_gil ( ) ;
332
325
let py = gil. python ( ) ;
333
326
334
- if * value == py. None ( ) {
327
+ if value == py. None ( ) {
335
328
return None ;
336
329
}
337
330
Some ( value)
338
331
}
339
332
340
- pub fn call_method ( value : & Value , method : & str , args : & [ Value ] ) -> Result < Value , Failure > {
333
+ pub fn call_method ( value : & PyObject , method : & str , args : & [ Value ] ) -> Result < PyObject , PyErr > {
341
334
let arg_handles: Vec < PyObject > = args. iter ( ) . map ( |v| v. clone ( ) . into ( ) ) . collect ( ) ;
342
335
let gil = Python :: acquire_gil ( ) ;
343
336
let args_tuple = PyTuple :: new ( gil. python ( ) , & arg_handles) ;
344
- value
345
- . call_method ( gil. python ( ) , method, args_tuple, None )
346
- . map ( Value :: from)
347
- . map_err ( |py_err| Failure :: from_py_err ( gil. python ( ) , py_err) )
337
+ value. call_method ( gil. python ( ) , method, args_tuple, None )
348
338
}
349
339
350
- pub fn call_function ( func : & Value , args : & [ Value ] ) -> Result < PyObject , PyErr > {
340
+ pub fn call_function < T : AsRef < PyObject > > ( func : T , args : & [ Value ] ) -> Result < PyObject , PyErr > {
341
+ let func: & PyObject = func. as_ref ( ) ;
351
342
let arg_handles: Vec < PyObject > = args. iter ( ) . map ( |v| v. clone ( ) . into ( ) ) . collect ( ) ;
352
343
let gil = Python :: acquire_gil ( ) ;
353
344
let args_tuple = PyTuple :: new ( gil. python ( ) , & arg_handles) ;
354
345
func. call ( gil. python ( ) , args_tuple, None )
355
346
}
356
347
357
- pub fn call ( func : & Value , args : & [ Value ] ) -> Result < Value , Failure > {
358
- let output = call_function ( func, args) ;
359
- output. map ( Value :: from) . map_err ( |py_err| {
360
- let gil = Python :: acquire_gil ( ) ;
361
- Failure :: from_py_err ( gil. python ( ) , py_err)
362
- } )
363
- }
364
-
365
348
pub fn generator_send ( generator : & Value , arg : & Value ) -> Result < GeneratorResponse , Failure > {
366
349
let response = with_externs ( |py, e| {
367
350
e. call_method (
@@ -370,7 +353,7 @@ pub fn generator_send(generator: &Value, arg: &Value) -> Result<GeneratorRespons
370
353
( generator as & PyObject , arg as & PyObject ) ,
371
354
None ,
372
355
)
373
- . map_err ( |py_err| Failure :: from_py_err ( py, py_err) )
356
+ . map_err ( |py_err| Failure :: from_py_err_with_gil ( py, py_err) )
374
357
} ) ?;
375
358
376
359
let gil = Python :: acquire_gil ( ) ;
@@ -398,7 +381,7 @@ pub fn generator_send(generator: &Value, arg: &Value) -> Result<GeneratorRespons
398
381
. map ( |g| {
399
382
let get = g
400
383
. cast_as :: < PyGeneratorResponseGet > ( py)
401
- . map_err ( |e| Failure :: from_py_err ( py, e. into ( ) ) ) ?;
384
+ . map_err ( |e| Failure :: from_py_err_with_gil ( py, e. into ( ) ) ) ?;
402
385
Ok ( Get :: new ( py, interns, get) ?)
403
386
} )
404
387
. collect :: < Result < Vec < _ > , _ > > ( ) ?;
@@ -520,7 +503,7 @@ impl Get {
520
503
output : interns. type_insert ( py, get. product ( py) . clone_ref ( py) ) ,
521
504
input : interns
522
505
. key_insert ( py, get. subject ( py) . clone_ref ( py) . into ( ) )
523
- . map_err ( |e| Failure :: from_py_err ( py, e) ) ?,
506
+ . map_err ( |e| Failure :: from_py_err_with_gil ( py, e) ) ?,
524
507
input_type : Some ( interns. type_insert ( py, get. declared_subject ( py) . clone_ref ( py) ) ) ,
525
508
} )
526
509
}
0 commit comments