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.