Source code for sphinxcontrib.eval

"""Provide ``setup()`` to
`sphinx <https://www.sphinx-doc.org/en/master/extdev/index.html>`_.
"""

from __future__ import annotations

import io
import os
from contextlib import redirect_stdout, suppress
from subprocess import check_output
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from sphinx.application import Sphinx

from ._version import __version__  # type: ignore
from .rst import RSTEvalParser

SH = os.getenv("SHELL", "sh")


[docs] def eval_sh(input: str) -> str: """Eval sh. :param input: :type input: str :rtype: str """ try: output = check_output( # nosec B603 [SH, "-c", input], universal_newlines=True ) except Exception: output = "" return output
[docs] def eval_bash(input: str) -> str: """Eval bash. :param input: :type input: str :rtype: str """ try: output = check_output( # nosec B603 B607 ["bash", "-c", input], universal_newlines=True ) except Exception: output = "" return output
[docs] def eval_python(input: str) -> str: """Eval python. :param input: :type input: str :rtype: str """ string = io.StringIO() try: with redirect_stdout(string): exec(input) # nosec B102 string.seek(0) output = string.read() except Exception: output = "" return output
EVAL_FUNCS = {"sh": eval_sh, "bash": eval_bash, "python": eval_python}
[docs] def setup(app: Sphinx) -> dict[str, Any]: """Set up. :param app: :type app: Sphinx :rtype: dict[str, Any] """ app.add_config_value("eval_funcs", EVAL_FUNCS, "env") app.add_source_parser(RSTEvalParser, True) with suppress(ImportError): from .myst import MystEvalParser app.add_source_parser(MystEvalParser, True) return {"version": __version__}