From b61c1e6a5739e5aabbea1dc8cd70297bb666827b Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Mon, 21 Feb 2022 12:58:40 +0000 Subject: Update how we auto-generate docs --- docs/conf.py | 118 ++++++++--------------------------------------------------- 1 file changed, 15 insertions(+), 103 deletions(-) (limited to 'docs/conf.py') diff --git a/docs/conf.py b/docs/conf.py index 142ceb41..e2801e2c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,16 +1,14 @@ # Configuration file for the Sphinx documentation builder. # https://www.sphinx-doc.org/en/master/usage/configuration.html -import ast -import importlib -import inspect +import functools import sys -import typing from pathlib import Path import git import tomli -from sphinx.application import Sphinx + +from docs import utils # -- Project information ----------------------------------------------------- @@ -90,43 +88,6 @@ html_js_files = [ ] -# -- Autodoc cleanup --------------------------------------------------------- -# Clean up the output generated by autodoc to produce a nicer documentation tree -# This is kept in a function to avoid polluting the namespace -def __cleanup() -> None: - for file in (PROJECT_ROOT / "docs" / "output").iterdir(): - if file.name == "modules.rst": - # We only have one module, so this is redundant - # Remove it and flatten out the tree - file.unlink() - continue - - elif file.name in ("botcore.rst", "botcore.exts.rst"): - content = file.read_text(encoding="utf-8").splitlines(keepends=True) - - # Rename the extension to be less wordy - # Example: botcore.exts -> Botcore Exts - title = content[0].split()[0].strip().replace("botcore.", "").replace(".", " ").title() - title = f"{title}\n{'=' * len(title)}\n\n" - content[0:2] = title - - file.write_text("".join(content), encoding="utf-8") - - else: - # Clean up the submodule name so it's just the name without the top level module name - # example: `botcore.regex module` -> `regex` - lines = file.read_text(encoding="utf-8").splitlines(keepends=True) - lines[0] = lines[0].replace("module", "").strip().split(".")[-1] + "\n" - file.write_text("".join(lines)) - - # Take the opportunity to configure autodoc - content = file.read_text(encoding="utf-8").replace("undoc-members", "special-members") - file.write_text(content, encoding="utf-8") - - -__cleanup() - - def skip(*args) -> bool: """Things that should be skipped by the autodoc generation.""" name = args[2] @@ -139,11 +100,6 @@ def skip(*args) -> bool: return would_skip -def setup(app: Sphinx) -> None: - """Add extra hook-based autodoc configuration.""" - app.connect("autodoc-skip-member", skip) - - # -- Extension configuration ------------------------------------------------- # -- Options for todo extension ---------------------------------------------- @@ -175,60 +131,16 @@ intersphinx_mapping = { } +# -- Options for the autodoc extension --------------------------------------- +utils.cleanup() +autodoc_default_options = { + "members": True, + "special-members": True, + "show-inheritance": True, + "imported-members": False, + "exclude-members": "__weakref__" +} + + # -- Options for the linkcode extension -------------------------------------- -def linkcode_resolve(domain: str, info: dict[str, str]) -> typing.Optional[str]: - """ - Function called by linkcode to get the URL for a given resource. - - See for more details: - https://www.sphinx-doc.org/en/master/usage/extensions/linkcode.html#confval-linkcode_resolve - """ - if domain != "py": - raise Exception("Unknown domain passed to linkcode function.") - - symbol_name = info["fullname"] - - module = importlib.import_module(info["module"]) - - symbol = [module] - for name in symbol_name.split("."): - symbol.append(getattr(symbol[-1], name)) - symbol_name = name - - try: - lines, start = inspect.getsourcelines(symbol[-1]) - end = start + len(lines) - except TypeError: - # Find variables by parsing the ast - source = ast.parse(inspect.getsource(symbol[-2])) - 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: - raise Exception(f"Could not find symbol `{symbol_name}` in {module.__name__}.") - - _, offset = inspect.getsourcelines(symbol[-2]) - if offset != 0: - offset -= 1 - start += offset - end += offset - - file = Path(inspect.getfile(module)).relative_to(PROJECT_ROOT).as_posix() - - url = f"{SOURCE_FILE_LINK}/{file}#L{start}" - if end != start: - url += f"-L{end}" - - return url +linkcode_resolve = functools.partial(utils.linkcode_resolve, SOURCE_FILE_LINK) -- cgit v1.2.3