diff --git a/src/buffer.rs b/src/buffer.rs index 71cbbf25e38..7a22c47717d 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -55,16 +55,23 @@ impl Debug for PyBuffer { } } +/// Represents the type of a Python buffer element. #[derive(Copy, Clone, 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 boolean type. Bool, + /// A float type and its width in bytes. Float { bytes: usize }, + /// An unknown type. This may occur when parsing has failed. Unknown, } impl ElementType { + /// Determines the `ElementType` from a Python `struct` module format string. pub fn from_format(format: &CStr) -> ElementType { match format.to_bytes() { [char] | [b'@', char] => native_element_type_from_type_char(*char), @@ -590,7 +597,7 @@ impl Drop for PyBuffer { } } -/// Like `std::mem::cell`, but only provides read-only access to the data. +/// Like [std::cell::Cell], but only provides read-only access to the data. /// /// `&ReadOnlyCell` is basically a safe version of `*const T`: /// The data cannot be modified through the reference, but other references may @@ -599,11 +606,13 @@ impl Drop for PyBuffer { pub struct ReadOnlyCell(cell::UnsafeCell); impl ReadOnlyCell { + /// Returns a copy of the current value. #[inline] pub fn get(&self) -> T { unsafe { *self.0.get() } } + /// Returns a pointer to the current value. #[inline] pub fn as_ptr(&self) -> *const T { self.0.get() diff --git a/src/class/basic.rs b/src/class/basic.rs index a6e6027436c..affa7ee68ba 100644 --- a/src/class/basic.rs +++ b/src/class/basic.rs @@ -12,14 +12,20 @@ use crate::callback::{HashCallbackOutput, IntoPyCallbackOutput}; use crate::{exceptions, ffi, FromPyObject, PyAny, PyCell, PyClass, PyObject}; use std::os::raw::c_int; -/// Operators for the __richcmp__ method +/// Operators for the `__richcmp__` method #[derive(Debug)] pub enum CompareOp { + /// The *less than* operator. Lt = ffi::Py_LT as isize, + /// The *less than or equal to* operator. Le = ffi::Py_LE as isize, + /// The equality operator. Eq = ffi::Py_EQ as isize, + /// The *not equal to* operator. Ne = ffi::Py_NE as isize, + /// The *greater than* operator. Gt = ffi::Py_GT as isize, + /// The *greater than or equal to* operator. Ge = ffi::Py_GE as isize, } diff --git a/src/class/iter.rs b/src/class/iter.rs index 6e51a7f7507..3d7e699dd6c 100644 --- a/src/class/iter.rs +++ b/src/class/iter.rs @@ -78,7 +78,9 @@ py_unarys_func!(iternext, PyIterNextProtocol, Self::__next__); /// /// See [`PyIterProtocol`](trait.PyIterProtocol.html) for an example. pub enum IterNextOutput { + /// The value yielded by the iterator. Yield(T), + /// The `StopIteration` object. Return(U), } diff --git a/src/class/pyasync.rs b/src/class/pyasync.rs index 69143e70374..3361294913a 100644 --- a/src/class/pyasync.rs +++ b/src/class/pyasync.rs @@ -98,11 +98,16 @@ py_unarys_func!(aiter, PyAsyncAiterProtocol, Self::__aiter__); py_unarys_func!(anext, PyAsyncAnextProtocol, Self::__anext__); /// Output of `__anext__`. +/// +/// pub enum IterANextOutput { + /// An expression which the generator yielded. Yield(T), + /// A `StopAsyncIteration` object. Return(U), } +/// An [IterANextOutput] of Python objects. pub type PyIterANextOutput = IterANextOutput; impl IntoPyCallbackOutput<*mut ffi::PyObject> for PyIterANextOutput { diff --git a/src/exceptions.rs b/src/exceptions.rs index ff9986e0f01..6a9faf917ac 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -18,6 +18,7 @@ macro_rules! impl_exception_boilerplate { } impl $name { + /// Creates a new [PyErr](crate::PyErr) of this type. pub fn new_err(args: A) -> $crate::PyErr where A: $crate::PyErrArguments + Send + Sync + 'static, @@ -275,6 +276,7 @@ impl_native_exception!(PyIOError, PyExc_IOError); impl_native_exception!(PyWindowsError, PyExc_WindowsError); impl PyUnicodeDecodeError { + /// Creates a Python `UnicodeDecodeError`. pub fn new<'p>( py: Python<'p>, encoding: &CStr, @@ -294,6 +296,7 @@ impl PyUnicodeDecodeError { } } + /// Creates a Python `UnicodeDecodeError` from a Rust UTF-8 decoding error. pub fn new_utf8<'p>( py: Python<'p>, input: &[u8], diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 3045e56db56..77e4b2b453e 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -4,6 +4,10 @@ //! It is meant for advanced users only - regular PyO3 users shouldn't //! need to interact with this module at all. //! +//! The contents of this module are not documented here, as it would entail +//! basically copying the documentation from CPython. Consult the [Python/C API Reference +//! Manual][capi] for up-to-date documentation. +//! //! # Safety //! //! The functions in this module lack individual safety documentation, but @@ -12,9 +16,12 @@ //! although null pointers are sometimes valid input. //! - The vast majority can only be used safely while the GIL is held. //! - Some functions have additional safety requirements, consult the -//! [Python/C API Reference Manual](https://docs.python.org/3/c-api/index.html) +//! [Python/C API Reference Manual][capi] //! for more information. +//! +//! [capi]: https://docs.python.org/3/c-api/index.html #![allow( + missing_docs, non_camel_case_types, non_snake_case, non_upper_case_globals, diff --git a/src/impl_/freelist.rs b/src/impl_/freelist.rs index a8d926c3247..d5e3d1f8143 100644 --- a/src/impl_/freelist.rs +++ b/src/impl_/freelist.rs @@ -14,10 +14,15 @@ use std::mem; /// Represents a slot of a [`FreeList`]. pub enum Slot { + /// A free slot. Empty, + /// An allocated slot. Filled(T), } +/// A free allocation list. +/// +/// See [the parent module](crate::impl_::freelist) for more details. pub struct FreeList { entries: Vec>, split: usize, diff --git a/src/instance.rs b/src/instance.rs index acc3f0ef153..60386ae1458 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -18,6 +18,7 @@ use std::ptr::NonNull; /// to the GIL, which is why you can get a token from all references of those /// types. pub unsafe trait PyNativeType: Sized { + /// Returns a GIL marker constrained to the lifetime of this type. fn py(&self) -> Python { unsafe { Python::assume_gil_acquired() } } diff --git a/src/once_cell.rs b/src/once_cell.rs index 0aaee72c678..7ae138f6eaa 100644 --- a/src/once_cell.rs +++ b/src/once_cell.rs @@ -1,3 +1,4 @@ +//! A write-once cell mediated by the Python GIL. use crate::Python; use std::cell::UnsafeCell; diff --git a/src/panic.rs b/src/panic.rs index d140ac8304b..cf1dd3701e3 100644 --- a/src/panic.rs +++ b/src/panic.rs @@ -1,3 +1,4 @@ +//! Helper to convert Rust panics to Python exceptions. use crate::exceptions::PyBaseException; use crate::PyErr; use std::any::Any; diff --git a/src/pyclass_slots.rs b/src/pyclass_slots.rs index fd006a39038..89184d18fb7 100644 --- a/src/pyclass_slots.rs +++ b/src/pyclass_slots.rs @@ -4,8 +4,11 @@ use crate::{ffi, Python}; /// Represents `__dict__` field for `#[pyclass]`. pub trait PyClassDict { + /// Whether this `__dict__` field is capable of holding a dictionary. const IS_DUMMY: bool = true; + /// Initializes a [PyObject](crate::ffi::PyObject) `__dict__` reference. fn new() -> Self; + /// Empties the dictionary of its key-value pairs. #[inline] fn clear_dict(&mut self, _py: Python) {} private_decl! {} @@ -13,8 +16,12 @@ pub trait PyClassDict { /// Represents `__weakref__` field for `#[pyclass]`. pub trait PyClassWeakRef { + /// Whether this `weakref` type is capable of holding weak references. const IS_DUMMY: bool = true; + /// Initializes a `weakref` instance. fn new() -> Self; + /// Clears the weak references to the given object. + /// /// # Safety /// - `_obj` must be a pointer to the pyclass instance which contains `self`. /// - The GIL must be held. diff --git a/src/python.rs b/src/python.rs index 62d247744dc..0a319fb4142 100644 --- a/src/python.rs +++ b/src/python.rs @@ -16,9 +16,13 @@ use std::os::raw::{c_char, c_int}; /// See [Python::version]. #[derive(Debug)] pub struct PythonVersionInfo<'p> { + /// Python major version (e.g. `3`). pub major: u8, + /// Python minor version (e.g. `11`). pub minor: u8, + /// Python patch version (e.g. `0`). pub patch: u8, + /// Python version suffix, if applicable (e.g. `a0`). pub suffix: Option<&'p str>, } diff --git a/src/types/datetime.rs b/src/types/datetime.rs index 3e82104d27f..cad4b79d2a9 100644 --- a/src/types/datetime.rs +++ b/src/types/datetime.rs @@ -29,12 +29,24 @@ use std::os::raw::c_int; #[cfg(not(PyPy))] use std::ptr; -/// Access traits +// Access traits /// Trait for accessing the date components of a struct containing a date. pub trait PyDateAccess { + /// Returns the year, as a positive int. + /// + /// Implementations should conform to the upstream documentation: + /// fn get_year(&self) -> i32; + /// Returns the month, as an int from 1 through 12. + /// + /// Implementations should conform to the upstream documentation: + /// fn get_month(&self) -> u8; + /// Returns the day, as an int from 1 through 31. + /// + /// Implementations should conform to the upstream documentation: + /// fn get_day(&self) -> u8; } @@ -44,17 +56,51 @@ pub trait PyDateAccess { /// microsecond) representation of the delta, they are *not* intended as /// aliases for calculating the total duration in each of these units. pub trait PyDeltaAccess { + /// Returns the number of days, as an int from -999999999 to 999999999. + /// + /// Implementations should conform to the upstream documentation: + /// fn get_days(&self) -> i32; + /// Returns the number of seconds, as an int from 0 through 86399. + /// + /// Implementations should conform to the upstream documentation: + /// fn get_seconds(&self) -> i32; + /// Returns the number of microseconds, as an int from 0 through 999999. + /// + /// Implementations should conform to the upstream documentation: + /// fn get_microseconds(&self) -> i32; } /// Trait for accessing the time components of a struct containing a time. pub trait PyTimeAccess { + /// Returns the hour, as an int from 0 through 23. + /// + /// Implementations should conform to the upstream documentation: + /// fn get_hour(&self) -> u8; + /// Returns the minute, as an int from 0 through 59. + /// + /// Implementations should conform to the upstream documentation: + /// fn get_minute(&self) -> u8; + /// Returns the second, as an int from 0 through 59. + /// + /// Implementations should conform to the upstream documentation: + /// fn get_second(&self) -> u8; + /// Returns the microsecond, as an int from 0 through 999999. + /// + /// Implementations should conform to the upstream documentation: + /// fn get_microsecond(&self) -> u32; + /// Returns whether this date is the later of two moments with the + /// same representation, during a repeated interval. + /// + /// This typically occurs at the end of daylight savings time, or during + /// leap seconds. Only valid if the represented time is ambiguous. See + /// [PEP 495](https://www.python.org/dev/peps/pep-0495/) for more detail. #[cfg(not(PyPy))] fn get_fold(&self) -> bool; } @@ -71,6 +117,7 @@ pyobject_native_type!( ); impl PyDate { + /// Creates a new `datetime.date`. pub fn new(py: Python, year: i32, month: u8, day: u8) -> PyResult<&PyDate> { unsafe { let ptr = (PyDateTimeAPI.Date_FromDate)( @@ -273,6 +320,7 @@ pyobject_native_type!( ); impl PyTime { + /// Creates a new `datetime.time` object. pub fn new<'p>( py: Python<'p>, hour: u8, @@ -368,6 +416,7 @@ pyobject_native_type!( ); impl PyDelta { + /// Creates a new `timedelta`. pub fn new( py: Python, days: i32, diff --git a/src/types/sequence.rs b/src/types/sequence.rs index b225fa21a08..5d4c5e0716f 100644 --- a/src/types/sequence.rs +++ b/src/types/sequence.rs @@ -28,6 +28,7 @@ impl PySequence { } } + /// Returns whether the sequence is empty. #[inline] pub fn is_empty(&self) -> PyResult { self.len().map(|l| l == 0) diff --git a/src/types/string.rs b/src/types/string.rs index cc3de2346a6..44dd985ee95 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -27,6 +27,9 @@ impl PyString { unsafe { py.from_owned_ptr(ffi::PyUnicode_FromStringAndSize(ptr, len)) } } + /// Attempts to create a Python string from a Python [bytes-like object]. + /// + /// [bytes-like object]: (https://docs.python.org/3/glossary.html#term-bytes-like-object). pub fn from_object<'p>(src: &'p PyAny, encoding: &str, errors: &str) -> PyResult<&'p PyString> { unsafe { src.py()