0
# Available Checkers
1
2
Built-in checkers for detecting common reStructuredText syntax issues, Python documentation problems, and general formatting issues. Each checker is designed to catch specific types of problems that might not be visible to sphinx-build.
3
4
## Capabilities
5
6
### Checker Registration System
7
8
Decorator for registering checker functions with metadata about supported file types and default behavior.
9
10
```python { .api }
11
def checker(*suffixes, **kwds):
12
"""
13
Decorator to register a function as a checker.
14
15
Parameters:
16
- *suffixes: file extensions this checker supports (e.g., '.rst', '.py')
17
- **kwds: checker properties (enabled=True/False, rst_only=True/False)
18
19
Returns:
20
Decorated function with checker metadata attributes
21
"""
22
```
23
24
### Checker Registry
25
26
Global registry containing all available checker functions.
27
28
```python { .api }
29
all_checkers: dict[str, CheckerFunction]
30
# Dictionary mapping checker names to checker functions
31
# Names are derived from function names by removing 'check_' prefix and replacing '_' with '-'
32
```
33
34
## reStructuredText Checkers
35
36
### Role and Markup Checkers
37
38
Checkers for reStructuredText roles, inline markup, and related syntax issues.
39
40
```python { .api }
41
def check_missing_backtick_after_role(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
42
"""
43
Search for roles missing their closing backticks.
44
45
Bad: :fct:`foo
46
Good: :fct:`foo`
47
48
Supported files: .rst, .po
49
"""
50
51
def check_missing_space_after_literal(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
52
"""
53
Search for inline literals immediately followed by a character.
54
55
Bad: ``items``s
56
Good: ``items``\\ s
57
58
Supported files: .rst, .po
59
"""
60
61
def check_unbalanced_inline_literals_delimiters(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
62
"""
63
Search for unbalanced inline literals delimiters.
64
65
Bad: ``hello`` world``
66
Good: ``hello`` world
67
68
Supported files: .rst, .po
69
"""
70
71
def check_default_role(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
72
"""
73
Search for default roles (disabled by default, allowed in many projects).
74
75
Bad: `print`
76
Good: ``print``
77
78
Supported files: .rst, .po
79
Enabled: False (disabled by default)
80
"""
81
82
def check_missing_space_after_role(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
83
"""
84
Search for roles immediately followed by a character.
85
86
Bad: :exc:`Exception`s.
87
Good: :exc:`Exceptions`\\ s
88
89
Supported files: .rst, .po
90
"""
91
92
def check_role_without_backticks(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
93
"""
94
Search roles without backticks.
95
96
Bad: :func:pdb.main
97
Good: :func:`pdb.main`
98
99
Supported files: .rst, .po
100
"""
101
102
def check_backtick_before_role(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
103
"""
104
Search for roles preceded by a backtick.
105
106
Bad: `:fct:`sum`
107
Good: :fct:`sum`
108
109
Supported files: .rst, .po
110
"""
111
112
def check_role_with_double_backticks(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
113
"""
114
Search for roles with double backticks.
115
116
Bad: :fct:``sum``
117
Good: :fct:`sum`
118
119
Supported files: .rst, .po
120
"""
121
122
def check_missing_space_before_role(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
123
"""
124
Search for missing spaces before roles.
125
126
Bad: the:fct:`sum`, issue:`123`, c:func:`foo`
127
Good: the :fct:`sum`, :issue:`123`, :c:func:`foo`
128
129
Supported files: .rst, .po
130
"""
131
132
def check_missing_space_before_default_role(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
133
"""
134
Search for missing spaces before default role.
135
136
Bad: the`sum`
137
Good: the `sum`
138
139
Supported files: .rst, .po
140
"""
141
142
def check_missing_colon_in_role(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
143
"""
144
Search for missing colons in roles.
145
146
Bad: :issue`123`
147
Good: :issue:`123`
148
149
Supported files: .rst, .po
150
"""
151
152
def check_unnecessary_parentheses(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
153
"""
154
Check for unnecessary parentheses in :func: and :meth: roles.
155
156
Bad: :func:`test()`
157
Good: :func:`test`
158
159
Supported files: .rst, .po
160
"""
161
```
162
163
### Directive Checkers
164
165
Checkers for reStructuredText directive syntax issues.
166
167
```python { .api }
168
def check_directive_with_three_dots(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
169
"""
170
Search for directives with three dots instead of two.
171
172
Bad: ... versionchanged:: 3.6
173
Good: .. versionchanged:: 3.6
174
175
Supported files: .rst, .po
176
"""
177
178
def check_directive_missing_colons(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
179
"""
180
Search for directive wrongly typed as comments.
181
182
Bad: .. versionchanged 3.6.
183
Good: .. versionchanged:: 3.6
184
185
Supported files: .rst, .po
186
"""
187
```
188
189
### Hyperlink Checkers
190
191
Checkers for hyperlink syntax and formatting issues.
192
193
```python { .api }
194
def check_missing_space_in_hyperlink(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
195
"""
196
Search for hyperlinks missing a space.
197
198
Bad: `Link text<https://example.com>`_
199
Good: `Link text <https://example.com>`_
200
201
Supported files: .rst, .po
202
"""
203
204
def check_missing_underscore_after_hyperlink(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
205
"""
206
Search for hyperlinks missing underscore after their closing backtick.
207
208
Bad: `Link text <https://example.com>`
209
Good: `Link text <https://example.com>`_
210
211
Supported files: .rst, .po
212
"""
213
214
def check_hyperlink_reference_missing_backtick(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
215
"""
216
Search for missing backticks in front of hyperlink references.
217
218
Bad: Misc/NEWS <https://github.com/python/cpython/blob/v3.2.6/Misc/NEWS>`_
219
Good: `Misc/NEWS <https://github.com/python/cpython/blob/v3.2.6/Misc/NEWS>`_
220
221
Supported files: .rst, .po
222
"""
223
```
224
225
## Python Code Checkers
226
227
### Syntax Validation
228
229
```python { .api }
230
def check_python_syntax(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
231
"""
232
Search invalid syntax in Python examples.
233
234
Compiles Python code and reports syntax errors.
235
Also checks for carriage returns in non-Windows environments.
236
237
Supported files: .py
238
RST-only: False (processes entire file content)
239
"""
240
```
241
242
## General Formatting Checkers
243
244
### Whitespace and Character Issues
245
246
Checkers for common formatting problems across all supported file types.
247
248
```python { .api }
249
def check_carriage_return(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
250
"""
251
Check for carriage returns (\\r) in lines.
252
253
Supported files: .py, .rst, .po
254
RST-only: False
255
"""
256
257
def check_horizontal_tab(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
258
"""
259
Check for horizontal tabs (\\t) in lines.
260
261
Supported files: .py, .rst, .po
262
RST-only: False
263
"""
264
265
def check_trailing_whitespace(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
266
"""
267
Check for trailing whitespaces at end of lines.
268
269
Supported files: .py, .rst, .po
270
RST-only: False
271
"""
272
273
def check_missing_final_newline(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
274
"""
275
Check that the last line of the file ends with a newline.
276
277
Supported files: .py, .rst, .po
278
RST-only: False
279
"""
280
```
281
282
### Line Length Checking
283
284
```python { .api }
285
def check_line_too_long(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
286
"""
287
Check for line length; this checker is not run by default.
288
289
Uses options.max_line_length for threshold.
290
Ignores wide tables, long interpreted text, directives, hyperlinks, and long literals.
291
292
Supported files: .rst, .po
293
Enabled: False (disabled by default)
294
RST-only: True
295
"""
296
```
297
298
## Specialized Checkers
299
300
### reStructuredText Structure
301
302
```python { .api }
303
def check_bad_dedent(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
304
"""
305
Check for mis-alignment in indentation in code blocks.
306
307
Detects blocks that appear to be code blocks but have incorrect indentation.
308
309
Supported files: .rst, .po
310
RST-only: False (but processes RST structure)
311
"""
312
313
def check_dangling_hyphen(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
314
"""
315
Check for lines ending in a hyphen.
316
317
Supported files: .rst
318
RST-only: True
319
"""
320
```
321
322
### Optional/Disabled Checkers
323
324
Checkers that are disabled by default but can be enabled when needed.
325
326
```python { .api }
327
def check_leaked_markup(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
328
"""
329
Check HTML files for leaked reST markup.
330
331
This only works if the HTML files have been built.
332
333
Supported files: .html
334
Enabled: False (disabled by default)
335
RST-only: False
336
"""
337
338
def check_triple_backticks(file: str, lines: list[str], options: CheckersOptions = None) -> Generator[tuple[int, str], None, None]:
339
"""
340
Check for triple backticks, like ```Point``` (but it's a valid syntax).
341
342
Bad: ```Point```
343
Good: ``Point``
344
345
Triple backticks are valid but uncommon in reStructuredText.
346
347
Supported files: .rst, .po
348
Enabled: False (disabled by default)
349
"""
350
```
351
352
## Checker Properties
353
354
Each checker function has the following attributes set by the `@checker` decorator:
355
356
- **`name`**: Checker name (derived from function name)
357
- **`suffixes`**: Tuple of supported file extensions
358
- **`enabled`**: Boolean indicating if checker runs by default
359
- **`rst_only`**: Boolean indicating if checker only processes RST content
360
361
## Usage Examples
362
363
### Listing Available Checkers
364
365
```python
366
from sphinxlint.checkers import all_checkers
367
368
# List all checker names
369
for name in sorted(all_checkers.keys()):
370
checker = all_checkers[name]
371
print(f"{name}: {checker.__doc__.splitlines()[0] if checker.__doc__ else 'No description'}")
372
373
# Filter by file type
374
rst_checkers = [name for name, checker in all_checkers.items() if '.rst' in checker.suffixes]
375
print(f"RST checkers: {', '.join(sorted(rst_checkers))}")
376
```
377
378
### Custom Checker Selection
379
380
```python
381
from sphinxlint.checkers import all_checkers
382
383
# Only whitespace checkers
384
whitespace_checkers = {
385
all_checkers['trailing-whitespace'],
386
all_checkers['horizontal-tab'],
387
all_checkers['carriage-return']
388
}
389
390
# Enable all including disabled ones
391
all_available = set(all_checkers.values())
392
393
# Role-related checkers only
394
role_checker_names = [name for name in all_checkers.keys() if 'role' in name]
395
role_checkers = {all_checkers[name] for name in role_checker_names}
396
```