@@ -409,8 +409,8 @@ impl<'a, 'py, T> IntoPyObject<'py> for &'a Py<T> {
409409/// Extract a type from a Python object.
410410///
411411///
412- /// Normal usage is through the `extract` methods on [`Bound`], [`Borrowed`] and
413- /// [`Py`], which forward to this trait.
412+ /// Normal usage is through the `extract` methods on [`Bound`], [`Borrowed`] and [`Py`], which
413+ /// forward to this trait.
414414///
415415/// # Examples
416416///
@@ -434,38 +434,27 @@ impl<'a, 'py, T> IntoPyObject<'py> for &'a Py<T> {
434434/// # }
435435/// ```
436436///
437- /// Note: depending on the implementation, the extracted result may depend on
438- /// the Python lifetime `'py` or the input lifetime `'a` of `obj`.
439- ///
440- /// For example, when extracting a [`Cow<'a, str>`] the result may or may not
441- /// borrow from the input lifetime `'a`. The behavior depends on the runtime
442- /// type of the Python object. For a Python byte string, the existing string
443- /// data can be borrowed (lifetime: `'a`) into a [`Cow::Borrowed`]. For a Python
444- /// Unicode string, the data may have to be reencoded to UTF-8, and copied into
445- /// a [`Cow::Owned`]. It does _not_ depend on the Python lifetime `'py`
446- ///
447- /// An example of a type depending on the Python lifetime `'py` would be
448- /// [`Bound<'py, PyString>`]. This type holds the invariant of beeing allowed to
449- /// interact with the Python interpreter, so it inherits the Python lifetime
450- /// from the input. It is however _not_ tied to the input lifetime `'a` and can
451- /// be passed around independently of `obj`.
452- ///
453- /// Special care needs to be taken for collection types, for example [`PyList`].
454- /// In contrast to a Rust's [`Vec`] a Python list will not hand out references
455- /// tied to its own lifetime, but "owned" references independent of it. (Similar
456- /// to [`Vec<Arc<T>>`] where you clone the [`Arc<T>`] out). This makes it
457- /// impossible to collect borrowed types in a collection, since they would not
458- /// borrow from the original input list, but the much shorter lived element
459- /// reference. This restriction is represented in PyO3 using
460- /// [`FromPyObjectOwned`]. It is used by [`FromPyObject`] implementations on
461- /// collection types to specify it can only collect types which do _not_ borrow
462- /// from the input.
437+ /// Note: Depending on the Python version and implementation, some [`FromPyObject`] implementations
438+ /// may produce a result that borrows into the Python type. This is described by the input lifetime
439+ /// `'a` of `obj`.
440+ ///
441+ /// Types that must not borrow from the input can use [`FromPyObjectOwned`] as a restriction. This
442+ /// is most often the case for collection types. See its documentation for more details.
443+ ///
444+ /// # Details
445+ /// [`Cow<'a, str>`] is an example of an output type that may or may not borrow from the input
446+ /// lifetime `'a`. Which variant will be produced depends on the runtime type of the Python object.
447+ /// For a Python byte string, the existing string data can be borrowed for `'a` into a
448+ /// [`Cow::Borrowed`]. For a Python Unicode string, the data may have to be reencoded to UTF-8, and
449+ /// copied into a [`Cow::Owned`]. It does _not_ depend on the Python lifetime `'py`.
450+ ///
451+ /// The output type may also depend on the Python lifetime `'py`. This allows the output type to
452+ /// keep interacting with the Python interpreter. See also [`Bound<'py, T>`].
463453///
464454/// [`Cow<'a, str>`]: std::borrow::Cow
465455/// [`Cow::Borrowed`]: std::borrow::Cow::Borrowed
466456/// [`Cow::Owned`]: std::borrow::Cow::Owned
467- /// [`PyList`]: crate::types::PyList
468- /// [`Arc<T>`]: std::sync::Arc
457+
469458pub trait FromPyObject < ' a , ' py > : Sized {
470459 /// Extracts `Self` from the bound smart pointer `obj`.
471460 ///
@@ -492,11 +481,17 @@ pub trait FromPyObject<'a, 'py>: Sized {
492481 }
493482}
494483
495- /// A data structure that can be extracted without borrowing any data from the input
484+ /// A data structure that can be extracted without borrowing any data from the input.
485+ ///
486+ /// This is primarily useful for trait bounds. For example a [`FromPyObject`] implementation of a
487+ /// wrapper type may be able to borrow data from the input, but a [`FromPyObject`] implementation of
488+ /// a collection type may only extract owned data.
496489///
497- /// This is primarily useful for trait bounds. For example a `FromPyObject` implementation of a
498- /// wrapper type may be able to borrow data from the input, but a `FromPyObject` implementation of a
499- /// collection type may only extract owned data.
490+ /// For example [`PyList`] will not hand out references tied to its own lifetime, but "owned"
491+ /// references independent of it. (Similar to [`Vec<Arc<T>>`] where you clone the [`Arc<T>`] out).
492+ /// This makes it impossible to collect borrowed types in a collection, since they would not borrow
493+ /// from the original [`PyList`], but the much shorter lived element reference. See the example
494+ /// below.
500495///
501496/// ```
502497/// # use pyo3::prelude::*;
@@ -527,6 +522,9 @@ pub trait FromPyObject<'a, 'py>: Sized {
527522/// }
528523/// }
529524/// ```
525+ ///
526+ /// [`PyList`]: crate::types::PyList
527+ /// [`Arc<T>`]: std::sync::Arc
530528pub trait FromPyObjectOwned < ' py > : for < ' a > FromPyObject < ' a , ' py > { }
531529impl < ' py , T > FromPyObjectOwned < ' py > for T where T : for < ' a > FromPyObject < ' a , ' py > { }
532530
0 commit comments