-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tool to check example in docstrings (#4353)
* Add tool to check example in docstrings * update lock * add task * add ignored message * add example check CI
- Loading branch information
1 parent
6c8b656
commit 7c1cabf
Showing
5 changed files
with
139 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
python/packages/autogen-core/docs/src/_extension/code_lint.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# Modified from: https://github.com/kai687/sphinxawesome-codelinter | ||
|
||
import tempfile | ||
from typing import AbstractSet, Any, Iterable | ||
|
||
from docutils import nodes | ||
from sphinx.application import Sphinx | ||
from sphinx.builders import Builder | ||
from sphinx.util import logging | ||
from sphinx.util.console import darkgreen, darkred, red, teal, faint # type: ignore[attr-defined] | ||
|
||
from pygments import highlight # type: ignore | ||
from pygments.lexers import PythonLexer | ||
from pygments.formatters import TerminalFormatter | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
__version__ = "0.1.0" | ||
|
||
|
||
class CodeLinter(Builder): | ||
"""Iterate over all ``literal_block`` nodes. | ||
pipe them into any command line tool that | ||
can read from standard input. | ||
""" | ||
|
||
name = "code_lint" | ||
allow_parallel = True | ||
|
||
def init(self) -> None: | ||
"""Initialize.""" | ||
self._had_errors = False | ||
pass | ||
|
||
def get_outdated_docs(self) -> str | Iterable[str]: | ||
"""Check for outdated files. | ||
Return an iterable of outdated output files, or a string describing what an | ||
update will build. | ||
""" | ||
return self.env.found_docs | ||
|
||
def get_target_uri(self, docname: str, typ: str | None = None) -> str: | ||
"""Return Target URI for a document name.""" | ||
return "" | ||
|
||
def prepare_writing(self, docnames: AbstractSet[str]) -> None: | ||
"""Run these steps before documents are written.""" | ||
return | ||
|
||
def write_doc(self, docname: str, doctree: nodes.Node) -> None: | ||
path_prefix: str = self.app.config.code_lint_path_prefix | ||
supported_languages = set(["python"]) | ||
|
||
if not docname.startswith(path_prefix): | ||
return | ||
|
||
for code in doctree.findall(nodes.literal_block): | ||
if code["language"] in supported_languages: | ||
logger.info("Checking a code block in %s...", docname, nonl=True) | ||
if "ignore" in code["classes"]: | ||
logger.info(" " + darkgreen("OK[ignored]")) | ||
continue | ||
|
||
# Create a temporary file to store the code block | ||
with tempfile.NamedTemporaryFile(mode="wb", suffix=".py") as temp_file: | ||
temp_file.write(code.astext().encode()) | ||
temp_file.flush() | ||
|
||
# Run pyright on the temporary file using subprocess.run | ||
import subprocess | ||
|
||
result = subprocess.run(["pyright", temp_file.name], capture_output=True, text=True) | ||
if result.returncode != 0: | ||
logger.info(" " + darkred("FAIL")) | ||
highlighted_code = highlight(code.astext(), PythonLexer(), TerminalFormatter()) # type: ignore | ||
output = f"{faint('========================================================')}\n{red('Error')}: Pyright found issues in {teal(docname)}:\n{faint('--------------------------------------------------------')}\n{highlighted_code}\n{faint('--------------------------------------------------------')}\n\n{teal('pyright output:')}\n{red(result.stdout)}{faint('========================================================')}\n" | ||
logger.info(output) | ||
self._had_errors = True | ||
else: | ||
logger.info(" " + darkgreen("OK")) | ||
|
||
def finish(self) -> None: | ||
"""Finish the build process.""" | ||
if self._had_errors: | ||
raise RuntimeError("Code linting failed - see earlier output") | ||
|
||
|
||
def setup(app: Sphinx) -> dict[str, Any]: | ||
app.add_builder(CodeLinter) | ||
app.add_config_value("code_lint_path_prefix", "", "env") | ||
|
||
return { | ||
"version": __version__, | ||
"parallel_read_safe": True, | ||
"parallel_write_safe": True, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.