| 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 | |