Skip to content

Commit a6760a6

Browse files
Merge pull request #160 from python-discord/fix-attributes
Add Support For Attributes In Docstrings
2 parents 3f55e71 + a7e908a commit a6760a6

4 files changed

Lines changed: 177 additions & 138 deletions

File tree

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
# -- Project information -----------------------------------------------------
2424

25-
project = "Bot Core"
25+
project = "Pydis Core"
2626
copyright = "2021, Python Discord"
2727
author = "Python Discord"
2828

docs/utils.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
import inspect
66
import os
77
import subprocess
8+
import types
89
import typing
910
from pathlib import Path
1011

12+
import docstring_parser
1113
import docutils.nodes
1214
import docutils.parsers.rst.states
1315
import git
@@ -25,6 +27,18 @@ def get_build_root() -> Path:
2527
return root
2628

2729

30+
def is_attribute(module: types.ModuleType, parameter: str) -> bool:
31+
"""Returns true if `parameter` is an attribute of `module`."""
32+
docs = docstring_parser.parse(inspect.getdoc(module), docstring_parser.DocstringStyle.GOOGLE)
33+
for param in docs.params:
34+
# The docstring_parser library can mis-parse arguments like `arg (:obj:`str`)` as `arg (`
35+
# which would create a false-negative below, so we just strip away the extra parenthesis.
36+
if param.args[0] == "attribute" and param.arg_name.rstrip(" (") == parameter:
37+
return True
38+
39+
return False
40+
41+
2842
def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> typing.Optional[str]:
2943
"""
3044
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
5973

6074
symbol = [module]
6175
for name in symbol_name.split("."):
62-
symbol.append(getattr(symbol[-1], name))
76+
try:
77+
symbol.append(getattr(symbol[-1], name))
78+
except AttributeError as e:
79+
# This could be caused by trying to link a class attribute
80+
if is_attribute(symbol[-1], name):
81+
break
82+
else:
83+
raise e
84+
6385
symbol_name = name
6486

6587
try:
@@ -138,9 +160,13 @@ def cleanup() -> None:
138160
content = file.read_text(encoding="utf-8").splitlines(keepends=True)
139161

140162
# Rename the extension to be less wordy
141-
# Example: pydis_core.exts -> pydis_core Exts
142-
title = content[0].split()[0].strip().replace("pydis_core.", "").replace(".", " ").title()
143-
title = f"{title}\n{'=' * len(title)}\n\n"
163+
# Example: pydis_core.exts -> Exts
164+
title = content[0].split()[0].strip().replace("\\", "").replace("pydis_core.", "").replace(".", " ")
165+
if "pydis_core" in title:
166+
# Root title: pydis_core -> pydis core
167+
title = title.replace("_", " ")
168+
169+
title = f"{title.title()}\n{'=' * len(title)}\n\n"
144170
content = title, *content[3:]
145171

146172
file.write_text("".join(content), encoding="utf-8")

0 commit comments

Comments
 (0)