1 | //! Defines conversions between Rust and Python types. |
2 | use crate::err::PyResult; |
3 | #[cfg (feature = "experimental-inspect" )] |
4 | use crate::inspect::types::TypeInfo; |
5 | use crate::pyclass::boolean_struct::False; |
6 | use crate::types::any::PyAnyMethods; |
7 | use crate::types::PyTuple; |
8 | use crate::{ |
9 | ffi, Borrowed, Bound, BoundObject, Py, PyAny, PyClass, PyErr, PyObject, PyRef, PyRefMut, Python, |
10 | }; |
11 | use std::convert::Infallible; |
12 | |
13 | /// Returns a borrowed pointer to a Python object. |
14 | /// |
15 | /// The returned pointer will be valid for as long as `self` is. It may be null depending on the |
16 | /// implementation. |
17 | /// |
18 | /// # Examples |
19 | /// |
20 | /// ```rust |
21 | /// use pyo3::prelude::*; |
22 | /// use pyo3::ffi; |
23 | /// |
24 | /// Python::with_gil(|py| { |
25 | /// let s = "foo" .into_pyobject(py)?; |
26 | /// let ptr = s.as_ptr(); |
27 | /// |
28 | /// let is_really_a_pystring = unsafe { ffi::PyUnicode_CheckExact(ptr) }; |
29 | /// assert_eq!(is_really_a_pystring, 1); |
30 | /// # Ok::<_, PyErr>(()) |
31 | /// }) |
32 | /// # .unwrap(); |
33 | /// ``` |
34 | /// |
35 | /// # Safety |
36 | /// |
37 | /// For callers, it is your responsibility to make sure that the underlying Python object is not dropped too |
38 | /// early. For example, the following code will cause undefined behavior: |
39 | /// |
40 | /// ```rust,no_run |
41 | /// # use pyo3::prelude::*; |
42 | /// # use pyo3::ffi; |
43 | /// # |
44 | /// Python::with_gil(|py| { |
45 | /// // ERROR: calling `.as_ptr()` will throw away the temporary object and leave `ptr` dangling. |
46 | /// let ptr: *mut ffi::PyObject = 0xabad1dea_u32.into_pyobject(py)?.as_ptr(); |
47 | /// |
48 | /// let isnt_a_pystring = unsafe { |
49 | /// // `ptr` is dangling, this is UB |
50 | /// ffi::PyUnicode_CheckExact(ptr) |
51 | /// }; |
52 | /// # assert_eq!(isnt_a_pystring, 0); |
53 | /// # Ok::<_, PyErr>(()) |
54 | /// }) |
55 | /// # .unwrap(); |
56 | /// ``` |
57 | /// |
58 | /// This happens because the pointer returned by `as_ptr` does not carry any lifetime information |
59 | /// and the Python object is dropped immediately after the `0xabad1dea_u32.into_pyobject(py).as_ptr()` |
60 | /// expression is evaluated. To fix the problem, bind Python object to a local variable like earlier |
61 | /// to keep the Python object alive until the end of its scope. |
62 | /// |
63 | /// Implementors must ensure this returns a valid pointer to a Python object, which borrows a reference count from `&self`. |
64 | pub unsafe trait AsPyPointer { |
65 | /// Returns the underlying FFI pointer as a borrowed pointer. |
66 | fn as_ptr(&self) -> *mut ffi::PyObject; |
67 | } |
68 | |
69 | /// Conversion trait that allows various objects to be converted into `PyObject`. |
70 | #[deprecated ( |
71 | since = "0.23.0" , |
72 | note = "`ToPyObject` is going to be replaced by `IntoPyObject`. See the migration guide (https://pyo3.rs/v0.23.0/migration) for more information." |
73 | )] |
74 | pub trait ToPyObject { |
75 | /// Converts self into a Python object. |
76 | fn to_object(&self, py: Python<'_>) -> PyObject; |
77 | } |
78 | |
79 | /// Defines a conversion from a Rust type to a Python object. |
80 | /// |
81 | /// It functions similarly to std's [`Into`] trait, but requires a [GIL token](Python) |
82 | /// as an argument. Many functions and traits internal to PyO3 require this trait as a bound, |
83 | /// so a lack of this trait can manifest itself in different error messages. |
84 | /// |
85 | /// # Examples |
86 | /// ## With `#[pyclass]` |
87 | /// The easiest way to implement `IntoPy` is by exposing a struct as a native Python object |
88 | /// by annotating it with [`#[pyclass]`](crate::prelude::pyclass). |
89 | /// |
90 | /// ```rust |
91 | /// use pyo3::prelude::*; |
92 | /// |
93 | /// # #[allow (dead_code)] |
94 | /// #[pyclass] |
95 | /// struct Number { |
96 | /// #[pyo3(get, set)] |
97 | /// value: i32, |
98 | /// } |
99 | /// ``` |
100 | /// Python code will see this as an instance of the `Number` class with a `value` attribute. |
101 | /// |
102 | /// ## Conversion to a Python object |
103 | /// |
104 | /// However, it may not be desirable to expose the existence of `Number` to Python code. |
105 | /// `IntoPy` allows us to define a conversion to an appropriate Python object. |
106 | /// ```rust |
107 | /// #![allow(deprecated)] |
108 | /// use pyo3::prelude::*; |
109 | /// |
110 | /// # #[allow (dead_code)] |
111 | /// struct Number { |
112 | /// value: i32, |
113 | /// } |
114 | /// |
115 | /// impl IntoPy<PyObject> for Number { |
116 | /// fn into_py(self, py: Python<'_>) -> PyObject { |
117 | /// // delegates to i32's IntoPy implementation. |
118 | /// self.value.into_py(py) |
119 | /// } |
120 | /// } |
121 | /// ``` |
122 | /// Python code will see this as an `int` object. |
123 | /// |
124 | /// ## Dynamic conversion into Python objects. |
125 | /// It is also possible to return a different Python object depending on some condition. |
126 | /// This is useful for types like enums that can carry different types. |
127 | /// |
128 | /// ```rust |
129 | /// #![allow(deprecated)] |
130 | /// use pyo3::prelude::*; |
131 | /// |
132 | /// enum Value { |
133 | /// Integer(i32), |
134 | /// String(String), |
135 | /// None, |
136 | /// } |
137 | /// |
138 | /// impl IntoPy<PyObject> for Value { |
139 | /// fn into_py(self, py: Python<'_>) -> PyObject { |
140 | /// match self { |
141 | /// Self::Integer(val) => val.into_py(py), |
142 | /// Self::String(val) => val.into_py(py), |
143 | /// Self::None => py.None(), |
144 | /// } |
145 | /// } |
146 | /// } |
147 | /// # fn main() { |
148 | /// # Python::with_gil(|py| { |
149 | /// # let v = Value::Integer(73).into_py(py); |
150 | /// # let v = v.extract::<i32>(py).unwrap(); |
151 | /// # |
152 | /// # let v = Value::String("foo" .into()).into_py(py); |
153 | /// # let v = v.extract::<String>(py).unwrap(); |
154 | /// # |
155 | /// # let v = Value::None.into_py(py); |
156 | /// # let v = v.extract::<Option<Vec<i32>>>(py).unwrap(); |
157 | /// # }); |
158 | /// # } |
159 | /// ``` |
160 | /// Python code will see this as any of the `int`, `string` or `None` objects. |
161 | #[cfg_attr ( |
162 | diagnostic_namespace, |
163 | diagnostic::on_unimplemented( |
164 | message = "`{Self}` cannot be converted to a Python object" , |
165 | note = "`IntoPy` is automatically implemented by the `#[pyclass]` macro" , |
166 | note = "if you do not wish to have a corresponding Python type, implement it manually" , |
167 | note = "if you do not own `{Self}` you can perform a manual conversion to one of the types in `pyo3::types::*`" |
168 | ) |
169 | )] |
170 | #[deprecated ( |
171 | since = "0.23.0" , |
172 | note = "`IntoPy` is going to be replaced by `IntoPyObject`. See the migration guide (https://pyo3.rs/v0.23.0/migration) for more information." |
173 | )] |
174 | pub trait IntoPy<T>: Sized { |
175 | /// Performs the conversion. |
176 | fn into_py(self, py: Python<'_>) -> T; |
177 | } |
178 | |
179 | /// Defines a conversion from a Rust type to a Python object, which may fail. |
180 | /// |
181 | /// This trait has `#[derive(IntoPyObject)]` to automatically implement it for simple types and |
182 | /// `#[derive(IntoPyObjectRef)]` to implement the same for references. |
183 | /// |
184 | /// It functions similarly to std's [`TryInto`] trait, but requires a [GIL token](Python) |
185 | /// as an argument. |
186 | /// |
187 | /// The [`into_pyobject`][IntoPyObject::into_pyobject] method is designed for maximum flexibility and efficiency; it |
188 | /// - allows for a concrete Python type to be returned (the [`Target`][IntoPyObject::Target] associated type) |
189 | /// - allows for the smart pointer containing the Python object to be either `Bound<'py, Self::Target>` or `Borrowed<'a, 'py, Self::Target>` |
190 | /// to avoid unnecessary reference counting overhead |
191 | /// - allows for a custom error type to be returned in the event of a conversion error to avoid |
192 | /// unnecessarily creating a Python exception |
193 | /// |
194 | /// # See also |
195 | /// |
196 | /// - The [`IntoPyObjectExt`] trait, which provides convenience methods for common usages of |
197 | /// `IntoPyObject` which erase type information and convert errors to `PyErr`. |
198 | #[cfg_attr ( |
199 | diagnostic_namespace, |
200 | diagnostic::on_unimplemented( |
201 | message = "`{Self}` cannot be converted to a Python object" , |
202 | note = "`IntoPyObject` is automatically implemented by the `#[pyclass]` macro" , |
203 | note = "if you do not wish to have a corresponding Python type, implement it manually" , |
204 | note = "if you do not own `{Self}` you can perform a manual conversion to one of the types in `pyo3::types::*`" |
205 | ) |
206 | )] |
207 | pub trait IntoPyObject<'py>: Sized { |
208 | /// The Python output type |
209 | type Target; |
210 | /// The smart pointer type to use. |
211 | /// |
212 | /// This will usually be [`Bound<'py, Target>`], but in special cases [`Borrowed<'a, 'py, Target>`] can be |
213 | /// used to minimize reference counting overhead. |
214 | type Output: BoundObject<'py, Self::Target>; |
215 | /// The type returned in the event of a conversion error. |
216 | type Error: Into<PyErr>; |
217 | |
218 | /// Performs the conversion. |
219 | fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error>; |
220 | |
221 | /// Extracts the type hint information for this type when it appears as a return value. |
222 | /// |
223 | /// For example, `Vec<u32>` would return `List[int]`. |
224 | /// The default implementation returns `Any`, which is correct for any type. |
225 | /// |
226 | /// For most types, the return value for this method will be identical to that of [`FromPyObject::type_input`]. |
227 | /// It may be different for some types, such as `Dict`, to allow duck-typing: functions return `Dict` but take `Mapping` as argument. |
228 | #[cfg (feature = "experimental-inspect" )] |
229 | fn type_output() -> TypeInfo { |
230 | TypeInfo::Any |
231 | } |
232 | |
233 | /// Converts sequence of Self into a Python object. Used to specialize `Vec<u8>`, `[u8; N]` |
234 | /// and `SmallVec<[u8; N]>` as a sequence of bytes into a `bytes` object. |
235 | #[doc (hidden)] |
236 | fn owned_sequence_into_pyobject<I>( |
237 | iter: I, |
238 | py: Python<'py>, |
239 | _: private::Token, |
240 | ) -> Result<Bound<'py, PyAny>, PyErr> |
241 | where |
242 | I: IntoIterator<Item = Self> + AsRef<[Self]>, |
243 | I::IntoIter: ExactSizeIterator<Item = Self>, |
244 | { |
245 | let mut iter = iter.into_iter().map(|e| e.into_bound_py_any(py)); |
246 | let list = crate::types::list::try_new_from_iter(py, &mut iter); |
247 | list.map(Bound::into_any) |
248 | } |
249 | |
250 | /// Converts sequence of Self into a Python object. Used to specialize `&[u8]` and `Cow<[u8]>` |
251 | /// as a sequence of bytes into a `bytes` object. |
252 | #[doc (hidden)] |
253 | fn borrowed_sequence_into_pyobject<I>( |
254 | iter: I, |
255 | py: Python<'py>, |
256 | _: private::Token, |
257 | ) -> Result<Bound<'py, PyAny>, PyErr> |
258 | where |
259 | Self: private::Reference, |
260 | I: IntoIterator<Item = Self> + AsRef<[<Self as private::Reference>::BaseType]>, |
261 | I::IntoIter: ExactSizeIterator<Item = Self>, |
262 | { |
263 | let mut iter = iter.into_iter().map(|e| e.into_bound_py_any(py)); |
264 | let list = crate::types::list::try_new_from_iter(py, &mut iter); |
265 | list.map(Bound::into_any) |
266 | } |
267 | } |
268 | |
269 | pub(crate) mod private { |
270 | pub struct Token; |
271 | |
272 | pub trait Reference { |
273 | type BaseType; |
274 | } |
275 | |
276 | impl<T> Reference for &'_ T { |
277 | type BaseType = T; |
278 | } |
279 | } |
280 | |
281 | impl<'py, T> IntoPyObject<'py> for Bound<'py, T> { |
282 | type Target = T; |
283 | type Output = Bound<'py, Self::Target>; |
284 | type Error = Infallible; |
285 | |
286 | fn into_pyobject(self, _py: Python<'py>) -> Result<Self::Output, Self::Error> { |
287 | Ok(self) |
288 | } |
289 | } |
290 | |
291 | impl<'a, 'py, T> IntoPyObject<'py> for &'a Bound<'py, T> { |
292 | type Target = T; |
293 | type Output = Borrowed<'a, 'py, Self::Target>; |
294 | type Error = Infallible; |
295 | |
296 | fn into_pyobject(self, _py: Python<'py>) -> Result<Self::Output, Self::Error> { |
297 | Ok(self.as_borrowed()) |
298 | } |
299 | } |
300 | |
301 | impl<'a, 'py, T> IntoPyObject<'py> for Borrowed<'a, 'py, T> { |
302 | type Target = T; |
303 | type Output = Borrowed<'a, 'py, Self::Target>; |
304 | type Error = Infallible; |
305 | |
306 | fn into_pyobject(self, _py: Python<'py>) -> Result<Self::Output, Self::Error> { |
307 | Ok(self) |
308 | } |
309 | } |
310 | |
311 | impl<'a, 'py, T> IntoPyObject<'py> for &Borrowed<'a, 'py, T> { |
312 | type Target = T; |
313 | type Output = Borrowed<'a, 'py, Self::Target>; |
314 | type Error = Infallible; |
315 | |
316 | fn into_pyobject(self, _py: Python<'py>) -> Result<Self::Output, Self::Error> { |
317 | Ok(*self) |
318 | } |
319 | } |
320 | |
321 | impl<'py, T> IntoPyObject<'py> for Py<T> { |
322 | type Target = T; |
323 | type Output = Bound<'py, Self::Target>; |
324 | type Error = Infallible; |
325 | |
326 | fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> { |
327 | Ok(self.into_bound(py)) |
328 | } |
329 | } |
330 | |
331 | impl<'a, 'py, T> IntoPyObject<'py> for &'a Py<T> { |
332 | type Target = T; |
333 | type Output = Borrowed<'a, 'py, Self::Target>; |
334 | type Error = Infallible; |
335 | |
336 | fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> { |
337 | Ok(self.bind_borrowed(py)) |
338 | } |
339 | } |
340 | |
341 | impl<'a, 'py, T> IntoPyObject<'py> for &&'a T |
342 | where |
343 | &'a T: IntoPyObject<'py>, |
344 | { |
345 | type Target = <&'a T as IntoPyObject<'py>>::Target; |
346 | type Output = <&'a T as IntoPyObject<'py>>::Output; |
347 | type Error = <&'a T as IntoPyObject<'py>>::Error; |
348 | |
349 | #[inline ] |
350 | fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> { |
351 | (*self).into_pyobject(py) |
352 | } |
353 | } |
354 | |
355 | mod into_pyobject_ext { |
356 | pub trait Sealed {} |
357 | impl<'py, T> Sealed for T where T: super::IntoPyObject<'py> {} |
358 | } |
359 | |
360 | /// Convenience methods for common usages of [`IntoPyObject`]. Every type that implements |
361 | /// [`IntoPyObject`] also implements this trait. |
362 | /// |
363 | /// These methods: |
364 | /// - Drop type information from the output, returning a `PyAny` object. |
365 | /// - Always convert the `Error` type to `PyErr`, which may incur a performance penalty but it |
366 | /// more convenient in contexts where the `?` operator would produce a `PyErr` anyway. |
367 | pub trait IntoPyObjectExt<'py>: IntoPyObject<'py> + into_pyobject_ext::Sealed { |
368 | /// Converts `self` into an owned Python object, dropping type information. |
369 | #[inline ] |
370 | fn into_bound_py_any(self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> { |
371 | match self.into_pyobject(py) { |
372 | Ok(obj) => Ok(obj.into_any().into_bound()), |
373 | Err(err) => Err(err.into()), |
374 | } |
375 | } |
376 | |
377 | /// Converts `self` into an owned Python object, dropping type information and unbinding it |
378 | /// from the `'py` lifetime. |
379 | #[inline ] |
380 | fn into_py_any(self, py: Python<'py>) -> PyResult<Py<PyAny>> { |
381 | match self.into_pyobject(py) { |
382 | Ok(obj) => Ok(obj.into_any().unbind()), |
383 | Err(err) => Err(err.into()), |
384 | } |
385 | } |
386 | |
387 | /// Converts `self` into a Python object. |
388 | /// |
389 | /// This is equivalent to calling [`into_pyobject`][IntoPyObject::into_pyobject] followed |
390 | /// with `.map_err(Into::into)` to convert the error type to [`PyErr`]. This is helpful |
391 | /// for generic code which wants to make use of the `?` operator. |
392 | #[inline ] |
393 | fn into_pyobject_or_pyerr(self, py: Python<'py>) -> PyResult<Self::Output> { |
394 | match self.into_pyobject(py) { |
395 | Ok(obj) => Ok(obj), |
396 | Err(err) => Err(err.into()), |
397 | } |
398 | } |
399 | } |
400 | |
401 | impl<'py, T> IntoPyObjectExt<'py> for T where T: IntoPyObject<'py> {} |
402 | |
403 | /// Extract a type from a Python object. |
404 | /// |
405 | /// |
406 | /// Normal usage is through the `extract` methods on [`Bound`] and [`Py`], which forward to this trait. |
407 | /// |
408 | /// # Examples |
409 | /// |
410 | /// ```rust |
411 | /// use pyo3::prelude::*; |
412 | /// use pyo3::types::PyString; |
413 | /// |
414 | /// # fn main() -> PyResult<()> { |
415 | /// Python::with_gil(|py| { |
416 | /// // Calling `.extract()` on a `Bound` smart pointer |
417 | /// let obj: Bound<'_, PyString> = PyString::new(py, "blah" ); |
418 | /// let s: String = obj.extract()?; |
419 | /// # assert_eq!(s, "blah" ); |
420 | /// |
421 | /// // Calling `.extract(py)` on a `Py` smart pointer |
422 | /// let obj: Py<PyString> = obj.unbind(); |
423 | /// let s: String = obj.extract(py)?; |
424 | /// # assert_eq!(s, "blah" ); |
425 | /// # Ok(()) |
426 | /// }) |
427 | /// # } |
428 | /// ``` |
429 | /// |
430 | // /// FIXME: until `FromPyObject` can pick up a second lifetime, the below commentary is no longer |
431 | // /// true. Update and restore this documentation at that time. |
432 | // /// |
433 | // /// Note: depending on the implementation, the lifetime of the extracted result may |
434 | // /// depend on the lifetime of the `obj` or the `prepared` variable. |
435 | // /// |
436 | // /// For example, when extracting `&str` from a Python byte string, the resulting string slice will |
437 | // /// point to the existing string data (lifetime: `'py`). |
438 | // /// On the other hand, when extracting `&str` from a Python Unicode string, the preparation step |
439 | // /// will convert the string to UTF-8, and the resulting string slice will have lifetime `'prepared`. |
440 | // /// Since which case applies depends on the runtime type of the Python object, |
441 | // /// both the `obj` and `prepared` variables must outlive the resulting string slice. |
442 | /// |
443 | /// During the migration of PyO3 from the "GIL Refs" API to the `Bound<T>` smart pointer, this trait |
444 | /// has two methods `extract` and `extract_bound` which are defaulted to call each other. To avoid |
445 | /// infinite recursion, implementors must implement at least one of these methods. The recommendation |
446 | /// is to implement `extract_bound` and leave `extract` as the default implementation. |
447 | pub trait FromPyObject<'py>: Sized { |
448 | /// Extracts `Self` from the bound smart pointer `obj`. |
449 | /// |
450 | /// Implementors are encouraged to implement this method and leave `extract` defaulted, as |
451 | /// this will be most compatible with PyO3's future API. |
452 | fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self>; |
453 | |
454 | /// Extracts the type hint information for this type when it appears as an argument. |
455 | /// |
456 | /// For example, `Vec<u32>` would return `Sequence[int]`. |
457 | /// The default implementation returns `Any`, which is correct for any type. |
458 | /// |
459 | /// For most types, the return value for this method will be identical to that of |
460 | /// [`IntoPyObject::type_output`]. It may be different for some types, such as `Dict`, |
461 | /// to allow duck-typing: functions return `Dict` but take `Mapping` as argument. |
462 | #[cfg (feature = "experimental-inspect" )] |
463 | fn type_input() -> TypeInfo { |
464 | TypeInfo::Any |
465 | } |
466 | } |
467 | |
468 | mod from_py_object_bound_sealed { |
469 | /// Private seal for the `FromPyObjectBound` trait. |
470 | /// |
471 | /// This prevents downstream types from implementing the trait before |
472 | /// PyO3 is ready to declare the trait as public API. |
473 | pub trait Sealed {} |
474 | |
475 | // This generic implementation is why the seal is separate from |
476 | // `crate::sealed::Sealed`. |
477 | impl<'py, T> Sealed for T where T: super::FromPyObject<'py> {} |
478 | impl Sealed for &'_ str {} |
479 | impl Sealed for std::borrow::Cow<'_, str> {} |
480 | impl Sealed for &'_ [u8] {} |
481 | impl Sealed for std::borrow::Cow<'_, [u8]> {} |
482 | } |
483 | |
484 | /// Expected form of [`FromPyObject`] to be used in a future PyO3 release. |
485 | /// |
486 | /// The difference between this and `FromPyObject` is that this trait takes an |
487 | /// additional lifetime `'a`, which is the lifetime of the input `Bound`. |
488 | /// |
489 | /// This allows implementations for `&'a str` and `&'a [u8]`, which could not |
490 | /// be expressed by the existing `FromPyObject` trait once the GIL Refs API was |
491 | /// removed. |
492 | /// |
493 | /// # Usage |
494 | /// |
495 | /// Users are prevented from implementing this trait, instead they should implement |
496 | /// the normal `FromPyObject` trait. This trait has a blanket implementation |
497 | /// for `T: FromPyObject`. |
498 | /// |
499 | /// The only case where this trait may have a use case to be implemented is when the |
500 | /// lifetime of the extracted value is tied to the lifetime `'a` of the input `Bound` |
501 | /// instead of the GIL lifetime `py`, as is the case for the `&'a str` implementation. |
502 | /// |
503 | /// Please contact the PyO3 maintainers if you believe you have a use case for implementing |
504 | /// this trait before PyO3 is ready to change the main `FromPyObject` trait to take an |
505 | /// additional lifetime. |
506 | /// |
507 | /// Similarly, users should typically not call these trait methods and should instead |
508 | /// use this via the `extract` method on `Bound` and `Py`. |
509 | pub trait FromPyObjectBound<'a, 'py>: Sized + from_py_object_bound_sealed::Sealed { |
510 | /// Extracts `Self` from the bound smart pointer `obj`. |
511 | /// |
512 | /// Users are advised against calling this method directly: instead, use this via |
513 | /// [`Bound<'_, PyAny>::extract`] or [`Py::extract`]. |
514 | fn from_py_object_bound(ob: Borrowed<'a, 'py, PyAny>) -> PyResult<Self>; |
515 | |
516 | /// Extracts the type hint information for this type when it appears as an argument. |
517 | /// |
518 | /// For example, `Vec<u32>` would return `Sequence[int]`. |
519 | /// The default implementation returns `Any`, which is correct for any type. |
520 | /// |
521 | /// For most types, the return value for this method will be identical to that of |
522 | /// [`IntoPyObject::type_output`]. It may be different for some types, such as `Dict`, |
523 | /// to allow duck-typing: functions return `Dict` but take `Mapping` as argument. |
524 | #[cfg (feature = "experimental-inspect" )] |
525 | fn type_input() -> TypeInfo { |
526 | TypeInfo::Any |
527 | } |
528 | } |
529 | |
530 | impl<'py, T> FromPyObjectBound<'_, 'py> for T |
531 | where |
532 | T: FromPyObject<'py>, |
533 | { |
534 | fn from_py_object_bound(ob: Borrowed<'_, 'py, PyAny>) -> PyResult<Self> { |
535 | Self::extract_bound(&ob) |
536 | } |
537 | |
538 | #[cfg (feature = "experimental-inspect" )] |
539 | fn type_input() -> TypeInfo { |
540 | <T as FromPyObject>::type_input() |
541 | } |
542 | } |
543 | |
544 | /// Identity conversion: allows using existing `PyObject` instances where |
545 | /// `T: ToPyObject` is expected. |
546 | #[allow (deprecated)] |
547 | impl<T: ?Sized + ToPyObject> ToPyObject for &'_ T { |
548 | #[inline ] |
549 | fn to_object(&self, py: Python<'_>) -> PyObject { |
550 | <T as ToPyObject>::to_object(*self, py) |
551 | } |
552 | } |
553 | |
554 | impl<T> FromPyObject<'_> for T |
555 | where |
556 | T: PyClass + Clone, |
557 | { |
558 | fn extract_bound(obj: &Bound<'_, PyAny>) -> PyResult<Self> { |
559 | let bound: &Bound<'_, T> = obj.downcast::<Self>()?; |
560 | Ok(bound.try_borrow()?.clone()) |
561 | } |
562 | } |
563 | |
564 | impl<'py, T> FromPyObject<'py> for PyRef<'py, T> |
565 | where |
566 | T: PyClass, |
567 | { |
568 | fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult<Self> { |
569 | obj.downcast::<T>()?.try_borrow().map_err(op:Into::into) |
570 | } |
571 | } |
572 | |
573 | impl<'py, T> FromPyObject<'py> for PyRefMut<'py, T> |
574 | where |
575 | T: PyClass<Frozen = False>, |
576 | { |
577 | fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult<Self> { |
578 | obj.downcast::<T>()?.try_borrow_mut().map_err(op:Into::into) |
579 | } |
580 | } |
581 | |
582 | /// Converts `()` to an empty Python tuple. |
583 | #[allow (deprecated)] |
584 | impl IntoPy<Py<PyTuple>> for () { |
585 | fn into_py(self, py: Python<'_>) -> Py<PyTuple> { |
586 | PyTuple::empty(py).unbind() |
587 | } |
588 | } |
589 | |
590 | impl<'py> IntoPyObject<'py> for () { |
591 | type Target = PyTuple; |
592 | type Output = Bound<'py, Self::Target>; |
593 | type Error = Infallible; |
594 | |
595 | fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> { |
596 | Ok(PyTuple::empty(py)) |
597 | } |
598 | } |
599 | |
600 | /// ```rust,compile_fail |
601 | /// use pyo3::prelude::*; |
602 | /// |
603 | /// #[pyclass] |
604 | /// struct TestClass { |
605 | /// num: u32, |
606 | /// } |
607 | /// |
608 | /// let t = TestClass { num: 10 }; |
609 | /// |
610 | /// Python::with_gil(|py| { |
611 | /// let pyvalue = Py::new(py, t).unwrap().to_object(py); |
612 | /// let t: TestClass = pyvalue.extract(py).unwrap(); |
613 | /// }) |
614 | /// ``` |
615 | mod test_no_clone {} |
616 | |