@@ -11,8 +11,10 @@ pub(crate) mod private {
11
11
12
12
impl Sealed for ( ) { }
13
13
impl Sealed for Bound < ' _ , PyTuple > { }
14
+ impl Sealed for & ' _ Bound < ' _ , PyTuple > { }
14
15
impl Sealed for Py < PyTuple > { }
15
-
16
+ impl Sealed for & ' _ Py < PyTuple > { }
17
+ impl Sealed for Borrowed < ' _ , ' _ , PyTuple > { }
16
18
pub struct Token ;
17
19
}
18
20
@@ -100,35 +102,99 @@ impl<'py> PyCallArgs<'py> for () {
100
102
}
101
103
102
104
impl < ' py > PyCallArgs < ' py > for Bound < ' py , PyTuple > {
105
+ #[ inline]
103
106
fn call (
104
107
self ,
105
108
function : Borrowed < ' _ , ' py , PyAny > ,
106
- kwargs : Borrowed < ' _ , ' _ , PyDict > ,
107
- _ : private:: Token ,
109
+ kwargs : Borrowed < ' _ , ' py , PyDict > ,
110
+ token : private:: Token ,
108
111
) -> PyResult < Bound < ' py , PyAny > > {
109
- unsafe {
110
- ffi:: PyObject_Call ( function. as_ptr ( ) , self . as_ptr ( ) , kwargs. as_ptr ( ) )
111
- . assume_owned_or_err ( function. py ( ) )
112
- }
112
+ self . as_borrowed ( ) . call ( function, kwargs, token)
113
113
}
114
114
115
+ #[ inline]
115
116
fn call_positional (
116
117
self ,
117
118
function : Borrowed < ' _ , ' py , PyAny > ,
118
- _ : private:: Token ,
119
+ token : private:: Token ,
119
120
) -> PyResult < Bound < ' py , PyAny > > {
120
- unsafe {
121
- ffi:: PyObject_Call ( function. as_ptr ( ) , self . as_ptr ( ) , std:: ptr:: null_mut ( ) )
122
- . assume_owned_or_err ( function. py ( ) )
123
- }
121
+ self . as_borrowed ( ) . call_positional ( function, token)
122
+ }
123
+ }
124
+
125
+ impl < ' py > PyCallArgs < ' py > for & ' _ Bound < ' py , PyTuple > {
126
+ #[ inline]
127
+ fn call (
128
+ self ,
129
+ function : Borrowed < ' _ , ' py , PyAny > ,
130
+ kwargs : Borrowed < ' _ , ' py , PyDict > ,
131
+ token : private:: Token ,
132
+ ) -> PyResult < Bound < ' py , PyAny > > {
133
+ self . as_borrowed ( ) . call ( function, kwargs, token)
134
+ }
135
+
136
+ #[ inline]
137
+ fn call_positional (
138
+ self ,
139
+ function : Borrowed < ' _ , ' py , PyAny > ,
140
+ token : private:: Token ,
141
+ ) -> PyResult < Bound < ' py , PyAny > > {
142
+ self . as_borrowed ( ) . call_positional ( function, token)
124
143
}
125
144
}
126
145
127
146
impl < ' py > PyCallArgs < ' py > for Py < PyTuple > {
147
+ #[ inline]
128
148
fn call (
129
149
self ,
130
150
function : Borrowed < ' _ , ' py , PyAny > ,
131
- kwargs : Borrowed < ' _ , ' _ , PyDict > ,
151
+ kwargs : Borrowed < ' _ , ' py , PyDict > ,
152
+ token : private:: Token ,
153
+ ) -> PyResult < Bound < ' py , PyAny > > {
154
+ self . bind_borrowed ( function. py ( ) )
155
+ . call ( function, kwargs, token)
156
+ }
157
+
158
+ #[ inline]
159
+ fn call_positional (
160
+ self ,
161
+ function : Borrowed < ' _ , ' py , PyAny > ,
162
+ token : private:: Token ,
163
+ ) -> PyResult < Bound < ' py , PyAny > > {
164
+ self . bind_borrowed ( function. py ( ) )
165
+ . call_positional ( function, token)
166
+ }
167
+ }
168
+
169
+ impl < ' py > PyCallArgs < ' py > for & ' _ Py < PyTuple > {
170
+ #[ inline]
171
+ fn call (
172
+ self ,
173
+ function : Borrowed < ' _ , ' py , PyAny > ,
174
+ kwargs : Borrowed < ' _ , ' py , PyDict > ,
175
+ token : private:: Token ,
176
+ ) -> PyResult < Bound < ' py , PyAny > > {
177
+ self . bind_borrowed ( function. py ( ) )
178
+ . call ( function, kwargs, token)
179
+ }
180
+
181
+ #[ inline]
182
+ fn call_positional (
183
+ self ,
184
+ function : Borrowed < ' _ , ' py , PyAny > ,
185
+ token : private:: Token ,
186
+ ) -> PyResult < Bound < ' py , PyAny > > {
187
+ self . bind_borrowed ( function. py ( ) )
188
+ . call_positional ( function, token)
189
+ }
190
+ }
191
+
192
+ impl < ' py > PyCallArgs < ' py > for Borrowed < ' _ , ' py , PyTuple > {
193
+ #[ inline]
194
+ fn call (
195
+ self ,
196
+ function : Borrowed < ' _ , ' py , PyAny > ,
197
+ kwargs : Borrowed < ' _ , ' py , PyDict > ,
132
198
_: private:: Token ,
133
199
) -> PyResult < Bound < ' py , PyAny > > {
134
200
unsafe {
@@ -137,6 +203,7 @@ impl<'py> PyCallArgs<'py> for Py<PyTuple> {
137
203
}
138
204
}
139
205
206
+ #[ inline]
140
207
fn call_positional (
141
208
self ,
142
209
function : Borrowed < ' _ , ' py , PyAny > ,
@@ -148,3 +215,101 @@ impl<'py> PyCallArgs<'py> for Py<PyTuple> {
148
215
}
149
216
}
150
217
}
218
+
219
+ #[ cfg( test) ]
220
+ #[ cfg( feature = "macros" ) ]
221
+ mod tests {
222
+ use crate :: {
223
+ pyfunction,
224
+ types:: { PyDict , PyTuple } ,
225
+ Py ,
226
+ } ;
227
+
228
+ #[ pyfunction( signature = ( * args, * * kwargs) , crate = "crate" ) ]
229
+ fn args_kwargs (
230
+ args : Py < PyTuple > ,
231
+ kwargs : Option < Py < PyDict > > ,
232
+ ) -> ( Py < PyTuple > , Option < Py < PyDict > > ) {
233
+ ( args, kwargs)
234
+ }
235
+
236
+ #[ test]
237
+ fn test_call ( ) {
238
+ use crate :: {
239
+ types:: { IntoPyDict , PyAnyMethods , PyDict , PyTuple } ,
240
+ wrap_pyfunction, Py , Python ,
241
+ } ;
242
+
243
+ Python :: with_gil ( |py| {
244
+ let f = wrap_pyfunction ! ( args_kwargs, py) . unwrap ( ) ;
245
+
246
+ let args = PyTuple :: new ( py, [ 1 , 2 , 3 ] ) . unwrap ( ) ;
247
+ let kwargs = & [ ( "foo" , 1 ) , ( "bar" , 2 ) ] . into_py_dict ( py) . unwrap ( ) ;
248
+
249
+ macro_rules! check_call {
250
+ ( $args: expr, $kwargs: expr) => {
251
+ let ( a, k) : ( Py <PyTuple >, Py <PyDict >) = f
252
+ . call( args. clone( ) , Some ( kwargs) )
253
+ . unwrap( )
254
+ . extract( )
255
+ . unwrap( ) ;
256
+ assert!( a. is( & args) ) ;
257
+ assert!( k. is( kwargs) ) ;
258
+ } ;
259
+ }
260
+
261
+ // Bound<'py, PyTuple>
262
+ check_call ! ( args. clone( ) , kwargs) ;
263
+
264
+ // &Bound<'py, PyTuple>
265
+ check_call ! ( & args, kwargs) ;
266
+
267
+ // Py<PyTuple>
268
+ check_call ! ( args. clone( ) . unbind( ) , kwargs) ;
269
+
270
+ // &Py<PyTuple>
271
+ check_call ! ( & args. as_unbound( ) , kwargs) ;
272
+
273
+ // Borrowed<'_, '_, PyTuple>
274
+ check_call ! ( args. as_borrowed( ) , kwargs) ;
275
+ } )
276
+ }
277
+
278
+ #[ test]
279
+ fn test_call_positional ( ) {
280
+ use crate :: {
281
+ types:: { PyAnyMethods , PyNone , PyTuple } ,
282
+ wrap_pyfunction, Py , Python ,
283
+ } ;
284
+
285
+ Python :: with_gil ( |py| {
286
+ let f = wrap_pyfunction ! ( args_kwargs, py) . unwrap ( ) ;
287
+
288
+ let args = PyTuple :: new ( py, [ 1 , 2 , 3 ] ) . unwrap ( ) ;
289
+
290
+ macro_rules! check_call {
291
+ ( $args: expr, $kwargs: expr) => {
292
+ let ( a, k) : ( Py <PyTuple >, Py <PyNone >) =
293
+ f. call1( args. clone( ) ) . unwrap( ) . extract( ) . unwrap( ) ;
294
+ assert!( a. is( & args) ) ;
295
+ assert!( k. is_none( py) ) ;
296
+ } ;
297
+ }
298
+
299
+ // Bound<'py, PyTuple>
300
+ check_call ! ( args. clone( ) , kwargs) ;
301
+
302
+ // &Bound<'py, PyTuple>
303
+ check_call ! ( & args, kwargs) ;
304
+
305
+ // Py<PyTuple>
306
+ check_call ! ( args. clone( ) . unbind( ) , kwargs) ;
307
+
308
+ // &Py<PyTuple>
309
+ check_call ! ( args. as_unbound( ) , kwargs) ;
310
+
311
+ // Borrowed<'_, '_, PyTuple>
312
+ check_call ! ( args. as_borrowed( ) , kwargs) ;
313
+ } )
314
+ }
315
+ }
0 commit comments