diff --git a/readme.md b/readme.md index a2f622e..822550f 100644 --- a/readme.md +++ b/readme.md @@ -36,6 +36,9 @@ This code will be executed ``` # Changelog +#### 0.12 (2024-01-09) +- Error when providing invalid options + #### 0.11 (2024-01-09) - Updated CI and ruff fixes diff --git a/src/sphinx_exec_code/__version__.py b/src/sphinx_exec_code/__version__.py index 438a041..b804441 100644 --- a/src/sphinx_exec_code/__version__.py +++ b/src/sphinx_exec_code/__version__.py @@ -1 +1 @@ -__version__ = '0.11' +__version__ = '0.12' diff --git a/src/sphinx_exec_code/sphinx_exec.py b/src/sphinx_exec_code/sphinx_exec.py index 9d4c696..b1017c1 100644 --- a/src/sphinx_exec_code/sphinx_exec.py +++ b/src/sphinx_exec_code/sphinx_exec.py @@ -10,7 +10,7 @@ from sphinx_exec_code.code_exec import CodeExceptionError, execute_code from sphinx_exec_code.code_format import VisibilityMarkerError, get_show_exec_code from sphinx_exec_code.configuration import EXAMPLE_DIR -from sphinx_exec_code.sphinx_spec import SpecCode, SpecOutput, SphinxSpecBase, build_spec +from sphinx_exec_code.sphinx_spec import SphinxSpecBase, build_spec, get_specs def create_literal_block(objs: list, code: str, spec: SphinxSpecBase): @@ -83,7 +83,7 @@ def _run(self) -> list: file = Path(raw_file) line = self._get_code_line(raw_line, content) - code_spec = SpecCode.from_options(self.options) + code_spec, output_spec = get_specs(self.options) # Read from example files if code_spec.filename: @@ -115,5 +115,5 @@ def _run(self) -> list: raise ExtensionError(msg) from None # Show the output from the code execution - create_literal_block(output, code_results, spec=SpecOutput.from_options(self.options)) + create_literal_block(output, code_results, spec=output_spec) return output diff --git a/src/sphinx_exec_code/sphinx_spec.py b/src/sphinx_exec_code/sphinx_spec.py index 2218d8d..33b9ecc 100644 --- a/src/sphinx_exec_code/sphinx_spec.py +++ b/src/sphinx_exec_code/sphinx_spec.py @@ -1,4 +1,4 @@ -from typing import Any, Callable, ClassVar, Dict +from typing import Any, Callable, ClassVar, Dict, Tuple from docutils.parsers.rst import directives # type: ignore @@ -28,6 +28,7 @@ def from_options(cls, options: Dict[str, Any]) -> 'SphinxSpecBase': if not val: val = cls.defaults[name] opts[name] = val + return cls(**opts) @classmethod @@ -44,6 +45,20 @@ def build_spec() -> Dict[str, Callable[[Any], Any]]: return spec +def get_specs(options: Dict[str, Any]) -> Tuple['SpecCode', 'SpecOutput']: + supported = set(SpecCode.aliases) | set(SpecOutput.aliases) + invalid = set(options) - supported + + if invalid: + msg = ( + f'Invalid option{"s" if len(invalid) != 1 else ""}: ' + f'{", ".join(sorted(map(str, invalid)))}! Supported: {", ".join(sorted(map(str, supported)))}' + ) + raise ValueError(msg) + + return SpecCode.from_options(options), SpecOutput.from_options(options) + + class SpecCode(SphinxSpecBase): aliases: ClassVar = { 'hide_code': 'hide', diff --git a/tests/test_sphinx_spec.py b/tests/test_sphinx_spec.py index c2ec7bf..51ad00b 100644 --- a/tests/test_sphinx_spec.py +++ b/tests/test_sphinx_spec.py @@ -4,7 +4,7 @@ import pytest from docutils.parsers.rst import directives -from sphinx_exec_code.sphinx_spec import SpecCode, SpecOutput, SphinxSpecBase, build_spec +from sphinx_exec_code.sphinx_spec import SpecCode, SpecOutput, SphinxSpecBase, build_spec, get_specs def test_aliases_unique(): @@ -42,12 +42,12 @@ def test_build_spec_code(): def test_spec_code(): - obj = SpecCode.from_options({'linenos': None, 'caption': 'my_header'}) + obj = SpecCode.from_options({'linenos': None, 'caption': 'my_header', 'filename': 'filename'}) assert obj.caption == 'my_header' assert obj.language == 'python' assert obj.linenos is True assert obj.hide is False - assert obj.filename == '' + assert obj.filename == 'filename' def test_spec_output(): @@ -56,3 +56,20 @@ def test_spec_output(): assert obj.language == 'none' assert obj.linenos is False assert obj.hide is True + + +def test_invalid_options(): + with pytest.raises(ValueError) as e: # noqa: PT011 + get_specs({'hide-output': None}) + + assert str(e.value) == ('Invalid option: hide-output! ' + 'Supported: caption, caption_output, filename, hide_code, hide_output, ' + 'language, language_output, linenos, linenos_output') + + + with pytest.raises(ValueError) as e: # noqa: PT011 + get_specs({'hide-output': None, 'language_output': 'asdf', 'caption-output': 'test'}) + + assert str(e.value) == ('Invalid options: caption-output, hide-output! ' + 'Supported: caption, caption_output, filename, hide_code, hide_output, ' + 'language, language_output, linenos, linenos_output')