-
-
Notifications
You must be signed in to change notification settings - Fork 169
Description
In section https://numpydoc.readthedocs.io/en/latest/format.html#parameters (also applies to Returns, ...) the style guide defines that types should be added to each parameter description.
Nowadays, having a well designed Python typing system, documenting parameter types in docstrings is not only outdated, but will also cause code and documentation to diverge from the key principle of Single-Source-of-Truth.
F.i. the following method:
def my_shiny_method(num_a: float, count: int) -> list[float]:
"""
Create list containing some dummy numbers.
Parameters
----------
num_a
Base number to use for filling list.
count
Target list length.
Returns
-------
List filled of length `count` with floats.
"""
return [num_a / count for i in range(count)]is fully defined, documented and typed, using the typing syntax as the Single-Source-of-Truth.
Requiring type definitions in the docstrings, f.i.
"""
Create list containing some dummy numbers.
Parameters
----------
num_a : float
Base number to use for filling list.
count : int
Target list length.
Returns
-------
list[float]
List filled of length `count` with floats.
"""
is not only superfluous, but also - in my experience - dangerous, because methods etc. tend to be updated over time. And method interfaces may change. In my experience, method interfaces - even in productive code - change more often than desired. And most developers - especially in productive environments - are pushed for time and thus tend to forget to change the irrelevant part - the duplicate types in the docstrings - resulting in something like the following:
def my_shiny_method(num_a: int, count: int) -> list[float]:
"""
Create list containing some dummy numbers.
Parameters
----------
num_a : float
Base number to use for filling list.
count : int
Target list length.
Returns
-------
list[float]
List filled of length `count` with floats.
"""
return tuple(num_a / count for i in range(count))--> Now we have diverging typing information
--> Most users will look at the help(method) to see what a method expects. This is, depending on the user's preference, misleading.
This becomes even more problematic when we look at stuff like Literals, which - in modern Python, should be typed
def foo(order: Literal["C", "F", "A"]) -> None: ...whereas the style guide recommends something using a completely different syntax (set != Literal --> faulty):
order : {'C', 'F', 'A'}
Description of `order`.
Proposal
- Recommend to only use the Python typing system
- If there is a specific requirement of needing types in docstrings, the type syntax should be aligned with the core Python library
Advantages
- Single-Source-of-Truth!!!
- No risk of diverging type descriptions
- All type definitions may easily be checked by mypy or alike
- All type definitions may be style checked and reformatted by tools like ruff, black, ... Thus type information is less prone to syntax errors like
param: typeinstead ofparam : type - types from namespaces are resolved correctly
- One and only one typing syntax
- Doc generators like sphinx nowadays focus on Python typing anyways: no more ambiguous option handling
- less typing
- cleaner and simpler docstrings
Challenge
How to format Returns and Yields sections?