Skip to content

Commit

Permalink
Merge pull request #2588 from davidhewitt/require-docs
Browse files Browse the repository at this point in the history
docs: require docs on all public APIs
  • Loading branch information
davidhewitt committed Sep 7, 2022
2 parents 7827393 + ab8f940 commit 58596ac
Show file tree
Hide file tree
Showing 18 changed files with 128 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .cargo/config
Expand Up @@ -18,4 +18,4 @@ rustflags = [
"-Delided_lifetimes_in_paths",
"-Dunused_lifetimes",
"-Drust_2021_prelude_collisions"
]
]
23 changes: 17 additions & 6 deletions src/buffer.rs
Expand Up @@ -58,14 +58,23 @@ impl<T> Debug for PyBuffer<T> {
/// Represents the type of a Python buffer element.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ElementType {
/// A signed integer type and its width in bytes.
SignedInteger { bytes: usize },
/// An unsigned integer type and its width in bytes.
UnsignedInteger { bytes: usize },
/// A signed integer type.
SignedInteger {
/// The width of the signed integer in bytes.
bytes: usize,
},
/// An unsigned integer type.
UnsignedInteger {
/// The width of the unsigned integer in bytes.
bytes: usize,
},
/// A boolean type.
Bool,
/// A float type and its width in bytes.
Float { bytes: usize },
/// A float type.
Float {
/// The width of the float in bytes.
bytes: usize,
},
/// An unknown type. This may occur when parsing has failed.
Unknown,
}
Expand Down Expand Up @@ -607,6 +616,8 @@ impl<T: Element> PyBuffer<T> {
}
}

/// Release the buffer object, freeing the reference to the Python object
/// which owns the buffer.
pub fn release(self, _py: Python<'_>) {
// First move self into a ManuallyDrop, so that PyBuffer::drop will
// never be called. (It would acquire the GIL and call PyBuffer_Release
Expand Down
2 changes: 2 additions & 0 deletions src/err/mod.rs
Expand Up @@ -53,6 +53,8 @@ pub struct PyDowncastError<'a> {
}

impl<'a> PyDowncastError<'a> {
/// Create a new `PyDowncastError` representing a failure to convert the object
/// `from` into the type named in `to`.
pub fn new(from: &'a PyAny, to: impl Into<Cow<'static, str>>) -> Self {
PyDowncastError {
from,
Expand Down
2 changes: 2 additions & 0 deletions src/impl_.rs
@@ -1,3 +1,5 @@
#![allow(missing_docs)]

//! Internals of PyO3 which are accessed by code expanded from PyO3's procedural macros.
//!
//! Usage of any of these APIs in downstream code is implicitly acknowledging that these
Expand Down
39 changes: 2 additions & 37 deletions src/impl_/pymethods.rs
@@ -1,8 +1,8 @@
use crate::internal_tricks::{extract_cstr_or_leak_cstring, NulByteInString};
use crate::{ffi, AsPyPointer, PyAny, PyObject, PyResult, Python};
use crate::{ffi, PyAny, PyObject, PyResult, PyTraverseError, Python};
use std::ffi::CStr;
use std::fmt;
use std::os::raw::{c_int, c_void};
use std::os::raw::c_int;

/// Python 3.8 and up - __ipow__ has modulo argument correctly populated.
#[cfg(Py_3_8)]
Expand Down Expand Up @@ -253,41 +253,6 @@ fn get_doc(doc: &'static str) -> Result<&'static CStr, NulByteInString> {
extract_cstr_or_leak_cstring(doc, "Document cannot contain NUL byte.")
}

#[repr(transparent)]
pub struct PyTraverseError(pub(crate) c_int);

/// Object visitor for GC.
#[derive(Clone)]
pub struct PyVisit<'p> {
pub(crate) visit: ffi::visitproc,
pub(crate) arg: *mut c_void,
/// VisitProc contains a Python instance to ensure that
/// 1) it is cannot be moved out of the traverse() call
/// 2) it cannot be sent to other threads
pub(crate) _py: Python<'p>,
}

impl<'p> PyVisit<'p> {
/// Visit `obj`.
pub fn call<T>(&self, obj: &T) -> Result<(), PyTraverseError>
where
T: AsPyPointer,
{
let r = unsafe { (self.visit)(obj.as_ptr(), self.arg) };
if r == 0 {
Ok(())
} else {
Err(PyTraverseError(r))
}
}

/// Creates the PyVisit from the arguments to tp_traverse
#[doc(hidden)]
pub unsafe fn from_raw(visit: ffi::visitproc, arg: *mut c_void, _py: Python<'p>) -> Self {
Self { visit, arg, _py }
}
}

/// Unwraps the result of __traverse__ for tp_traverse
#[doc(hidden)]
#[inline]
Expand Down
6 changes: 3 additions & 3 deletions src/inspect/mod.rs
@@ -1,4 +1,4 @@
/// Runtime inspection of objects exposed to Python.
///
/// Tracking issue: <https://github.com/PyO3/pyo3/issues/2454>.
//! Runtime inspection of objects exposed to Python.
//!
//! Tracking issue: <https://github.com/PyO3/pyo3/issues/2454>.
pub mod types;
2 changes: 2 additions & 0 deletions src/inspect/types.rs
@@ -1,3 +1,5 @@
//! Data types used to describe runtime Python types.

use std::borrow::Cow;
use std::fmt::{Display, Formatter};

Expand Down
39 changes: 37 additions & 2 deletions src/lib.rs
@@ -1,3 +1,4 @@
#![warn(missing_docs)]
#![cfg_attr(feature = "nightly", feature(auto_traits, negative_impls))]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
#![cfg_attr(
Expand Down Expand Up @@ -310,7 +311,13 @@ pub use crate::type_object::PyTypeInfo;
pub use crate::types::PyAny;
pub use crate::version::PythonVersionInfo;

// Old directory layout, to be rethought?
/// Old module which contained some implementation details of the `#[pyproto]` module.
///
/// Prefer using the same content from `pyo3::pyclass`, e.g. `use pyo3::pyclass::CompareOp` instead
/// of `use pyo3::class::basic::CompareOp`.
///
/// For compatibility reasons this has not yet been removed, however will be done so
/// once <https://github.com/rust-lang/rust/issues/30827> is resolved.
pub mod class {
#[doc(hidden)]
pub use crate::impl_::pymethods as methods;
Expand All @@ -322,20 +329,48 @@ pub mod class {
PyClassAttributeDef, PyGetterDef, PyMethodDef, PyMethodDefType, PyMethodType, PySetterDef,
};

/// Old module which contained some implementation details of the `#[pyproto]` module.
///
/// Prefer using the same content from `pyo3::pyclass`, e.g. `use pyo3::pyclass::CompareOp` instead
/// of `use pyo3::class::basic::CompareOp`.
///
/// For compatibility reasons this has not yet been removed, however will be done so
/// once <https://github.com/rust-lang/rust/issues/30827> is resolved.
pub mod basic {
pub use crate::pyclass::CompareOp;
}

/// Old module which contained some implementation details of the `#[pyproto]` module.
///
/// Prefer using the same content from `pyo3::pyclass`, e.g. `use pyo3::pyclass::IterANextOutput` instead
/// of `use pyo3::class::pyasync::IterANextOutput`.
///
/// For compatibility reasons this has not yet been removed, however will be done so
/// once <https://github.com/rust-lang/rust/issues/30827> is resolved.
pub mod pyasync {
pub use crate::pyclass::{IterANextOutput, PyIterANextOutput};
}

/// Old module which contained some implementation details of the `#[pyproto]` module.
///
/// Prefer using the same content from `pyo3::pyclass`, e.g. `use pyo3::pyclass::IterNextOutput` instead
/// of `use pyo3::class::pyasync::IterNextOutput`.
///
/// For compatibility reasons this has not yet been removed, however will be done so
/// once <https://github.com/rust-lang/rust/issues/30827> is resolved.
pub mod iter {
pub use crate::pyclass::{IterNextOutput, PyIterNextOutput};
}

/// Old module which contained some implementation details of the `#[pyproto]` module.
///
/// Prefer using the same content from `pyo3::pyclass`, e.g. `use pyo3::pyclass::PyTraverseError` instead
/// of `use pyo3::class::gc::PyTraverseError`.
///
/// For compatibility reasons this has not yet been removed, however will be done so
/// once <https://github.com/rust-lang/rust/issues/30827> is resolved.
pub mod gc {
pub use crate::impl_::pymethods::{PyTraverseError, PyVisit};
pub use crate::pyclass::{PyTraverseError, PyVisit};
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/once_cell.rs
Expand Up @@ -161,10 +161,12 @@ macro_rules! intern {
pub struct Interned(&'static str, GILOnceCell<Py<PyString>>);

impl Interned {
/// Creates an empty holder for an interned `str`.
pub const fn new(value: &'static str) -> Self {
Interned(value, GILOnceCell::new())
}

/// Gets or creates the interned `str` value.
#[inline]
pub fn get<'py>(&'py self, py: Python<'py>) -> &'py PyString {
self.1
Expand Down
1 change: 1 addition & 0 deletions src/pycell/impl_.rs
@@ -1,3 +1,4 @@
#![allow(missing_docs)]
//! Crate-private implementation of pycell

use std::cell::Cell;
Expand Down
5 changes: 5 additions & 0 deletions src/pyclass.rs
Expand Up @@ -18,6 +18,10 @@ use std::{
ptr,
};

mod gc;

pub use self::gc::{PyTraverseError, PyVisit};

/// Types that can be used as Python classes.
///
/// The `#[pyclass]` attribute implements this trait for your Rust struct -
Expand Down Expand Up @@ -502,6 +506,7 @@ pub enum IterNextOutput<T, U> {
Return(U),
}

/// Alias of `IterNextOutput` with `PyObject` yield & return values.
pub type PyIterNextOutput = IterNextOutput<PyObject, PyObject>;

impl IntoPyCallbackOutput<*mut ffi::PyObject> for PyIterNextOutput {
Expand Down
39 changes: 39 additions & 0 deletions src/pyclass/gc.rs
@@ -0,0 +1,39 @@
use std::os::raw::{c_int, c_void};

use crate::{ffi, AsPyPointer, Python};

/// Error returned by a `__traverse__` visitor implementation.
#[repr(transparent)]
pub struct PyTraverseError(pub(crate) c_int);

/// Object visitor for GC.
#[derive(Clone)]
pub struct PyVisit<'p> {
pub(crate) visit: ffi::visitproc,
pub(crate) arg: *mut c_void,
/// VisitProc contains a Python instance to ensure that
/// 1) it is cannot be moved out of the traverse() call
/// 2) it cannot be sent to other threads
pub(crate) _py: Python<'p>,
}

impl<'p> PyVisit<'p> {
/// Visit `obj`.
pub fn call<T>(&self, obj: &T) -> Result<(), PyTraverseError>
where
T: AsPyPointer,
{
let r = unsafe { (self.visit)(obj.as_ptr(), self.arg) };
if r == 0 {
Ok(())
} else {
Err(PyTraverseError(r))
}
}

/// Creates the PyVisit from the arguments to tp_traverse
#[doc(hidden)]
pub unsafe fn from_raw(visit: ffi::visitproc, arg: *mut c_void, _py: Python<'p>) -> Self {
Self { visit, arg, _py }
}
}
2 changes: 2 additions & 0 deletions src/type_object.rs
Expand Up @@ -96,6 +96,7 @@ pub struct LazyStaticType {
}

impl LazyStaticType {
/// Creates an uninitialized `LazyStaticType`.
pub const fn new() -> Self {
LazyStaticType {
value: GILOnceCell::new(),
Expand All @@ -104,6 +105,7 @@ impl LazyStaticType {
}
}

/// Gets the type object contained by this `LazyStaticType`, initializing it if needed.
pub fn get_or_init<T: PyClass>(&self, py: Python<'_>) -> *mut ffi::PyTypeObject {
fn inner<T: PyClass>() -> *mut ffi::PyTypeObject {
// Safety: `py` is held by the caller of `get_or_init`.
Expand Down
1 change: 1 addition & 0 deletions src/types/datetime.rs
Expand Up @@ -234,6 +234,7 @@ pyobject_native_type!(
);

impl PyDateTime {
/// Creates a new `datetime.datetime` object.
#[allow(clippy::too_many_arguments)]
pub fn new<'p>(
py: Python<'p>,
Expand Down
1 change: 1 addition & 0 deletions src/types/dict.rs
Expand Up @@ -262,6 +262,7 @@ impl PyDict {
}
}

/// PyO3 implementation of an iterator for a Python `dict` object.
pub struct PyDictIterator<'py> {
dict: &'py PyDict,
ppos: ffi::Py_ssize_t,
Expand Down
2 changes: 2 additions & 0 deletions src/types/frozenset.rs
Expand Up @@ -89,6 +89,7 @@ mod impl_ {
}
}

/// PyO3 implementation of an iterator for a Python `frozenset` object.
pub struct PyFrozenSetIterator<'p> {
it: &'p PyIterator,
}
Expand Down Expand Up @@ -116,6 +117,7 @@ mod impl_ {
}
}

/// PyO3 implementation of an iterator for a Python `frozenset` object.
pub struct PyFrozenSetIterator<'py> {
set: &'py PyAny,
pos: ffi::Py_ssize_t,
Expand Down
3 changes: 3 additions & 0 deletions src/types/set.rs
Expand Up @@ -143,6 +143,7 @@ mod impl_ {
}
}

/// PyO3 implementation of an iterator for a Python `set` object.
pub struct PySetIterator<'p> {
it: &'p PyIterator,
}
Expand All @@ -165,6 +166,8 @@ mod impl_ {
#[cfg(not(Py_LIMITED_API))]
mod impl_ {
use super::*;

/// PyO3 implementation of an iterator for a Python `set` object.
pub struct PySetIterator<'py> {
set: &'py super::PyAny,
pos: ffi::Py_ssize_t,
Expand Down
7 changes: 6 additions & 1 deletion src/types/slice.rs
Expand Up @@ -18,16 +18,21 @@ pyobject_native_type!(
#checkfunction=ffi::PySlice_Check
);

/// Represents Python `slice` indices.
/// Return value from [`PySlice::indices`].
#[derive(Debug, Eq, PartialEq)]
pub struct PySliceIndices {
/// Start of the slice
pub start: isize,
/// End of the slice
pub stop: isize,
/// Increment to use when iterating the slice from `start` to `stop`.
pub step: isize,
/// The length of the slice calculated from the original input sequence.
pub slicelength: isize,
}

impl PySliceIndices {
/// Creates a new `PySliceIndices`.
pub fn new(start: isize, stop: isize, step: isize) -> PySliceIndices {
PySliceIndices {
start,
Expand Down

0 comments on commit 58596ac

Please sign in to comment.