-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
[WIP] PR: formatting of generated docstrings according to style-guides #24041
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
Examples of generated docstrings for the various styles with master and with this PR. Numpy stylemaster"""
Example file for numpydoc linting.
"""
def func_no_return_no_arg():
"""
Returns
-------
None.
"""
print("no args or returns")
def func_no_return_with_arg(x):
"""
Parameters
----------
x : TYPE
DESCRIPTION.
Returns
-------
None.
"""
print("x")
def func_with_return_no_arg():
"""
Returns
-------
bool
DESCRIPTION.
"""
return True
def func_with_return_args(x, y):
"""
Parameters
----------
x : TYPE
DESCRIPTION.
y : TYPE
DESCRIPTION.
Returns
-------
x : TYPE
DESCRIPTION.
"""
return x
def func_with_multiplte_return_vals(x, y):
"""
Parameters
----------
x : TYPE
DESCRIPTION.
y : TYPE
DESCRIPTION.
Returns
-------
x : TYPE
DESCRIPTION.
y : TYPE
DESCRIPTION.
"""
return x, y
def func_with_multiple_return_vals_type_ann(
x: int, y: float, z: float = None
) -> tuple[float, float]:
"""
Parameters
----------
x : int
DESCRIPTION.
y : float
DESCRIPTION.
z : float, optional
DESCRIPTION. The default is None.
Returns
-------
tuple[float, float]
DESCRIPTION.
"""
return x, y
def func_raise_type_ann(x: int, y: float, z: float = None) -> float:
"""
Parameters
----------
x : int
DESCRIPTION.
y : float
DESCRIPTION.
z : float, optional
DESCRIPTION. The default is None.
Raises
------
ValueError
DESCRIPTION.
Returns
-------
float
DESCRIPTION.
"""
try:
return x / y
except ZeroDivisionError as exc:
raise ValueError(":( y cannot be zero") from exc
Output of numpydoc lint with masterthis PR"""
Example file for numpydoc linting.
"""
def func_no_return_no_arg():
"""
SUMMARY.
"""
print("no args or returns")
def func_no_return_with_arg(x):
"""
SUMMARY.
Parameters
----------
x : TYPE
DESCRIPTION.
"""
print("x")
def func_with_return_no_arg():
"""
SUMMARY.
Returns
-------
bool
DESCRIPTION.
"""
return True
def func_with_return_args(x, y):
"""
SUMMARY.
Parameters
----------
x : TYPE
DESCRIPTION.
y : TYPE
DESCRIPTION.
Returns
-------
TYPE
DESCRIPTION.
"""
return x
def func_with_multiplte_return_vals(x, y):
"""
SUMMARY.
Parameters
----------
x : TYPE
DESCRIPTION.
y : TYPE
DESCRIPTION.
Returns
-------
x : TYPE
DESCRIPTION.
y : TYPE
DESCRIPTION.
"""
return x, y
def func_with_multiple_return_vals_type_ann(
x: int, y: float, z: float = None
) -> tuple[float, float]:
"""
SUMMARY.
Parameters
----------
x : int
DESCRIPTION.
y : float
DESCRIPTION.
z : float, optional
DESCRIPTION. The default is None.
Returns
-------
tuple[float, float]
DESCRIPTION.
"""
return x, y
def func_raise_type_ann(x: int, y: float, z: float = None) -> float:
"""
SUMMARY.
Parameters
----------
x : int
DESCRIPTION.
y : float
DESCRIPTION.
z : float, optional
DESCRIPTION. The default is None.
Returns
-------
float
DESCRIPTION.
Raises
------
ValueError
DESCRIPTION.
"""
try:
return x / y
except ZeroDivisionError as exc:
raise ValueError(":( y cannot be zero") from excThis passes numpydoc linting with Google stylemasterdef func_no_return_no_arg():
"""
Returns:
None.
"""
print("no args or returns")
def func_no_return_with_arg(x):
"""
Args:
x (TYPE): DESCRIPTION.
Returns:
None.
"""
print("x")
def func_with_return_no_arg():
"""
Returns:
bool: DESCRIPTION.
"""
return True
def func_with_return_args(x, y):
"""
Args:
x (TYPE): DESCRIPTION.
y (TYPE): DESCRIPTION.
Returns:
TYPE: DESCRIPTION.
"""
return x + y
def func_with_multiplte_return_vals(x, y):
"""
Args:
x (TYPE): DESCRIPTION.
y (TYPE): DESCRIPTION.
Returns:
x (TYPE): DESCRIPTION.
y (TYPE): DESCRIPTION.
"""
return x, y
def func_with_multiple_return_vals_type_ann(
x: int, y: float, z: float = None
) -> tuple[float, float]:
"""
Args:
x (int): DESCRIPTION.
y (float): DESCRIPTION.
z (float, optional): DESCRIPTION. Defaults to None.
Returns:
tuple[float, float]: DESCRIPTION.
"""
return x, y
def func_raise_type_ann(x: int, y: float, z: float = None) -> float:
"""
Args:
x (int): DESCRIPTION.
y (float): DESCRIPTION.
z (float, optional): DESCRIPTION. Defaults to None.
Raises:
ValueError: DESCRIPTION.
Returns:
float: DESCRIPTION.
"""
try:
return x / y
except ZeroDivisionError as exc:
raise ValueError(":( y cannot be zero") from excthis PRdef func_no_return_no_arg():
"""SUMMARY.
"""
print("no args or returns")
def func_no_return_with_arg(x):
"""SUMMARY.
Args:
x (TYPE): DESCRIPTION.
"""
print("x")
def func_with_return_no_arg():
"""SUMMARY.
Returns:
bool: DESCRIPTION.
"""
return True
def func_with_return_args(x, y):
"""SUMMARY.
Args:
x (TYPE): DESCRIPTION.
y (TYPE): DESCRIPTION.
Returns:
TYPE: DESCRIPTION.
"""
return x + y
def func_with_multiplte_return_vals(x, y):
"""SUMMARY.
Args:
x (TYPE): DESCRIPTION.
y (TYPE): DESCRIPTION.
Returns:
x (TYPE): DESCRIPTION.
y (TYPE): DESCRIPTION.
"""
return x, y
def func_with_multiple_return_vals_type_ann(
x: int, y: float, z: float = None
) -> tuple[float, float]:
"""SUMMARY.
Args:
x (int): DESCRIPTION.
y (float): DESCRIPTION.
z (float, optional): DESCRIPTION. Defaults to None.
Returns:
tuple[float, float]: DESCRIPTION.
"""
return x, y
def func_raise_type_ann(x: int, y: float, z: float = None) -> float:
"""SUMMARY.
Args:
x (int): DESCRIPTION.
y (float): DESCRIPTION.
z (float, optional): DESCRIPTION. Defaults to None.
Returns:
float: DESCRIPTION.
Raises:
ValueError: DESCRIPTION.
"""
try:
return x / y
except ZeroDivisionError as exc:
raise ValueError(":( y cannot be zero") from excSphinx stylemasterdef func_no_return_no_arg():
"""
:return: DESCRIPTION
:rtype: TYPE
"""
print("no args or returns")
def func_no_return_with_arg(x):
"""
:param x: DESCRIPTION
:type x: TYPE
:return: DESCRIPTION
:rtype: TYPE
"""
print("x")
def func_with_return_no_arg():
"""
:return: DESCRIPTION
:rtype: TYPE
"""
return True
def func_with_return_args(x, y):
"""
:param x: DESCRIPTION
:type x: TYPE
:param y: DESCRIPTION
:type y: TYPE
:return: DESCRIPTION
:rtype: TYPE
"""
return x + y
def func_with_multiplte_return_vals(x, y):
"""
:param x: DESCRIPTION
:type x: TYPE
:param y: DESCRIPTION
:type y: TYPE
:return: DESCRIPTION
:rtype: TYPE
"""
return x, y
def func_with_multiple_return_vals_type_ann(
x: int, y: float, z: float = None
) -> tuple[float, float]:
"""
:param x: DESCRIPTION
:type x: int
:param y: DESCRIPTION
:type y: float
:param z: DESCRIPTION, defaults to None
:type z: float, optional
:return: DESCRIPTION
:rtype: tuple[float, float]
"""
return x, y
def func_raise_type_ann(x: int, y: float, z: float = None) -> float:
"""
:param x: DESCRIPTION
:type x: int
:param y: DESCRIPTION
:type y: float
:param z: DESCRIPTION, defaults to None
:type z: float, optional
:raises ValueError: DESCRIPTION
:return: DESCRIPTION
:rtype: float
"""
try:
return x / y
except ZeroDivisionError as exc:
raise ValueError(":( y cannot be zero") from exc
this PRdef func_no_return_no_arg():
"""SUMMARY.
"""
print("no args or returns")
def func_no_return_with_arg(x):
"""SUMMARY.
:param x: DESCRIPTION
:type x: TYPE
"""
print("x")
def func_with_return_no_arg():
"""SUMMARY.
:return: DESCRIPTION
:rtype: TYPE
"""
return True
def func_with_return_args(x, y):
"""SUMMARY.
:param x: DESCRIPTION
:type x: TYPE
:param y: DESCRIPTION
:type y: TYPE
:return: DESCRIPTION
:rtype: TYPE
"""
return x + y
def func_with_multiplte_return_vals(x, y):
"""SUMMARY.
:param x: DESCRIPTION
:type x: TYPE
:param y: DESCRIPTION
:type y: TYPE
:return: DESCRIPTION
:rtype: TYPE
"""
return x, y
def func_with_multiple_return_vals_type_ann(
x: int, y: float, z: float = None
) -> tuple[float, float]:
"""SUMMARY.
:param x: DESCRIPTION
:type x: int
:param y: DESCRIPTION
:type y: float
:param z: DESCRIPTION, defaults to None
:type z: float, optional
:return: DESCRIPTION
:rtype: tuple[float, float]
"""
return x, y
def func_raise_type_ann(x: int, y: float, z: float = None) -> float:
"""SUMMARY.
:param x: DESCRIPTION
:type x: int
:param y: DESCRIPTION
:type y: float
:param z: DESCRIPTION, defaults to None
:type z: float, optional
:raises ValueError: DESCRIPTION
:return: DESCRIPTION
:rtype: float
"""
try:
return x / y
except ZeroDivisionError as exc:
raise ValueError(":( y cannot be zero") from exc |
|
@ccordoba12 I understand fully this is not a prioritized issue ahead of 6.1 - just checking if there is an interest in including the PR some time in the future - if so then I can fix the tests when I have a free moment |
|
Hey @rhkarls , thanks for all your work here and sorry no one responded to you until now! These are pretty much all good improvements, a number of which had really annoyed me too (which I only have myself to blame for, haha, as I co-developed and reviewed this functionality with a contributor many years ago) and was starting to work on finally fixing them myself before I found this PR. In particular, I was using Spyder's docstring generation to expand Spyder's own docstrings (see e.g. #25512 for one example) , but was wasting loads of time manually fixing loads of style issues (many fixed here), dealing with lots of bugs and edge cases (e.g. it wouldn't work for Black-format docstrings) and having to manually integrate the existing docstrings with the new generated ones. As such, to speed up that work I was starting to make some changes in Spyder myself when I came across this PR, so it seemed prudent to rebase this on top of the latest See #25558 for the result, which incorporates your main commit verbatim (though not quite the return None change as you have it; see there for more details but that could be added in a followup PR as an optional setting). I hope you don't mind; since I didn't want to invalidate your existing PR but we needed this for Spyder's own docstrings. Thanks again for your work here and you are more than welcome to review and test that PR; happy to hear any feedback! |
|
Thanks for the ping @CAM-Gerlach, I appreciate it! And #25558 looks great, and I can see that a much more extensive overhaul is the way to go - looking forward to seeing that PR merged, its a really great feature of Spyder! |
Description of Changes
The aim of this PR is to make the auto-generated docstrings pass numpydoc linting. Some changes also included for the Google and Sphinx docstring style. See #24040
Specifically, this PR:
How to deal with None return values is a bit unclear.
Currently, this PR has removed the return section if it only returns None.
Google style-guide: "If the function only returns None, this section is not required."
Numpydoc: not mentioned, but convention appears to be to omit the section: https://stackoverflow.com/a/66176351
Sphinx: unclear
An alternative, in the case of numpy, would be to produce something like this to pass numpydoc linting.
Or keep the current behavior on master.
Once the changes to be included in this PR are agreed on I will deal with the tests.
Links and references:
Google docstring style: https://google.github.io/styleguide/pyguide.html#383-functions-and-methods
Sphinx docstring style: https://sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html#the-sphinx-docstring-format ,
Numpydoc: https://numpydoc.readthedocs.io/en/latest/format.html#sections
Additional note:
There are some inconsistencies in how the return section is generated, at least for numpy style, with multiple return values and depending on if the return value is type annotated or not.
These are however still valid docstrings as far as I can tell, so I consider this outside the scope of this PR.
Issue(s) Resolved
Fixes #24040 and #22043
Affirmation
By submitting this Pull Request or typing my (user)name below,
I affirm the Developer Certificate of Origin
with respect to all commits and content included in this PR,
and understand I am releasing the same under Spyder's MIT (Expat) license.
I certify the above statement is true and correct: @rhkarls