sphinx-lint
sphinx-lint copied to clipboard
Default role not found in indented block
Given this (based on https://github.com/python/cpython/blob/9f088336b268dfe9011a7cb550f4e488ccd7e8f5/Doc/library/code.rst?plain=1):
.. c:type:: int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject* co)
Not detected:
If *event* is ``PY_CODE_EVENT_CREATE``, then the callback is invoked
after `co` has been fully initialized. Otherwise, the callback is invoked
before the destruction of *co* takes place, so the prior state of *co*
can be inspected.
Detected:
If *event* is ``PY_CODE_EVENT_CREATE``, then the callback is invoked
after `co` has been fully initialized. Otherwise, the callback is invoked
before the destruction of *co* takes place, so the prior state of *co*
can be inspected.
Sphinx Lint only finds the second `co`:
❯ sphinx-lint --enable=default-role 1.rst
1.rst:13: default role used (hint: for inline literals, use double backticks) (default-role)
Another undetected `func` at https://github.com/python/cpython/blob/9f088336b268dfe9011a7cb550f4e488ccd7e8f5/Doc/c-api/function.rst?plain=1#L171:
.. c:type:: int (*PyFunction_WatchCallback)(PyFunction_WatchEvent event, PyFunctionObject *func, PyObject *new_value)
Type of a function watcher callback function.
If *event* is ``PyFunction_EVENT_CREATE`` or ``PyFunction_EVENT_DESTROY``
then *new_value* will be ``NULL``. Otherwise, *new_value* will hold a
:term:`borrowed reference` to the new value that is about to be stored in
*func* for the attribute that is being modified.
The callback may inspect but must not modify *func*; doing so could have
unpredictable effects, including infinite recursion.
If *event* is ``PyFunction_EVENT_CREATE``, then the callback is invoked
after `func` has been fully initialized. Otherwise, the callback is invoked
before the modification to *func* takes place, so the prior state of *func*
can be inspected. The runtime is permitted to optimize away the creation of
function objects when possible. In such cases no event will be emitted.
Although this creates the possibility of an observable difference of
runtime behavior depending on optimization decisions, it does not change
the semantics of the Python code being executed.
(https://github.com/pre-commit/pygrep-hooks's rst-backticks does find them, but also finds valid uses in productionlist directives.)
I think this is because Sphinx Lint doesn't know about .. c:type:: (and the others at https://www.sphinx-doc.org/en/master/usage/domains/c.html#cross-referencing-c-constructs), so we we classify it as "comment":
@per_file_cache
def type_of_explicit_markup(line):
"""Tell apart various explicit markup blocks."""
line = line.lstrip()
if _starts_with_directive_marker(line):
return "directive"
if _starts_with_footnote_marker(line):
return "footnote"
if _starts_with_citation_marker(line):
return "citation"
if _starts_with_target(line):
return "target"
if _starts_with_substitution_definition(line):
return "substitution_definition"
return "comment"
And so these indented lines are hidden by hide_non_rst_blocks so don't get checked:
def check_text(filename, text, checkers, options=None):
if options is None:
options = CheckersOptions()
errors = []
ext = splitext(filename)[1]
checkers = {checker for checker in checkers if ext in checker.suffixes}
lines = tuple(text.splitlines(keepends=True))
if any(checker.rst_only for checker in checkers):
lines_with_rst_only = hide_non_rst_blocks(lines)
for check in checkers:
...
Adding 'c:type' to DIRECTIVES_CONTAINING_RST enables detection of these blocks and finds the default roles:
Doc/c-api/code.rst:171: default role used (hint: for inline literals, use double backticks) (default-role)
Doc/c-api/code.rst:200: default role used (hint: for inline literals, use double backticks) (default-role)
Doc/c-api/function.rst:171: default role used (hint: for inline literals, use double backticks) (default-role)