Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default role not found in indented block #108

Open
hugovk opened this issue Jan 11, 2024 · 2 comments · May be fixed by #109
Open

Default role not found in indented block #108

hugovk opened this issue Jan 11, 2024 · 2 comments · May be fixed by #109

Comments

@hugovk
Copy link
Collaborator

hugovk commented Jan 11, 2024

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)
@hugovk
Copy link
Collaborator Author

hugovk commented Jan 11, 2024

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.)

@hugovk
Copy link
Collaborator Author

hugovk commented Jan 11, 2024

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)

@hugovk hugovk linked a pull request Jan 16, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant