From 2b6fe6eb8a0618a0d305ecfd88a10dc0ec8dec2c Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Thu, 10 Nov 2022 22:21:42 +0400 Subject: Add Support For Attributes In Docstrings This allows class attributes to be defined in docstrings without causing an exception while linking the source code. Due to the non-static nature of attributes, it's not trivial to link their actual definition, so the chosen lines will actually be all the lines of the parent class. Signed-off-by: Hassan Abouelela --- docs/utils.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'docs/utils.py') diff --git a/docs/utils.py b/docs/utils.py index e7295798..ba6c8e34 100644 --- a/docs/utils.py +++ b/docs/utils.py @@ -5,9 +5,11 @@ import importlib.util import inspect import os import subprocess +import types import typing from pathlib import Path +import docstring_parser import docutils.nodes import docutils.parsers.rst.states import git @@ -25,6 +27,18 @@ def get_build_root() -> Path: return root +def is_attribute(module: types.ModuleType, parameter: str) -> bool: + """Returns true if `parameter` is an attribute of `module`.""" + docs = docstring_parser.parse(inspect.getdoc(module), docstring_parser.DocstringStyle.GOOGLE) + for param in docs.params: + # The docstring_parser library can mis-parse arguments like `arg (:obj:`str`)` as `arg (` + # which would create a false-negative below, so we just strip away the extra parenthesis. + if param.args[0] == "attribute" and param.arg_name.rstrip(" (") == parameter: + return True + + return False + + def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> typing.Optional[str]: """ Function called by linkcode to get the URL for a given resource. @@ -59,7 +73,15 @@ def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> typin symbol = [module] for name in symbol_name.split("."): - symbol.append(getattr(symbol[-1], name)) + try: + symbol.append(getattr(symbol[-1], name)) + except AttributeError as e: + # This could be caused by trying to link a class attribute + if is_attribute(symbol[-1], name): + break + else: + raise e + symbol_name = name try: -- cgit v1.2.3 From a7e908a51d62021e4b8d49af73da605c2dfc73e7 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Thu, 10 Nov 2022 22:42:18 +0400 Subject: Clean Up Formatting Of Project Name In Docs Signed-off-by: Hassan Abouelela --- docs/conf.py | 2 +- docs/utils.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'docs/utils.py') diff --git a/docs/conf.py b/docs/conf.py index 9aaa8eff..2fea7264 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ from docs import utils # noqa: E402 # -- Project information ----------------------------------------------------- -project = "Bot Core" +project = "Pydis Core" copyright = "2021, Python Discord" author = "Python Discord" diff --git a/docs/utils.py b/docs/utils.py index ba6c8e34..3f58e767 100644 --- a/docs/utils.py +++ b/docs/utils.py @@ -160,9 +160,13 @@ def cleanup() -> None: content = file.read_text(encoding="utf-8").splitlines(keepends=True) # Rename the extension to be less wordy - # Example: pydis_core.exts -> pydis_core Exts - title = content[0].split()[0].strip().replace("pydis_core.", "").replace(".", " ").title() - title = f"{title}\n{'=' * len(title)}\n\n" + # Example: pydis_core.exts -> Exts + title = content[0].split()[0].strip().replace("\\", "").replace("pydis_core.", "").replace(".", " ") + if "pydis_core" in title: + # Root title: pydis_core -> pydis core + title = title.replace("_", " ") + + title = f"{title.title()}\n{'=' * len(title)}\n\n" content = title, *content[3:] file.write_text("".join(content), encoding="utf-8") -- cgit v1.2.3