docs: use versioned links from docs to guide (#4331)

* use versioned links from docs to guide

* use standard python version in `guide-build` ci job
This commit is contained in:
David Hewitt 2024-07-10 13:30:01 +01:00 committed by GitHub
parent c7c1dff710
commit 32b6a1aef1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 51 additions and 37 deletions

View File

@ -22,7 +22,7 @@ jobs:
tag_name: ${{ steps.prepare_tag.outputs.tag_name }} tag_name: ${{ steps.prepare_tag.outputs.tag_name }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: dtolnay/rust-toolchain@nightly - uses: dtolnay/rust-toolchain@nightly
- name: Setup mdBook - name: Setup mdBook

View File

@ -163,7 +163,7 @@ fn main() {
For more discussion on and workarounds for MacOS linking problems [see this issue](https://github.com/PyO3/pyo3/issues/1800#issuecomment-906786649). For more discussion on and workarounds for MacOS linking problems [see this issue](https://github.com/PyO3/pyo3/issues/1800#issuecomment-906786649).
Finally, don't forget that on MacOS the `extension-module` feature will cause `cargo test` to fail without the `--no-default-features` flag (see [the FAQ](https://pyo3.rs/main/faq.html#i-cant-run-cargo-test-im-having-linker-issues-like-symbol-not-found-or-undefined-reference-to-_pyexc_systemerror)). Finally, don't forget that on MacOS the `extension-module` feature will cause `cargo test` to fail without the `--no-default-features` flag (see [the FAQ](https://pyo3.rs/main/faq.html#i-cant-run-cargo-test-or-i-cant-build-in-a-cargo-workspace-im-having-linker-issues-like-symbol-not-found-or-undefined-reference-to-_pyexc_systemerror)).
### The `extension-module` feature ### The `extension-module` feature

View File

@ -394,8 +394,17 @@ def check_guide(session: nox.Session):
docs(session) docs(session)
session.posargs.extend(posargs) session.posargs.extend(posargs)
if toml is None:
session.error("requires Python 3.11 or `toml` to be installed")
pyo3_version = toml.loads((PYO3_DIR / "Cargo.toml").read_text())["package"][
"version"
]
remaps = { remaps = {
f"file://{PYO3_GUIDE_SRC}/([^/]*/)*?%7B%7B#PYO3_DOCS_URL}}}}": f"file://{PYO3_DOCS_TARGET}", f"file://{PYO3_GUIDE_SRC}/([^/]*/)*?%7B%7B#PYO3_DOCS_URL}}}}": f"file://{PYO3_DOCS_TARGET}",
f"https://pyo3.rs/v{pyo3_version}": f"file://{PYO3_GUIDE_TARGET}",
"https://pyo3.rs/main/": f"file://{PYO3_GUIDE_TARGET}/",
"https://pyo3.rs/latest/": f"file://{PYO3_GUIDE_TARGET}/",
"%7B%7B#PYO3_DOCS_VERSION}}": "latest", "%7B%7B#PYO3_DOCS_VERSION}}": "latest",
} }
remap_args = [] remap_args = []
@ -416,8 +425,7 @@ def check_guide(session: nox.Session):
session, session,
"lychee", "lychee",
str(PYO3_DOCS_TARGET), str(PYO3_DOCS_TARGET),
f"--remap=https://pyo3.rs/main/ file://{PYO3_GUIDE_TARGET}/", *remap_args,
f"--remap=https://pyo3.rs/latest/ file://{PYO3_GUIDE_TARGET}/",
f"--exclude=file://{PYO3_DOCS_TARGET}", f"--exclude=file://{PYO3_DOCS_TARGET}",
"--exclude=http://www.adobe.com/", "--exclude=http://www.adobe.com/",
*session.posargs, *session.posargs,

View File

@ -39,7 +39,9 @@ use target_lexicon::OperatingSystem;
/// | `#[cfg(PyPy)]` | This marks code which is run when compiling for PyPy. | /// | `#[cfg(PyPy)]` | This marks code which is run when compiling for PyPy. |
/// | `#[cfg(GraalPy)]` | This marks code which is run when compiling for GraalPy. | /// | `#[cfg(GraalPy)]` | This marks code which is run when compiling for GraalPy. |
/// ///
/// For examples of how to use these attributes, [see PyO3's guide](https://pyo3.rs/latest/building-and-distribution/multiple_python_versions.html). /// For examples of how to use these attributes,
#[doc = concat!("[see PyO3's guide](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/building-and-distribution/multiple_python_versions.html)")]
/// .
#[cfg(feature = "resolve-config")] #[cfg(feature = "resolve-config")]
pub fn use_pyo3_cfgs() { pub fn use_pyo3_cfgs() {
print_expected_cfgs(); print_expected_cfgs();

View File

@ -221,11 +221,10 @@
//! [`maturin`]: https://github.com/PyO3/maturin "Build and publish crates with pyo3, rust-cpython and cffi bindings as well as rust binaries as python packages" //! [`maturin`]: https://github.com/PyO3/maturin "Build and publish crates with pyo3, rust-cpython and cffi bindings as well as rust binaries as python packages"
//! [`pyo3-build-config`]: https://docs.rs/pyo3-build-config //! [`pyo3-build-config`]: https://docs.rs/pyo3-build-config
//! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book" //! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book"
//! [manual_builds]: https://pyo3.rs/latest/building-and-distribution.html#manual-builds "Manual builds - Building and Distribution - PyO3 user guide" #![doc = concat!("[manual_builds]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/building-and-distribution.html#manual-builds \"Manual builds - Building and Distribution - PyO3 user guide\"")]
//! [setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions" //! [setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions"
//! [PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI" //! [PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI"
//! [Features chapter of the guide]: https://pyo3.rs/latest/features.html#features-reference "Features Reference - PyO3 user guide" #![doc = concat!("[Features chapter of the guide]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/features.html#features-reference \"Features Reference - PyO3 user guide\"")]
#![allow( #![allow(
missing_docs, missing_docs,
non_camel_case_types, non_camel_case_types,

View File

@ -231,17 +231,19 @@ pub fn build_py_class(
if let Some(lt) = class.generics.lifetimes().next() { if let Some(lt) = class.generics.lifetimes().next() {
bail_spanned!( bail_spanned!(
lt.span() => lt.span() => concat!(
"#[pyclass] cannot have lifetime parameters. \ "#[pyclass] cannot have lifetime parameters. For an explanation, see \
For an explanation, see https://pyo3.rs/latest/class.html#no-lifetime-parameters" https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#no-lifetime-parameters"
)
); );
} }
ensure_spanned!( ensure_spanned!(
class.generics.params.is_empty(), class.generics.params.is_empty(),
class.generics.span() => class.generics.span() => concat!(
"#[pyclass] cannot have generic parameters. \ "#[pyclass] cannot have generic parameters. For an explanation, see \
For an explanation, see https://pyo3.rs/latest/class.html#no-generic-parameters" https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#no-generic-parameters"
)
); );
let mut field_options: Vec<(&syn::Field, FieldPyO3Options)> = match &mut class.fields { let mut field_options: Vec<(&syn::Field, FieldPyO3Options)> = match &mut class.fields {

View File

@ -32,7 +32,7 @@ use syn::{parse::Nothing, parse_macro_input, Item};
/// `#[pymodule]` implementation generates a hidden module with the same name containing /// `#[pymodule]` implementation generates a hidden module with the same name containing
/// metadata about the module, which is used by `wrap_pymodule!`). /// metadata about the module, which is used by `wrap_pymodule!`).
/// ///
/// [1]: https://pyo3.rs/latest/module.html #[doc = concat!("[1]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/module.html")]
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn pymodule(args: TokenStream, input: TokenStream) -> TokenStream { pub fn pymodule(args: TokenStream, input: TokenStream) -> TokenStream {
match parse_macro_input!(input as Item) { match parse_macro_input!(input as Item) {
@ -99,17 +99,17 @@ pub fn pyclass(attr: TokenStream, input: TokenStream) -> TokenStream {
/// multiple `#[pymethods]` blocks for a single `#[pyclass]`. /// multiple `#[pymethods]` blocks for a single `#[pyclass]`.
/// This will add a transitive dependency on the [`inventory`][3] crate. /// This will add a transitive dependency on the [`inventory`][3] crate.
/// ///
/// [1]: https://pyo3.rs/latest/class.html#instance-methods #[doc = concat!("[1]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#instance-methods")]
/// [2]: https://pyo3.rs/latest/features.html#multiple-pymethods #[doc = concat!("[2]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/features.html#multiple-pymethods")]
/// [3]: https://docs.rs/inventory/ /// [3]: https://docs.rs/inventory/
/// [4]: https://pyo3.rs/latest/class.html#constructor #[doc = concat!("[4]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#constructor")]
/// [5]: https://pyo3.rs/latest/class.html#object-properties-using-getter-and-setter #[doc = concat!("[5]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#object-properties-using-getter-and-setter")]
/// [6]: https://pyo3.rs/latest/class.html#static-methods #[doc = concat!("[6]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#static-methods")]
/// [7]: https://pyo3.rs/latest/class.html#class-methods #[doc = concat!("[7]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#class-methods")]
/// [8]: https://pyo3.rs/latest/class.html#callable-objects #[doc = concat!("[8]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#callable-objects")]
/// [9]: https://pyo3.rs/latest/class.html#class-attributes #[doc = concat!("[9]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#class-attributes")]
/// [10]: https://pyo3.rs/latest/class.html#method-arguments #[doc = concat!("[10]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#method-arguments")]
/// [11]: https://pyo3.rs/latest/class.html#object-properties-using-pyo3get-set #[doc = concat!("[11]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#object-properties-using-pyo3get-set")]
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn pymethods(attr: TokenStream, input: TokenStream) -> TokenStream { pub fn pymethods(attr: TokenStream, input: TokenStream) -> TokenStream {
let methods_type = if cfg!(feature = "multiple-pymethods") { let methods_type = if cfg!(feature = "multiple-pymethods") {
@ -138,7 +138,7 @@ pub fn pymethods(attr: TokenStream, input: TokenStream) -> TokenStream {
/// `#[pyfunction]` implementation generates a hidden module with the same name containing /// `#[pyfunction]` implementation generates a hidden module with the same name containing
/// metadata about the function, which is used by `wrap_pyfunction!`). /// metadata about the function, which is used by `wrap_pyfunction!`).
/// ///
/// [1]: https://pyo3.rs/latest/function.html #[doc = concat!("[1]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/function.html")]
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn pyfunction(attr: TokenStream, input: TokenStream) -> TokenStream { pub fn pyfunction(attr: TokenStream, input: TokenStream) -> TokenStream {
let mut ast = parse_macro_input!(input as syn::ItemFn); let mut ast = parse_macro_input!(input as syn::ItemFn);

View File

@ -744,7 +744,8 @@ impl<T> IntoPy<PyObject> for Borrowed<'_, '_, T> {
/// - [`Py::borrow`], [`Py::try_borrow`], [`Py::borrow_mut`], or [`Py::try_borrow_mut`], /// - [`Py::borrow`], [`Py::try_borrow`], [`Py::borrow_mut`], or [`Py::try_borrow_mut`],
/// ///
/// to get a (mutable) reference to a contained pyclass, using a scheme similar to std's [`RefCell`]. /// to get a (mutable) reference to a contained pyclass, using a scheme similar to std's [`RefCell`].
/// See the [guide entry](https://pyo3.rs/latest/class.html#bound-and-interior-mutability) /// See the
#[doc = concat!("[guide entry](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#bound-and-interior-mutability)")]
/// for more information. /// for more information.
/// - You can call methods directly on `Py` with [`Py::call_bound`], [`Py::call_method_bound`] and friends. /// - You can call methods directly on `Py` with [`Py::call_bound`], [`Py::call_method_bound`] and friends.
/// ///

View File

@ -295,25 +295,25 @@
//! [`rust_decimal`]: ./rust_decimal/index.html "Documenation about the `rust_decimal` feature." //! [`rust_decimal`]: ./rust_decimal/index.html "Documenation about the `rust_decimal` feature."
//! [`Decimal`]: https://docs.rs/rust_decimal/latest/rust_decimal/struct.Decimal.html //! [`Decimal`]: https://docs.rs/rust_decimal/latest/rust_decimal/struct.Decimal.html
//! [`serde`]: <./serde/index.html> "Documentation about the `serde` feature." //! [`serde`]: <./serde/index.html> "Documentation about the `serde` feature."
//! [calling_rust]: https://pyo3.rs/latest/python-from-rust.html "Calling Python from Rust - PyO3 user guide" #![doc = concat!("[calling_rust]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/python-from-rust.html \"Calling Python from Rust - PyO3 user guide\"")]
//! [examples subdirectory]: https://github.com/PyO3/pyo3/tree/main/examples //! [examples subdirectory]: https://github.com/PyO3/pyo3/tree/main/examples
//! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book" //! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book"
//! [global interpreter lock]: https://docs.python.org/3/glossary.html#term-global-interpreter-lock //! [global interpreter lock]: https://docs.python.org/3/glossary.html#term-global-interpreter-lock
//! [hashbrown]: https://docs.rs/hashbrown //! [hashbrown]: https://docs.rs/hashbrown
//! [smallvec]: https://docs.rs/smallvec //! [smallvec]: https://docs.rs/smallvec
//! [indexmap]: https://docs.rs/indexmap //! [indexmap]: https://docs.rs/indexmap
//! [manual_builds]: https://pyo3.rs/latest/building-and-distribution.html#manual-builds "Manual builds - Building and Distribution - PyO3 user guide" #![doc = concat!("[manual_builds]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/building-and-distribution.html#manual-builds \"Manual builds - Building and Distribution - PyO3 user guide\"")]
//! [num-bigint]: https://docs.rs/num-bigint //! [num-bigint]: https://docs.rs/num-bigint
//! [num-complex]: https://docs.rs/num-complex //! [num-complex]: https://docs.rs/num-complex
//! [num-rational]: https://docs.rs/num-rational //! [num-rational]: https://docs.rs/num-rational
//! [serde]: https://docs.rs/serde //! [serde]: https://docs.rs/serde
//! [setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions" //! [setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions"
//! [the guide]: https://pyo3.rs "PyO3 user guide" //! [the guide]: https://pyo3.rs "PyO3 user guide"
//! [types]: https://pyo3.rs/latest/types.html "GIL lifetimes, mutability and Python object types" #![doc = concat!("[types]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/types.html \"GIL lifetimes, mutability and Python object types\"")]
//! [PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI" //! [PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI"
//! [Python from Rust]: https://github.com/PyO3/pyo3#using-python-from-rust //! [Python from Rust]: https://github.com/PyO3/pyo3#using-python-from-rust
//! [Rust from Python]: https://github.com/PyO3/pyo3#using-rust-from-python //! [Rust from Python]: https://github.com/PyO3/pyo3#using-rust-from-python
//! [Features chapter of the guide]: https://pyo3.rs/latest/features.html#features-reference "Features Reference - PyO3 user guide" #![doc = concat!("[Features chapter of the guide]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/features.html#features-reference \"Features Reference - PyO3 user guide\"")]
//! [`Ungil`]: crate::marker::Ungil //! [`Ungil`]: crate::marker::Ungil
pub use crate::class::*; pub use crate::class::*;
pub use crate::conversion::{AsPyPointer, FromPyObject, IntoPy, ToPyObject}; pub use crate::conversion::{AsPyPointer, FromPyObject, IntoPy, ToPyObject};
@ -483,7 +483,7 @@ pub use pyo3_macros::{pyfunction, pymethods, pymodule, FromPyObject};
/// For more on creating Python classes, /// For more on creating Python classes,
/// see the [class section of the guide][1]. /// see the [class section of the guide][1].
/// ///
/// [1]: https://pyo3.rs/latest/class.html #[doc = concat!("[1]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html")]
#[cfg(feature = "macros")] #[cfg(feature = "macros")]
pub use pyo3_macros::pyclass; pub use pyo3_macros::pyclass;

View File

@ -59,7 +59,9 @@ unsafe impl<T> Sync for GILProtected<T> where T: Send {}
/// Unlike `once_cell::sync` which blocks threads to achieve thread safety, this implementation /// Unlike `once_cell::sync` which blocks threads to achieve thread safety, this implementation
/// uses the Python GIL to mediate concurrent access. This helps in cases where `once_cell` or /// uses the Python GIL to mediate concurrent access. This helps in cases where `once_cell` or
/// `lazy_static`'s synchronization strategy can lead to deadlocks when interacting with the Python /// `lazy_static`'s synchronization strategy can lead to deadlocks when interacting with the Python
/// GIL. For an example, see [the FAQ section](https://pyo3.rs/latest/faq.html) of the guide. /// GIL. For an example, see
#[doc = concat!("[the FAQ section](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/faq.html)")]
/// of the guide.
/// ///
/// Note that: /// Note that:
/// 1) `get_or_init` and `get_or_try_init` do not protect against infinite recursion /// 1) `get_or_init` and `get_or_try_init` do not protect against infinite recursion

View File

@ -304,7 +304,7 @@ impl PyModule {
/// make an *instance* of `Foo` (or *get* one for that matter, as we haven't exported /// make an *instance* of `Foo` (or *get* one for that matter, as we haven't exported
/// anything that can return instances of `Foo`). /// anything that can return instances of `Foo`).
/// ///
/// [1]: https://pyo3.rs/latest/class.html#constructor #[doc = concat!("[1]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#constructor")]
pub fn add_class<T>(&self) -> PyResult<()> pub fn add_class<T>(&self) -> PyResult<()>
where where
T: PyClass, T: PyClass,
@ -509,7 +509,7 @@ pub trait PyModuleMethods<'py>: crate::sealed::Sealed {
/// make an *instance* of `Foo` (or *get* one for that matter, as we haven't exported /// make an *instance* of `Foo` (or *get* one for that matter, as we haven't exported
/// anything that can return instances of `Foo`). /// anything that can return instances of `Foo`).
/// ///
/// [1]: https://pyo3.rs/latest/class.html#constructor #[doc = concat!("[1]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#constructor")]
fn add_class<T>(&self) -> PyResult<()> fn add_class<T>(&self) -> PyResult<()>
where where
T: PyClass; T: PyClass;

View File

@ -1,10 +1,10 @@
error: #[pyclass] cannot have generic parameters. For an explanation, see https://pyo3.rs/latest/class.html#no-generic-parameters error: #[pyclass] cannot have generic parameters. For an explanation, see https://pyo3.rs/v0.23.0-dev/class.html#no-generic-parameters
--> tests/ui/reject_generics.rs:4:25 --> tests/ui/reject_generics.rs:4:25
| |
4 | struct ClassWithGenerics<A> { 4 | struct ClassWithGenerics<A> {
| ^ | ^
error: #[pyclass] cannot have lifetime parameters. For an explanation, see https://pyo3.rs/latest/class.html#no-lifetime-parameters error: #[pyclass] cannot have lifetime parameters. For an explanation, see https://pyo3.rs/v0.23.0-dev/class.html#no-lifetime-parameters
--> tests/ui/reject_generics.rs:9:27 --> tests/ui/reject_generics.rs:9:27
| |
9 | struct ClassWithLifetimes<'a> { 9 | struct ClassWithLifetimes<'a> {