Skip to content

Commit 213bf03

Browse files
committed
Enhance static typing
Signed-off-by: Reece Dunham <me@rdil.rocks>
1 parent 475cc62 commit 213bf03

6 files changed

Lines changed: 41 additions & 28 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ pip-wheel-metadata/
1212
.python-version
1313
site/
1414
poetry.lock
15-
15+
.mypy_cache

src/mkdocstrings/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
22
mkdocstrings package.
33
4-
Automatic documentation from source code, for mkdocs.
4+
Automatic documentation from source code, for MkDocs.
55
66
This project was originally written for Python source code only, hence the name.
77
It was then refactored to use external tools to load documentation. The main purpose

src/mkdocstrings/extension.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@
3333
from markdown.extensions import Extension
3434
from markdown.util import AtomicString
3535
from mkdocs.utils import log
36+
from typing import Union
3637

3738
from .handlers import CollectionError, get_handler
3839

3940

40-
def atomic_brute_cast(tree: Element) -> None:
41+
def atomic_brute_cast(tree: Element) -> Union[Element, None]:
4142
"""
4243
Cast every node's text into an atomic string to prevent further processing on it.
4344
@@ -91,27 +92,28 @@ def __init__(self, parser, md: Markdown, config: dict) -> None:
9192

9293
def test(self, parent: Element, block: Element) -> bool:
9394
sibling = self.lastChild(parent)
94-
bool1 = self.RE.search(block)
95+
bool1 = self.RE.search(str(block))
9596
bool2 = (
96-
block.startswith(" " * self.tab_length)
97+
str(block).startswith(" " * self.tab_length)
9798
and sibling is not None
9899
and sibling.get("class", "").find(self.CLASSNAME) != -1
99100
)
100101
return bool(bool1 or bool2)
101102

102103
def run(self, parent: Element, blocks: Element) -> None:
103104
block = blocks.pop(0)
104-
m = self.RE.search(block)
105+
m = self.RE.search(str(block))
105106

106107
if m:
107-
block = block[m.end() :] # removes the first line
108+
# removes the first line
109+
block = block[m.end() :] # type: ignore
108110

109111
block, the_rest = self.detab(block)
110112

111113
if m:
112114
identifier = m.group(1)
113115
log.debug(f"mkdocstrings.extension: Matched '::: {identifier}'")
114-
config = yaml.safe_load(block) or {}
116+
config = yaml.safe_load(str(block)) or {}
115117

116118
handler_name = self.get_handler_name(config)
117119
log.debug(f"mkdocstrings.extension: Using handler '{handler_name}'")
@@ -138,9 +140,11 @@ def run(self, parent: Element, blocks: Element) -> None:
138140
except ParseError as error:
139141
message = f"mkdocstrings.extension: {error}"
140142
if "mismatched tag" in str(error):
141-
lineno, columnno = str(error).split(":")[-1].split(", ")
142-
lineno = int(lineno.split(" ")[-1])
143-
columnno = int(columnno.split(" ")[-1])
143+
line, column = str(error).split(":")[-1].split(", ")
144+
145+
lineno = int(line.split(" ")[-1])
146+
columnno = int(column.split(" ")[-1])
147+
144148
line = rendered.split("\n")[lineno - 1]
145149
character = line[columnno]
146150
message += (
@@ -151,7 +155,7 @@ def run(self, parent: Element, blocks: Element) -> None:
151155
log.error(message)
152156
return
153157

154-
as_xml = atomic_brute_cast(as_xml)
158+
as_xml = atomic_brute_cast(as_xml) # type: ignore
155159
parent.append(as_xml)
156160

157161
if the_rest:
@@ -225,6 +229,9 @@ def __init__(self, config: dict, **kwargs) -> None:
225229
kwargs: Keyword arguments used by `markdown.extensions.Extension`.
226230
"""
227231
super().__init__(**kwargs)
232+
if config == {}:
233+
# fake init, cancel early
234+
return
228235
self._config = config
229236

230237
def extendMarkdown(self, md: Markdown) -> None:

src/mkdocstrings/handlers/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ class BaseRenderer:
9898
To define a fallback theme, add a `FALLBACK_THEME` class-variable.
9999
"""
100100

101+
FALLBACK_THEME: str = ""
102+
101103
def __init__(self, directory: str, theme: str) -> None:
102104
"""
103105
Initialization method.
@@ -112,7 +114,7 @@ def __init__(self, directory: str, theme: str) -> None:
112114
themes_dir = Path(__file__).parent.parent / "templates" / directory
113115
theme_dir = themes_dir / theme
114116
if not theme_dir.exists():
115-
if hasattr(self, "FALLBACK_THEME"):
117+
if self.FALLBACK_THEME != "":
116118
log.warning(
117119
f"mkdocstrings.handlers: No '{theme}' theme in '{directory}', "
118120
f"falling back to theme '{self.FALLBACK_THEME}'"

src/mkdocstrings/handlers/python.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from markdown import Markdown
1212
from mkdocs.utils import log
1313

14-
from . import BaseCollector, BaseHandler, BaseRenderer, CollectionError
14+
from . import BaseCollector, BaseHandler, BaseRenderer, CollectionError, DataType
1515

1616

1717
class PythonRenderer(BaseRenderer):
@@ -51,7 +51,7 @@ class PythonRenderer(BaseRenderer):
5151
**`heading_level`** | `int` | The initial heading level to use. | `2`
5252
"""
5353

54-
def render(self, data: dict, config: dict) -> str:
54+
def render(self, data: DataType, config: dict) -> str:
5555
final_config = dict(self.DEFAULT_CONFIG)
5656
final_config.update(config)
5757

@@ -149,7 +149,7 @@ def __init__(self) -> None:
149149
env=env,
150150
)
151151

152-
def collect(self, identifier: str, config: dict) -> dict:
152+
def collect(self, identifier: str, config: dict) -> DataType:
153153
"""
154154
Collect the documentation tree given an identifier and selection options.
155155
@@ -187,7 +187,7 @@ def collect(self, identifier: str, config: dict) -> dict:
187187
print(json_input, file=self.process.stdin, flush=True)
188188

189189
log.debug("mkdocstrings.handlers.python: Reading process' stdout")
190-
stdout = self.process.stdout.readline()
190+
stdout = self.process.stdout.readline() # type: ignore
191191

192192
log.debug("mkdocstrings.handlers.python: Loading JSON output as Python object")
193193
try:
@@ -204,13 +204,13 @@ def collect(self, identifier: str, config: dict) -> dict:
204204
raise CollectionError(result["error"])
205205

206206
if result["loading_errors"]:
207-
for error in result["loading_errors"]:
208-
log.warning(f"mkdocstrings.handlers.python: {error}")
207+
for err in result["loading_errors"]:
208+
log.warning(f"mkdocstrings.handlers.python: {err}")
209209

210210
if result["parsing_errors"]:
211-
for path, errors in result["parsing_errors"].items():
212-
for error in errors:
213-
log.warning(f"mkdocstrings.handlers.python: {error}")
211+
for path, problems in result["parsing_errors"].items():
212+
for err in problems:
213+
log.warning(f"mkdocstrings.handlers.python: {err}")
214214

215215
# We always collect only one object at a time
216216
result = result["objects"][0]
@@ -224,7 +224,6 @@ def teardown(self) -> None:
224224
"""Terminate the opened subprocess, set it to None."""
225225
log.debug("mkdocstrings.handlers.python: Tearing process down")
226226
self.process.terminate()
227-
self.process = None
228227

229228

230229
class PythonHandler(BaseHandler):

src/mkdocstrings/plugin.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from mkdocs.structure.pages import Page
3939
from mkdocs.structure.toc import AnchorLink
4040
from mkdocs.utils import log
41+
from typing import Dict, Any
4142

4243
from .extension import MkdocstringsExtension
4344
from .handlers import teardown
@@ -71,10 +72,13 @@ class MkdocstringsPlugin(BasePlugin):
7172
"""
7273

7374
config_scheme: Tuple[Tuple[str, MkType]] = (
74-
("watch", MkType(list, default=[])),
75+
("watch", MkType(list, default=[])), # type: ignore
7576
("handlers", MkType(dict, default={})),
7677
("default_handler", MkType(str, default="python")),
7778
)
79+
80+
url_map: Dict[Any, str]
81+
7882
"""
7983
The configuration options of `mkdocstrings`, written in `mkdocs.yml`.
8084
@@ -103,7 +107,8 @@ class MkdocstringsPlugin(BasePlugin):
103107

104108
def __init__(self) -> None:
105109
super(MkdocstringsPlugin, self).__init__()
106-
self.mkdocstrings_extension = None
110+
# stop mypy from complaining about NoneType mismatches
111+
self.mkdocstrings_extension = MkdocstringsExtension(config={})
107112
self.url_map = {}
108113

109114
def on_serve(self, server: Server, config: Config, **kwargs) -> Server:
@@ -193,7 +198,7 @@ def on_post_page(self, output: str, page: Page, config: Config, **kwargs) -> str
193198
while re.search(placeholder.seed, output) or any(placeholder.seed in url for url in self.url_map.values()):
194199
placeholder.set_seed()
195200

196-
unmapped, unintended = [], []
201+
unmapped, unintended = [], [] # type: ignore
197202
soup = BeautifulSoup(output, "html.parser")
198203
placeholder.replace_code_tags(soup)
199204
fixed_soup = AUTO_REF.sub(self.fix_ref(unmapped, unintended), str(soup))
@@ -296,8 +301,8 @@ class Placeholder:
296301
"""
297302

298303
def __init__(self) -> None:
299-
self.ids = {}
300-
self.seed = None
304+
self.ids: Dict[str, str] = {}
305+
self.seed = ""
301306
self.set_seed()
302307

303308
def store(self, value: str) -> str:

0 commit comments

Comments
 (0)