aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorGravatar ChrisJL <[email protected]>2022-10-25 21:29:47 +0100
committerGravatar GitHub <[email protected]>2022-10-25 21:29:47 +0100
commitc7a6ddd00eb371759d837aa75fa397c6d5771401 (patch)
tree54902b389c4c79b9426b7ed20b2f7c3c522b5eeb /docs
parentMerge pull request #138 from python-discord/bump-d.py (diff)
parentbump sphinx and sphinx-autodoc-typehints (diff)
Merge pull request #88 from Numerlor/no-duplicate-deco
Diffstat (limited to 'docs')
-rw-r--r--docs/utils.py49
1 files changed, 35 insertions, 14 deletions
diff --git a/docs/utils.py b/docs/utils.py
index cb4ffd50..c8bbc895 100644
--- a/docs/utils.py
+++ b/docs/utils.py
@@ -72,21 +72,11 @@ def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> typin
while isinstance(source.body[0], ast.ClassDef):
source = source.body[0]
- for ast_obj in source.body:
- if isinstance(ast_obj, ast.Assign):
- names = []
- for target in ast_obj.targets:
- if isinstance(target, ast.Tuple):
- names.extend([name.id for name in target.elts])
- else:
- names.append(target.id)
-
- if symbol_name in names:
- start, end = ast_obj.lineno, ast_obj.end_lineno
- break
- else:
+ pos = _global_assign_pos(source, symbol_name)
+ if pos is None:
raise Exception(f"Could not find symbol `{symbol_name}` in {module.__name__}.")
-
+ else:
+ start, end = pos
_, offset = inspect.getsourcelines(symbol[-2])
if offset != 0:
offset -= 1
@@ -108,6 +98,37 @@ def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> typin
return url
+class NodeWithBody(typing.Protocol):
+ """An AST node with the body attribute."""
+
+ body: list[ast.AST]
+
+
+def _global_assign_pos(ast_: NodeWithBody, name: str) -> typing.Union[tuple[int, int], None]:
+ """
+ Find the first instance where the `name` global is defined in `ast_`.
+
+ Check top-level assignments and assignments nested in top-level if blocks.
+ """
+ for ast_obj in ast_.body:
+ if isinstance(ast_obj, ast.Assign):
+ names = []
+ for target in ast_obj.targets:
+ if isinstance(target, ast.Tuple):
+ names.extend([name.id for name in target.elts if isinstance(name, ast.Name)])
+ else:
+ if isinstance(target, ast.Name):
+ names.append(target.id)
+
+ if name in names:
+ return ast_obj.lineno, ast_obj.end_lineno
+
+ elif isinstance(ast_obj, ast.If):
+ pos_in_if = _global_assign_pos(ast_obj, name)
+ if pos_in_if is not None:
+ return pos_in_if
+
+
def cleanup() -> None:
"""Remove unneeded autogenerated doc files, and clean up others."""
included = __get_included()