diff --git a/.github/workflows/guide.yml b/.github/workflows/guide.yml
index c62d2c4e..2dea1b9f 100644
--- a/.github/workflows/guide.yml
+++ b/.github/workflows/guide.yml
@@ -4,6 +4,7 @@ on:
push:
branches:
- main
+ pull_request:
release:
types: [published]
@@ -18,6 +19,11 @@ jobs:
steps:
- uses: actions/checkout@v2
+ - uses: actions-rs/toolchain@v1
+ with:
+ toolchain: nightly
+ profile: minimal
+
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v1
with:
@@ -38,11 +44,12 @@ jobs:
# This adds the docs to gh-pages-build/doc
- name: Build the doc
run: |
- cargo doc --features="default num-bigint num-complex" --no-deps
+ cargo +nightly rustdoc --lib --no-default-features --features="macros num-bigint num-complex hashbrown serde multiple-pymethods" -- --cfg docsrs
cp -r target/doc gh-pages-build/doc
echo "" > gh-pages-build/doc/index.html
- name: Deploy
+ if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'release' }}
uses: peaceiris/actions-gh-pages@v3.7.0-8
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/Cargo.toml b/Cargo.toml
index e48f49d1..533b816b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -79,3 +79,8 @@ members = [
"examples/setuptools-rust-starter",
"examples/word-count"
]
+
+[package.metadata.docs.rs]
+no-default-features = true
+features = ["macros", "num-bigint", "num-complex", "hashbrown", "serde", "multiple-pymethods"]
+rustdoc-args = ["--cfg", "docsrs"]
\ No newline at end of file
diff --git a/pyo3-macros-backend/src/lib.rs b/pyo3-macros-backend/src/lib.rs
index d2198c72..9c990d7f 100644
--- a/pyo3-macros-backend/src/lib.rs
+++ b/pyo3-macros-backend/src/lib.rs
@@ -1,6 +1,7 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
//! This crate contains the implementation of the proc macro attributes
+#![cfg_attr(docsrs, feature(doc_cfg))]
#![recursion_limit = "1024"]
// Listed first so that macros in this module are available in the rest of the crate.
diff --git a/pyo3-macros/src/lib.rs b/pyo3-macros/src/lib.rs
index 5073419b..152df18b 100644
--- a/pyo3-macros/src/lib.rs
+++ b/pyo3-macros/src/lib.rs
@@ -2,6 +2,7 @@
//! This crate declares only the proc macro attributes, as a crate defining proc macro attributes
//! must not contain any other public items.
+#![cfg_attr(docsrs, feature(doc_cfg))]
extern crate proc_macro;
use proc_macro::TokenStream;
diff --git a/src/class/mod.rs b/src/class/mod.rs
index 4b7543aa..29315a82 100644
--- a/src/class/mod.rs
+++ b/src/class/mod.rs
@@ -7,6 +7,7 @@ mod macros;
pub mod basic;
#[cfg(not(Py_LIMITED_API))]
+#[cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
pub mod buffer;
pub mod context;
pub mod descr;
@@ -23,6 +24,7 @@ pub mod sequence;
pub use self::basic::PyObjectProtocol;
#[cfg(not(Py_LIMITED_API))]
+#[cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
pub use self::buffer::PyBufferProtocol;
pub use self::context::PyContextProtocol;
pub use self::descr::PyDescrProtocol;
diff --git a/src/conversion.rs b/src/conversion.rs
index 5ec8a8e0..914c2445 100644
--- a/src/conversion.rs
+++ b/src/conversion.rs
@@ -108,6 +108,7 @@ where
T: ToPyObject,
{
#[cfg(feature = "nightly")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "nightly")))]
default fn with_borrowed_ptr(&self, py: Python, f: F) -> R
where
F: FnOnce(*mut ffi::PyObject) -> R,
@@ -122,6 +123,7 @@ where
}
#[cfg(feature = "nightly")]
+#[cfg_attr(docsrs, doc(cfg(feature = "nightly")))]
impl ToBorrowedObject for T
where
T: ToPyObject + AsPyPointer,
@@ -201,6 +203,7 @@ where
/// }
/// ```
/// Python code will see this as any of the `int`, `string` or `None` objects.
+#[cfg_attr(docsrs, doc(alias = "IntoPyCallbackOutput"))]
pub trait IntoPy: Sized {
/// Performs the conversion.
fn into_py(self, py: Python) -> T;
diff --git a/src/gil.rs b/src/gil.rs
index 2b30f904..15a7488c 100644
--- a/src/gil.rs
+++ b/src/gil.rs
@@ -45,9 +45,6 @@ pub(crate) fn gil_is_acquired() -> bool {
/// If both the Python interpreter and Python threading are already initialized,
/// this function has no effect.
///
-/// # Availability
-/// This function is not available on PyPy.
-///
/// # Panics
/// - If the Python interpreter is initialized but Python threading is not,
/// a panic occurs.
@@ -68,6 +65,7 @@ pub(crate) fn gil_is_acquired() -> bool {
/// }
/// ```
#[cfg(not(PyPy))]
+#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
#[allow(clippy::clippy::collapsible_if)] // for if cfg!
pub fn prepare_freethreaded_python() {
// Protect against race conditions when Python is not yet initialized and multiple threads
@@ -106,9 +104,6 @@ pub fn prepare_freethreaded_python() {
/// single process, it is not safe to call this function more than once. (Many such modules will not
/// initialize correctly on the second run.)
///
-/// # Availability
-/// This function is not available on PyPy.
-///
/// # Panics
/// - If the Python interpreter is already initalized before calling this function.
///
@@ -132,6 +127,7 @@ pub fn prepare_freethreaded_python() {
/// }
/// ```
#[cfg(not(PyPy))]
+#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
#[allow(clippy::clippy::collapsible_if)] // for if cfg!
pub unsafe fn with_embedded_python_interpreter(f: F) -> R
where
diff --git a/src/lib.rs b/src/lib.rs
index 298b423b..62bf441f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,5 @@
#![cfg_attr(feature = "nightly", feature(specialization))]
+#![cfg_attr(docsrs, feature(doc_cfg))]
#![allow(clippy::missing_safety_doc)] // FIXME (#698)
//! Rust bindings to the Python interpreter.
@@ -132,6 +133,7 @@ pub use crate::conversion::{
};
pub use crate::err::{PyDowncastError, PyErr, PyErrArguments, PyResult};
#[cfg(not(PyPy))]
+#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub use crate::gil::{prepare_freethreaded_python, with_embedded_python_interpreter};
pub use crate::gil::{GILGuard, GILPool};
pub use crate::instance::{Py, PyNativeType, PyObject};
@@ -159,7 +161,9 @@ mod internal_tricks;
// The CPython stable ABI does not include PyBuffer.
#[cfg(not(Py_LIMITED_API))]
+#[cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
pub mod buffer;
+
#[doc(hidden)]
pub mod callback;
pub mod class;
@@ -174,8 +178,11 @@ pub mod ffi;
pub mod freelist;
mod gil;
mod instance;
+
#[cfg(not(Py_LIMITED_API))]
+#[cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
pub mod marshal;
+
pub mod once_cell;
pub mod panic;
pub mod prelude;
diff --git a/src/types/complex.rs b/src/types/complex.rs
index fffd5145..70b782e4 100644
--- a/src/types/complex.rs
+++ b/src/types/complex.rs
@@ -34,6 +34,7 @@ impl PyComplex {
}
/// Returns `|self|`.
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
+ #[cfg_attr(docsrs, doc(cfg(not(any(Py_LIMITED_API, PyPy)))))]
pub fn abs(&self) -> c_double {
unsafe {
let val = (*(self.as_ptr() as *mut ffi::PyComplexObject)).cval;
@@ -42,6 +43,7 @@ impl PyComplex {
}
/// Returns `self ** other`
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
+ #[cfg_attr(docsrs, doc(cfg(not(any(Py_LIMITED_API, PyPy)))))]
pub fn pow(&self, other: &PyComplex) -> &PyComplex {
unsafe {
self.py()
@@ -63,6 +65,7 @@ unsafe fn complex_operation(
}
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
+#[cfg_attr(docsrs, doc(cfg(not(any(Py_LIMITED_API, PyPy)))))]
impl<'py> Add for &'py PyComplex {
type Output = &'py PyComplex;
fn add(self, other: &'py PyComplex) -> &'py PyComplex {
@@ -74,6 +77,7 @@ impl<'py> Add for &'py PyComplex {
}
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
+#[cfg_attr(docsrs, doc(cfg(not(any(Py_LIMITED_API, PyPy)))))]
impl<'py> Sub for &'py PyComplex {
type Output = &'py PyComplex;
fn sub(self, other: &'py PyComplex) -> &'py PyComplex {
@@ -85,6 +89,7 @@ impl<'py> Sub for &'py PyComplex {
}
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
+#[cfg_attr(docsrs, doc(cfg(not(any(Py_LIMITED_API, PyPy)))))]
impl<'py> Mul for &'py PyComplex {
type Output = &'py PyComplex;
fn mul(self, other: &'py PyComplex) -> &'py PyComplex {
@@ -96,6 +101,7 @@ impl<'py> Mul for &'py PyComplex {
}
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
+#[cfg_attr(docsrs, doc(cfg(not(any(Py_LIMITED_API, PyPy)))))]
impl<'py> Div for &'py PyComplex {
type Output = &'py PyComplex;
fn div(self, other: &'py PyComplex) -> &'py PyComplex {
@@ -107,6 +113,7 @@ impl<'py> Div for &'py PyComplex {
}
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
+#[cfg_attr(docsrs, doc(cfg(not(any(Py_LIMITED_API, PyPy)))))]
impl<'py> Neg for &'py PyComplex {
type Output = &'py PyComplex;
fn neg(self) -> &'py PyComplex {
@@ -119,13 +126,14 @@ impl<'py> Neg for &'py PyComplex {
}
#[cfg(feature = "num-complex")]
+#[cfg_attr(docsrs, doc(cfg(feature = "num-complex")))]
mod complex_conversion {
use super::*;
use crate::{FromPyObject, PyErr, PyNativeType, PyObject, PyResult, ToPyObject};
use num_complex::Complex;
impl PyComplex {
- /// Creates a new Python `PyComplex` object from num_complex::Complex.
+ /// Creates a new Python `PyComplex` object from `num_complex`'s [`Complex`].
pub fn from_complex>(py: Python, complex: Complex) -> &PyComplex {
unsafe {
let ptr = ffi::PyComplex_FromDoubles(complex.re.into(), complex.im.into());
diff --git a/src/types/dict.rs b/src/types/dict.rs
index b8b4cbc0..49fad9c7 100644
--- a/src/types/dict.rs
+++ b/src/types/dict.rs
@@ -37,6 +37,7 @@ impl PyDict {
/// Returns an error on invalid input. In the case of key collisions,
/// this keeps the last entry seen.
#[cfg(not(PyPy))]
+ #[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn from_sequence(py: Python, seq: PyObject) -> PyResult<&PyDict> {
unsafe {
let dict = py.from_owned_ptr::(ffi::PyDict_New());
diff --git a/src/types/iterator.rs b/src/types/iterator.rs
index ab936f24..d24e82e8 100644
--- a/src/types/iterator.rs
+++ b/src/types/iterator.rs
@@ -69,6 +69,7 @@ impl<'p> Iterator for &'p PyIterator {
// PyIter_Check does not exist in the limited API until 3.8
#[cfg(any(not(Py_LIMITED_API), Py_3_8))]
+#[cfg_attr(docsrs, doc(cfg(any(not(Py_LIMITED_API), Py_3_8))))]
impl<'v> PyTryFrom<'v> for PyIterator {
fn try_from>(value: V) -> Result<&'v PyIterator, PyDowncastError<'v>> {
let value = value.into();
diff --git a/src/types/mod.rs b/src/types/mod.rs
index bcfe16f5..2f17878f 100644
--- a/src/types/mod.rs
+++ b/src/types/mod.rs
@@ -8,6 +8,7 @@ pub use self::bytearray::PyByteArray;
pub use self::bytes::PyBytes;
pub use self::complex::PyComplex;
#[cfg(not(Py_LIMITED_API))]
+#[cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
pub use self::datetime::{
PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime, PyTimeAccess, PyTzInfo,
};
@@ -225,6 +226,7 @@ mod bytearray;
mod bytes;
mod complex;
#[cfg(not(Py_LIMITED_API))]
+#[cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
mod datetime;
mod dict;
mod floatob;
diff --git a/src/types/module.rs b/src/types/module.rs
index 53a73e3c..3cc4e65d 100644
--- a/src/types/module.rs
+++ b/src/types/module.rs
@@ -112,6 +112,7 @@ impl PyModule {
///
/// May fail if the module does not have a `__file__` attribute.
#[cfg(not(all(windows, PyPy)))]
+ #[cfg_attr(docsrs, doc(cfg(not(all(windows, PyPy)))))]
pub fn filename(&self) -> PyResult<&str> {
use crate::types::PyString;
unsafe {
diff --git a/src/types/num.rs b/src/types/num.rs
index 7e944cdb..c1828dc5 100644
--- a/src/types/num.rs
+++ b/src/types/num.rs
@@ -357,6 +357,10 @@ mod test_128bit_intergers {
}
#[cfg(all(feature = "num-bigint", not(any(Py_LIMITED_API, PyPy))))]
+#[cfg_attr(
+ docsrs,
+ doc(cfg(all(feature = "num-bigint", not(any(Py_LIMITED_API, PyPy)))))
+)]
mod bigint_conversion {
use super::*;
use crate::{err, Py};
diff --git a/src/types/sequence.rs b/src/types/sequence.rs
index 6432c4a0..514c6b61 100644
--- a/src/types/sequence.rs
+++ b/src/types/sequence.rs
@@ -187,6 +187,7 @@ impl PySequence {
/// number of keys for which `self[key] == value`.
#[inline]
#[cfg(not(PyPy))]
+ #[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn count(&self, value: V) -> PyResult
where
V: ToBorrowedObject,
diff --git a/src/types/set.rs b/src/types/set.rs
index c724989f..dc524641 100644
--- a/src/types/set.rs
+++ b/src/types/set.rs
@@ -324,6 +324,7 @@ impl<'a> std::iter::IntoIterator for &'a PyFrozenSet {
}
#[cfg(feature = "hashbrown")]
+#[cfg_attr(docsrs, doc(cfg(feature = "hashbrown")))]
mod hashbrown_hashset_conversion {
use super::*;
use crate::{FromPyObject, PyObject, PyResult, ToPyObject};
diff --git a/src/types/tuple.rs b/src/types/tuple.rs
index d43144d6..ea12e8aa 100644
--- a/src/types/tuple.rs
+++ b/src/types/tuple.rs
@@ -78,9 +78,8 @@ impl PyTuple {
}
/// Returns `self` as a slice of objects.
- ///
- /// Not available when compiled with Py_LIMITED_API.
#[cfg(not(Py_LIMITED_API))]
+ #[cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
pub fn as_slice(&self) -> &[&PyAny] {
// This is safe because &PyAny has the same memory layout as *mut ffi::PyObject,
// and because tuples are immutable.