If I have a Python module and a method:
# mymod.py
def func(x):
"""
Return a value.
"""
return x
And a Sphinx autodocument command in an rst file:
API Ref
-------
.. automodapi:: project.mymod
This will generate relevant pages and cross-referencable links for :meth:'project.mymod.func'. All is well and good!
However, If I now create a Rust extension for my Python package and move this function to Rust and build the extension with PyO3 I can maintain code backwards compatibility by importing the rust function to the Python module as an overload:
// mymod.rs
#[pymethod]
fn func(x: T) -> PyResult<T> {
Ok(x)
}
# mymod.py
from mymodrs import func
Sphinx will now no longer auto detect this func method, with no cross-referencable link. Can I add something to maintain the Sphinx operability? I don't mind if it is manual.
One way I have found so far of getting this to work with almost the same formatting and section consistency is to do something like:
Current Version
# mymod.py
def func(x):
"""
Return a value
Parameters
----------
x: float
The value
Returns
-------
float
"""
return x
# index.rst
Methods
-------
.. automodapi:: project.mymod
New Rust Version
# mymod.py
from mymodrs import func
func.__doc__ = "Return a value" # Needed for the description in autosummary
Create an explicit documentation file for the Rust method.
# api_manual/mymod.func.rst
func
----
.. currentmodule:: mymod
.. py:method:: func(x)
Return a value
:param x: The value
:param type: float
:rtype: float
Link to it in the original automod file.
# index.rst
Methods
-------
.. autosummary::
mymod.func
.. toctree::
:titlesonly:
:maxdepth: 0
:hidden:
api_manual/mymod.func.rst
You can document your method in rust, as described in the pyo3 guide and the help (and, optionally, a customized signature) of the function are available to autodoc like any other Python function.
use pyo3::prelude::*;
/// This function adds two unsigned 64-bit integers.
#[pyfunction]
fn add(a: u64, b: u64) -> u64 {
a + b
}
Then you can document it with autodoc like normal:
.. autofunction:: mymodule.add

You can use whatever docstring format you want, too and it'll render the same as if written in a Python docstring. For example, using sphinx-style docstrings:
/// This function adds two numbers
///
/// :param a: the first operand, an integer
/// :param b: the second operand, an integer
/// :return: the sum of the two operands
#[pyfunction]
fn add(a: u64, b: u64) -> u64 {
a + b
}
When documented with autodoc, works just like in Python:

By default automodule will not document imported members, including those you import from extension modules. But adding .. autofunction:: will work or you can use the imported-members directive.
.. automodule:: mypythonmodule
:members:
:imported-members: add
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With