Skip to content

Commit

Permalink
docs: improve signposting to bound and traits (#4325)
Browse files Browse the repository at this point in the history
* docs: improve signposting to bound and traits

* update UI tests
  • Loading branch information
davidhewitt committed Jul 17, 2024
1 parent 840ae08 commit 48a055b
Show file tree
Hide file tree
Showing 33 changed files with 190 additions and 39 deletions.
14 changes: 13 additions & 1 deletion src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,19 @@ pub unsafe trait PyNativeType: Sized {
}
}

/// A GIL-attached equivalent to `Py`.
/// A GIL-attached equivalent to [`Py<T>`].
///
/// This type can be thought of as equivalent to the tuple `(Py<T>, Python<'py>)`. By having the `'py`
/// lifetime of the [`Python<'py>`] token, this ties the lifetime of the [`Bound<'py, T>`] smart pointer
/// to the lifetime of the GIL and allows PyO3 to call Python APIs at maximum efficiency.
///
/// To access the object in situations where the GIL is not held, convert it to [`Py<T>`]
/// using [`.unbind()`][Bound::unbind]. This includes situations where the GIL is temporarily
/// released, such as [`Python::allow_threads`](crate::Python::allow_threads)'s closure.
///
/// See
#[doc = concat!("[the guide](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/types.html#boundpy-t)")]
/// for more detail.
#[repr(transparent)]
pub struct Bound<'py, T>(Python<'py>, ManuallyDrop<Py<T>>);

Expand Down
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,6 @@ pub mod marshal;
#[macro_use]
pub mod sync;
pub mod panic;
pub mod prelude;
pub mod pybacked;
pub mod pycell;
pub mod pyclass;
Expand Down Expand Up @@ -495,6 +494,10 @@ mod macros;
#[cfg(feature = "experimental-inspect")]
pub mod inspect;

// Putting the declaration of prelude at the end seems to help encourage rustc and rustdoc to prefer using
// other paths to the same items. (e.g. `pyo3::types::PyAnyMethods` instead of `pyo3::prelude::PyAnyMethods`).
pub mod prelude;

/// Ths module only contains re-exports of pyo3 deprecation warnings and exists
/// purely to make compiler error messages nicer.
///
Expand Down
25 changes: 7 additions & 18 deletions src/types/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,15 @@ use std::os::raw::c_int;

/// Represents any Python object.
///
/// It currently only appears as a *reference*, `&PyAny`,
/// with a lifetime that represents the scope during which the GIL is held.
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyAny>`][crate::Py] or [`Bound<'py, PyAny>`][Bound].
///
/// `PyAny` has some interesting properties, which it shares
/// with the other [native Python types](crate::types):
/// For APIs available on all Python objects, see the [`PyAnyMethods`] trait which is implemented for
/// [`Bound<'py, PyAny>`][Bound].
///
/// - It can only be obtained and used while the GIL is held,
/// therefore its API does not require a [`Python<'py>`](crate::Python) token.
/// - It can't be used in situations where the GIL is temporarily released,
/// such as [`Python::allow_threads`](crate::Python::allow_threads)'s closure.
/// - The underlying Python object, if mutable, can be mutated through any reference.
/// - It can be converted to the GIL-independent [`Py`]`<`[`PyAny`]`>`,
/// allowing it to outlive the GIL scope. However, using [`Py`]`<`[`PyAny`]`>`'s API
/// *does* require a [`Python<'py>`](crate::Python) token.
///
/// It can be cast to a concrete type with PyAny::downcast (for native Python types only)
/// and FromPyObject::extract. See their documentation for more information.
///
/// See [the guide](https://pyo3.rs/latest/types.html) for an explanation
/// of the different Python object types.
/// See
#[doc = concat!("[the guide](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/types.html#concrete-python-types)")]
/// for an explanation of the different Python object types.
#[repr(transparent)]
pub struct PyAny(UnsafeCell<ffi::PyObject>);

Expand Down
6 changes: 6 additions & 0 deletions src/types/boolobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ use crate::{
use super::any::PyAnyMethods;

/// Represents a Python `bool`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyBool>`][crate::Py] or [`Bound<'py, PyBool>`][Bound].
///
/// For APIs available on `bool` objects, see the [`PyBoolMethods`] trait which is implemented for
/// [`Bound<'py, PyBool>`][Bound].
#[repr(transparent)]
pub struct PyBool(PyAny);

Expand Down
6 changes: 6 additions & 0 deletions src/types/bytearray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ use crate::{AsPyPointer, PyNativeType};
use std::slice;

/// Represents a Python `bytearray`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyByteArray>`][crate::Py] or [`Bound<'py, PyByteArray>`][Bound].
///
/// For APIs available on `bytearray` objects, see the [`PyByteArrayMethods`] trait which is implemented for
/// [`Bound<'py, PyByteArray>`][Bound].
#[repr(transparent)]
pub struct PyByteArray(PyAny);

Expand Down
10 changes: 8 additions & 2 deletions src/types/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@ use std::str;
///
/// This type is immutable.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyBytes>`][crate::Py] or [`Bound<'py, PyBytes>`][Bound].
///
/// For APIs available on `bytes` objects, see the [`PyBytesMethods`] trait which is implemented for
/// [`Bound<'py, PyBytes>`][Bound].
///
/// # Equality
///
/// For convenience, [`Bound<'py, PyBytes>`] implements [`PartialEq<[u8]>`] to allow comparing the
/// data in the Python bytes to a Rust `[u8]`.
/// For convenience, [`Bound<'py, PyBytes>`][Bound] implements [`PartialEq<[u8]>`][PartialEq] to allow comparing the
/// data in the Python bytes to a Rust `[u8]` byte slice.
///
/// This is not always the most appropriate way to compare Python bytes, as Python bytes subclasses
/// may have different equality semantics. In situations where subclasses overriding equality might be
Expand Down
5 changes: 5 additions & 0 deletions src/types/capsule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ use std::os::raw::{c_char, c_int, c_void};
/// > in one module available to other modules, so the regular import mechanism can
/// > be used to access C APIs defined in dynamically loaded modules.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyCapsule>`][crate::Py] or [`Bound<'py, PyCapsule>`][Bound].
///
/// For APIs available on capsule objects, see the [`PyCapsuleMethods`] trait which is implemented for
/// [`Bound<'py, PyCapsule>`][Bound].
///
/// # Example
/// ```
Expand Down
3 changes: 3 additions & 0 deletions src/types/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ use crate::ffi;
use crate::PyAny;

/// Represents a Python code object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyCode>`][crate::Py] or [`Bound<'py, PyCode>`][crate::Bound].
#[repr(transparent)]
pub struct PyCode(PyAny);

Expand Down
6 changes: 6 additions & 0 deletions src/types/complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ use std::os::raw::c_double;

/// Represents a Python [`complex`](https://docs.python.org/3/library/functions.html#complex) object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyComplex>`][crate::Py] or [`Bound<'py, PyComplex>`][Bound].
///
/// For APIs available on `complex` objects, see the [`PyComplexMethods`] trait which is implemented for
/// [`Bound<'py, PyComplex>`][Bound].
///
/// Note that `PyComplex` supports only basic operations. For advanced operations
/// consider using [num-complex](https://docs.rs/num-complex)'s [`Complex`] type instead.
/// This optional dependency can be activated with the `num-complex` feature flag.
Expand Down
23 changes: 19 additions & 4 deletions src/types/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,10 @@ pub trait PyTzInfoAccess<'py> {
fn get_tzinfo_bound(&self) -> Option<Bound<'py, PyTzInfo>>;
}

/// Bindings around `datetime.date`
/// Bindings around `datetime.date`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyDate>`][crate::Py] or [`Bound<'py, PyDate>`][Bound].
#[repr(transparent)]
pub struct PyDate(PyAny);
pyobject_native_type!(
Expand Down Expand Up @@ -279,7 +282,10 @@ impl PyDateAccess for Bound<'_, PyDate> {
}
}

/// Bindings for `datetime.datetime`
/// Bindings for `datetime.datetime`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyDateTime>`][crate::Py] or [`Bound<'py, PyDateTime>`][Bound].
#[repr(transparent)]
pub struct PyDateTime(PyAny);
pyobject_native_type!(
Expand Down Expand Up @@ -578,7 +584,10 @@ impl<'py> PyTzInfoAccess<'py> for Bound<'py, PyDateTime> {
}
}

/// Bindings for `datetime.time`
/// Bindings for `datetime.time`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyTime>`][crate::Py] or [`Bound<'py, PyTime>`][Bound].
#[repr(transparent)]
pub struct PyTime(PyAny);
pyobject_native_type!(
Expand Down Expand Up @@ -781,6 +790,9 @@ impl<'py> PyTzInfoAccess<'py> for Bound<'py, PyTime> {

/// Bindings for `datetime.tzinfo`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyTzInfo>`][crate::Py] or [`Bound<'py, PyTzInfo>`][Bound].
///
/// This is an abstract base class and cannot be constructed directly.
/// For concrete time zone implementations, see [`timezone_utc_bound`] and
/// the [`zoneinfo` module](https://docs.python.org/3/library/zoneinfo.html).
Expand Down Expand Up @@ -834,7 +846,10 @@ pub(crate) fn timezone_from_offset<'py>(
}
}

/// Bindings for `datetime.timedelta`
/// Bindings for `datetime.timedelta`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyDelta>`][crate::Py] or [`Bound<'py, PyDelta>`][Bound].
#[repr(transparent)]
pub struct PyDelta(PyAny);
pyobject_native_type!(
Expand Down
6 changes: 6 additions & 0 deletions src/types/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ use crate::PyNativeType;
use crate::{ffi, Python, ToPyObject};

/// Represents a Python `dict`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyDict>`][crate::Py] or [`Bound<'py, PyDict>`][Bound].
///
/// For APIs available on `dict` objects, see the [`PyDictMethods`] trait which is implemented for
/// [`Bound<'py, PyDict>`][Bound].
#[repr(transparent)]
pub struct PyDict(PyAny);

Expand Down
3 changes: 3 additions & 0 deletions src/types/ellipsis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ use crate::{
};

/// Represents the Python `Ellipsis` object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyEllipsis>`][crate::Py] or [`Bound<'py, PyEllipsis>`][Bound].
#[repr(transparent)]
pub struct PyEllipsis(PyAny);

Expand Down
10 changes: 8 additions & 2 deletions src/types/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ use std::os::raw::c_double;

/// Represents a Python `float` object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyFloat>`][crate::Py] or [`Bound<'py, PyFloat>`][Bound].
///
/// For APIs available on `float` objects, see the [`PyFloatMethods`] trait which is implemented for
/// [`Bound<'py, PyFloat>`][Bound].
///
/// You can usually avoid directly working with this type
/// by using [`ToPyObject`] and [`extract`](PyAnyMethods::extract)
/// with `f32`/`f64`.
/// by using [`ToPyObject`] and [`extract`][PyAnyMethods::extract]
/// with [`f32`]/[`f64`].
#[repr(transparent)]
pub struct PyFloat(PyAny);

Expand Down
3 changes: 3 additions & 0 deletions src/types/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ use crate::ffi;
use crate::PyAny;

/// Represents a Python frame.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyFrame>`][crate::Py] or [`Bound<'py, PyFrame>`][crate::Bound].
#[repr(transparent)]
pub struct PyFrame(PyAny);

Expand Down
8 changes: 7 additions & 1 deletion src/types/frozenset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,13 @@ impl<'py> PyFrozenSetBuilder<'py> {
}
}

/// Represents a Python `frozenset`
/// Represents a Python `frozenset`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyFrozenSet>`][crate::Py] or [`Bound<'py, PyFrozenSet>`][Bound].
///
/// For APIs available on `frozenset` objects, see the [`PyFrozenSetMethods`] trait which is implemented for
/// [`Bound<'py, PyFrozenSet>`][Bound].
#[repr(transparent)]
pub struct PyFrozenSet(PyAny);

Expand Down
6 changes: 6 additions & 0 deletions src/types/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ use std::cell::UnsafeCell;
use std::ffi::CStr;

/// Represents a builtin Python function object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyCFunction>`][crate::Py] or [`Bound<'py, PyCFunction>`][Bound].
#[repr(transparent)]
pub struct PyCFunction(PyAny);

Expand Down Expand Up @@ -241,6 +244,9 @@ struct ClosureDestructor<F> {
unsafe impl<F: Send> Send for ClosureDestructor<F> {}

/// Represents a Python function object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyFunction>`][crate::Py] or [`Bound<'py, PyFunction>`][Bound].
#[repr(transparent)]
#[cfg(all(not(Py_LIMITED_API), not(all(PyPy, not(Py_3_8)))))]
pub struct PyFunction(PyAny);
Expand Down
3 changes: 3 additions & 0 deletions src/types/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ use crate::{AsPyPointer, PyDowncastError, PyNativeType};

/// A Python iterator object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyIterator>`][crate::Py] or [`Bound<'py, PyIterator>`][Bound].
///
/// # Examples
///
/// ```rust
Expand Down
6 changes: 6 additions & 0 deletions src/types/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ use crate::types::any::PyAnyMethods;
use crate::types::sequence::PySequenceMethods;

/// Represents a Python `list`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyList>`][crate::Py] or [`Bound<'py, PyList>`][Bound].
///
/// For APIs available on `list` objects, see the [`PyListMethods`] trait which is implemented for
/// [`Bound<'py, PyDict>`][Bound].
#[repr(transparent)]
pub struct PyList(PyAny);

Expand Down
6 changes: 6 additions & 0 deletions src/types/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ use crate::{err::PyDowncastError, PyNativeType};
use crate::{ffi, Py, PyTypeCheck, Python, ToPyObject};

/// Represents a reference to a Python object supporting the mapping protocol.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyMapping>`][crate::Py] or [`Bound<'py, PyMapping>`][Bound].
///
/// For APIs available on mapping objects, see the [`PyMappingMethods`] trait which is implemented for
/// [`Bound<'py, PyMapping>`][Bound].
#[repr(transparent)]
pub struct PyMapping(PyAny);
pyobject_native_type_named!(PyMapping);
Expand Down
3 changes: 3 additions & 0 deletions src/types/memoryview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ use crate::{ffi, Bound, PyAny};
use crate::{AsPyPointer, PyNativeType};

/// Represents a Python `memoryview`.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyMemoryView>`][crate::Py] or [`Bound<'py, PyMemoryView>`][Bound].
#[repr(transparent)]
pub struct PyMemoryView(PyAny);

Expand Down
6 changes: 6 additions & 0 deletions src/types/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ use {super::PyStringMethods, crate::PyNativeType};

/// Represents a Python [`module`][1] object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyModule>`][crate::Py] or [`Bound<'py, PyModule>`][Bound].
///
/// For APIs available on `module` objects, see the [`PyModuleMethods`] trait which is implemented for
/// [`Bound<'py, PyModule>`][Bound].
///
/// As with all other Python objects, modules are first class citizens.
/// This means they can be passed to or returned from functions,
/// created dynamically, assigned to variables and so forth.
Expand Down
3 changes: 3 additions & 0 deletions src/types/none.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ use crate::{
};

/// Represents the Python `None` object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyNone>`][crate::Py] or [`Bound<'py, PyNone>`][Bound].
#[repr(transparent)]
pub struct PyNone(PyAny);

Expand Down
3 changes: 3 additions & 0 deletions src/types/notimplemented.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ use crate::{
};

/// Represents the Python `NotImplemented` object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyNotImplemented>`][crate::Py] or [`Bound<'py, PyNotImplemented>`][Bound].
#[repr(transparent)]
pub struct PyNotImplemented(PyAny);

Expand Down
3 changes: 3 additions & 0 deletions src/types/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ use crate::{ffi, PyAny};

/// Represents a Python `int` object.
///
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PyLong>`][crate::Py] or [`Bound<'py, PyLong>`][crate::Bound].
///
/// You can usually avoid directly working with this type
/// by using [`ToPyObject`](crate::conversion::ToPyObject)
/// and [`extract`](super::PyAnyMethods::extract)
Expand Down
3 changes: 2 additions & 1 deletion src/types/pysuper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use crate::{PyAny, PyResult};

/// Represents a Python `super` object.
///
/// This type is immutable.
/// Values of this type are accessed via PyO3's smart pointers, e.g. as
/// [`Py<PySuper>`][crate::Py] or [`Bound<'py, PySuper>`][Bound].
#[repr(transparent)]
pub struct PySuper(PyAny);

Expand Down
Loading

0 comments on commit 48a055b

Please sign in to comment.