-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Add add_deprecation_to_docstring
for docsite deprecation support
#9685
Merged
mergify
merged 23 commits into
Qiskit:main
from
Eric-Arellano:deprecation-via-docstring
Mar 13, 2023
Merged
Changes from 19 commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
e8bd369
Add deprecations to function docstring
Eric-Arellano 2679c84
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into de…
Eric-Arellano f5a49e4
Work around issue with multiline strings
Eric-Arellano 5eab996
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into de…
Eric-Arellano 300903e
Merge branch 'main' into deprecation-via-docstring
Eric-Arellano 581e206
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into de…
Eric-Arellano 803492d
Better variable name
Eric-Arellano 36b759e
Merge branch 'deprecation-via-docstring' of https://github.com/Eric-A…
Eric-Arellano 4fff65d
Jake's review feedback
Eric-Arellano a005a9d
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into de…
Eric-Arellano d399caa
Make Napoleon check case-insensitive
Eric-Arellano f733a6f
Promote add_deprecation_to_docstring to be public
Eric-Arellano d96714a
Properly error when metadata line is the first line
Eric-Arellano aa93cca
Tests feedback: don't use helper function and simplify instructions t…
Eric-Arellano d5f92cf
Merge branch 'main' into deprecation-via-docstring
Eric-Arellano c425e30
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into de…
Eric-Arellano 285021f
Don't use the function with @deprecate_function and @deprecate_argume…
Eric-Arellano 6541f9d
Update qiskit/utils/deprecation.py
Eric-Arellano bf28d6b
Merge branch 'main' into deprecation-via-docstring
Eric-Arellano 54e1ebc
Update qiskit/utils/deprecation.py
Eric-Arellano fef76a6
Merge branch 'main' of https://github.com/Qiskit/qiskit-terra into de…
Eric-Arellano 7e21cc5
Add release note
Eric-Arellano 117f64e
Merge branch 'deprecation-via-docstring' of https://github.com/Eric-A…
Eric-Arellano File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,11 +14,11 @@ | |
|
||
import functools | ||
import warnings | ||
from typing import Any, Dict, Optional, Type | ||
from typing import Any, Callable, Dict, Optional, Type | ||
|
||
|
||
def deprecate_arguments( | ||
kwarg_map: Dict[str, str], | ||
kwarg_map: Dict[str, Optional[str]], | ||
category: Type[Warning] = DeprecationWarning, | ||
*, | ||
since: Optional[str] = None, | ||
|
@@ -113,3 +113,117 @@ def _rename_kwargs( | |
) | ||
|
||
kwargs[new_arg] = kwargs.pop(old_arg) | ||
|
||
|
||
# We insert deprecations in-between the description and Napoleon's meta sections. The below is from | ||
# https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html#docstring-sections. We use | ||
# lowercase because Napoleon is case-insensitive. | ||
_NAPOLEON_META_LINES = frozenset( | ||
{ | ||
"args:", | ||
"arguments:", | ||
"attention:", | ||
"attributes:", | ||
"caution:", | ||
"danger:", | ||
"error:", | ||
"example:", | ||
"examples:", | ||
"hint:", | ||
"important:", | ||
"keyword args:", | ||
"keyword arguments:", | ||
"note:", | ||
"notes:", | ||
"other parameters:", | ||
"parameters:", | ||
"return:", | ||
"returns:", | ||
"raises:", | ||
"references:", | ||
"see also:", | ||
"tip:", | ||
"todo:", | ||
"warning:", | ||
"warnings:", | ||
"warn:", | ||
"warns:", | ||
"yield:", | ||
"yields:", | ||
} | ||
) | ||
|
||
|
||
def add_deprecation_to_docstring( | ||
func: Callable, msg: str, *, since: Optional[str], pending: bool | ||
) -> None: | ||
"""Dynamically insert the deprecation message into ``func``'s docstring. | ||
|
||
Args: | ||
func: The function to modify. | ||
msg: The full deprecation message. | ||
since: The version the deprecation started at. | ||
pending: Is the deprecation still pending? | ||
""" | ||
if "\n" in msg: | ||
raise ValueError( | ||
"Deprecation messages cannot contain new lines (`\\n`), but the deprecation for " | ||
f'{func.__qualname__} had them. Usually this happens when using `"""` multiline ' | ||
f"strings; instead, use string concatenation.\n\n" | ||
"This is a simplification to facilitate deprecation messages being added to the " | ||
"documentation. If you have a compelling reason to need " | ||
"new lines, feel free to improve this function or open a request at " | ||
"https://github.com/Qiskit/qiskit-terra/issues." | ||
) | ||
Comment on lines
+169
to
+177
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels a bit hypocritical to complain that the developer uses a newline in their warning message when we do the exact same thing in this error message ;). edit: not saying we need to change this. The situations are different. |
||
|
||
if since is None: | ||
version_str = "unknown" | ||
else: | ||
version_str = f"{since}_pending" if pending else since | ||
jakelishman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
indent = "" | ||
meta_index = None | ||
if func.__doc__: | ||
original_lines = func.__doc__.splitlines() | ||
content_encountered = False | ||
for i, line in enumerate(original_lines): | ||
stripped = line.strip() | ||
|
||
# Determine the indent based on the first line with content. But, we don't consider the | ||
# first line, which corresponds to the format """Docstring.""", as it does not properly | ||
# capture the indentation of lines beneath it. | ||
if not content_encountered and i != 0 and stripped: | ||
num_leading_spaces = len(line) - len(line.lstrip()) | ||
indent = " " * num_leading_spaces | ||
content_encountered = True | ||
|
||
if stripped.lower() in _NAPOLEON_META_LINES: | ||
meta_index = i | ||
if content_encountered is not True: | ||
Eric-Arellano marked this conversation as resolved.
Show resolved
Hide resolved
|
||
raise ValueError( | ||
"add_deprecation_to_docstring cannot currently handle when a Napoleon " | ||
"metadata line like 'Args' is the very first line of docstring, " | ||
f'e.g. `"""Args:`. So, it cannot process {func.__qualname__}. Instead, ' | ||
f'move the metadata line to the second line, e.g.:\n\n"""\nArgs:' | ||
) | ||
# We can stop checking since we only care about the first meta line, and | ||
# we've validated content_encountered is True to determine the indent. | ||
break | ||
else: | ||
original_lines = [] | ||
|
||
# We defensively include new lines in the beginning and end. This is sometimes necessary, | ||
# depending on the original docstring. It is not a big deal to have extra, other than `help()` | ||
# being a little longer. | ||
new_lines = [ | ||
indent, | ||
jakelishman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
f"{indent}.. deprecated:: {version_str}", | ||
f"{indent} {msg}", | ||
Eric-Arellano marked this conversation as resolved.
Show resolved
Hide resolved
|
||
indent, | ||
] | ||
|
||
if meta_index: | ||
original_lines[meta_index - 1 : meta_index - 1] = new_lines | ||
else: | ||
original_lines.extend(new_lines) | ||
func.__doc__ = "\n".join(original_lines) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the point of the
*
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It requires you to use keyword arguments for everything after the star. The reasons for that:
True
orFalse
with no context. IDEs make this less painful by showing what argument names are, but there are many contexts you read code w/o that, like GitHub or Vim.