diff --git a/docs/changelog.rst b/docs/changelog.rst index 8df9f41..60d8fc7 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -2,6 +2,13 @@ Change log ********** +x.x.x +##### + +Changes + +* The ``:filename:`` input is now resolved only to the ``conf.py`` directory (``srcdir`` in Sphinx) + 0.6.0 ##### diff --git a/docs/usage.rst b/docs/usage.rst index 7b38314..397cc8a 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -55,8 +55,8 @@ To document a file that is not part of a module, use :filename: :func: my_func_that_returns_a_parser :prog: script.py -The 'filename' option could be absolute path or a relative path under current -working dir. +The 'filename' option can be an absolute path or a relative one. +When a relative path is provided, the Sphinx ``srcdir`` will be taken as the base, which is the directory housing the active ``conf.py`` file. \:module\: Module name, where the function is located diff --git a/sphinxarg/ext.py b/sphinxarg/ext.py index 702d455..2e79880 100644 --- a/sphinxarg/ext.py +++ b/sphinxarg/ext.py @@ -3,7 +3,6 @@ import importlib import operator import os -import shutil import sys from argparse import ArgumentParser from typing import TYPE_CHECKING, ClassVar, cast @@ -492,24 +491,33 @@ def _nested_parse_paragraph(self, text): self.state.nested_parse(StringList(text.split('\n')), 0, content) return content + @property + def _srcdir(self): + """Internal property for source root-dir. + + This is a property such that we can easily mock it during tests. + """ + return self.env.srcdir + def _open_filename(self): + file = self.options['filename'] + + # If the provided path is not absolute, we consider it relative to the docs + # conf dir: + if not os.path.isabs(file): + file = os.path.realpath( + os.path.join(self._srcdir, file) + ) # Resolve things like ".." to make clear where we're searching + # try open with given path try: - return open(self.options['filename']) + return open(file) except OSError: - pass - # try open with abspath - try: - return open(os.path.abspath(self.options['filename'])) - except OSError: - pass - # try open with shutil which - try: - return open(shutil.which(self.options['filename'])) - except (OSError, TypeError): - pass - # raise exception - raise FileNotFoundError(self.options['filename']) + msg = ( + f'Failed to find provided source file `{self.options["filename"]}` ' + f'(resolved to `{file}`)' + ) + raise FileNotFoundError(msg) from None def _print_subcommands(self, data, nested_content, markdown_help=False, settings=None): """ diff --git a/test/conftest.py b/test/conftest.py index 1872ee3..a6382d9 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -7,11 +7,25 @@ from lxml import etree as lxmltree from sphinx.testing.util import SphinxTestApp +from sphinxarg.ext import ArgParseDirective + pytest_plugins = 'sphinx.testing.fixtures' etree_cache: dict[str, str] = {} +@pytest.fixture(autouse=True) +def mock_argparse_src_dir(monkeypatch): + """Fixture to mock the source root dir in `ArgParseDirective`. + + Auto-used, i.e. applied to all tests by default. + Without this, the source .py files will be searched inside the pytest temp + directory, where our .py files won't be copied into. + """ + tests_dir = Path(__file__).parent.absolute() + monkeypatch.setattr(ArgParseDirective, '_srcdir', str(tests_dir)) + + @pytest.fixture(scope='session') def rootdir(): return Path(__file__).parent.absolute() / 'roots' diff --git a/test/roots/test-argparse-directive/index.rst b/test/roots/test-argparse-directive/index.rst index ee2cfa6..88f1310 100644 --- a/test/roots/test-argparse-directive/index.rst +++ b/test/roots/test-argparse-directive/index.rst @@ -2,7 +2,7 @@ Fails to parse ============== .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser :index-groups: Needs; Commas diff --git a/test/roots/test-command-by-group-index/sample.rst b/test/roots/test-command-by-group-index/sample.rst index a84877b..15b442e 100644 --- a/test/roots/test-command-by-group-index/sample.rst +++ b/test/roots/test-command-by-group-index/sample.rst @@ -2,7 +2,7 @@ Sample ====== .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser :nosubcommands: diff --git a/test/roots/test-command-by-group-index/subcommand-a.rst b/test/roots/test-command-by-group-index/subcommand-a.rst index d5959a8..135eed1 100644 --- a/test/roots/test-command-by-group-index/subcommand-a.rst +++ b/test/roots/test-command-by-group-index/subcommand-a.rst @@ -2,7 +2,7 @@ Command A ========= .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser :path: A diff --git a/test/roots/test-command-by-group-index/subcommand-b.rst b/test/roots/test-command-by-group-index/subcommand-b.rst index 1817a39..af01701 100644 --- a/test/roots/test-command-by-group-index/subcommand-b.rst +++ b/test/roots/test-command-by-group-index/subcommand-b.rst @@ -2,7 +2,7 @@ Command B ========= .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser :path: B diff --git a/test/roots/test-command-index/sample.rst b/test/roots/test-command-index/sample.rst index d7eb90b..190c293 100644 --- a/test/roots/test-command-index/sample.rst +++ b/test/roots/test-command-index/sample.rst @@ -2,6 +2,6 @@ Sample ====== .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser diff --git a/test/roots/test-command-index/subcommand-a.rst b/test/roots/test-command-index/subcommand-a.rst index 4cbbf44..8cc768d 100644 --- a/test/roots/test-command-index/subcommand-a.rst +++ b/test/roots/test-command-index/subcommand-a.rst @@ -2,7 +2,7 @@ Command A ========= .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser :path: A diff --git a/test/roots/test-command-index/subcommand-b.rst b/test/roots/test-command-index/subcommand-b.rst index 53625f2..9d7abe4 100644 --- a/test/roots/test-command-index/subcommand-b.rst +++ b/test/roots/test-command-index/subcommand-b.rst @@ -2,7 +2,7 @@ Command B ========= .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser :path: B diff --git a/test/roots/test-conf-opts-html/index.rst b/test/roots/test-conf-opts-html/index.rst index d7eb90b..190c293 100644 --- a/test/roots/test-conf-opts-html/index.rst +++ b/test/roots/test-conf-opts-html/index.rst @@ -2,6 +2,6 @@ Sample ====== .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser diff --git a/test/roots/test-conf-opts-html/subcommand-a.rst b/test/roots/test-conf-opts-html/subcommand-a.rst index 4cbbf44..8cc768d 100644 --- a/test/roots/test-conf-opts-html/subcommand-a.rst +++ b/test/roots/test-conf-opts-html/subcommand-a.rst @@ -2,7 +2,7 @@ Command A ========= .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser :path: A diff --git a/test/roots/test-default-html/default-suppressed.rst b/test/roots/test-default-html/default-suppressed.rst index a94e8b1..f39bc42 100644 --- a/test/roots/test-default-html/default-suppressed.rst +++ b/test/roots/test-default-html/default-suppressed.rst @@ -2,6 +2,6 @@ Default suppressed ================== .. argparse:: - :filename: test/sample-default-supressed.py + :filename: sample-default-supressed.py :prog: sample-default-suppressed :func: get_parser diff --git a/test/roots/test-default-html/index.rst b/test/roots/test-default-html/index.rst index 636e7f0..5e25646 100644 --- a/test/roots/test-default-html/index.rst +++ b/test/roots/test-default-html/index.rst @@ -2,7 +2,7 @@ Sample ###### .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser diff --git a/test/roots/test-default-html/special-characters.rst b/test/roots/test-default-html/special-characters.rst index ce87bf2..497156e 100644 --- a/test/roots/test-default-html/special-characters.rst +++ b/test/roots/test-default-html/special-characters.rst @@ -2,5 +2,5 @@ Special Characters ================== .. argparse:: - :filename: test/sample-directive-special.py + :filename: sample-directive-special.py :func: get_parser diff --git a/test/roots/test-default-html/subcommand-a.rst b/test/roots/test-default-html/subcommand-a.rst index 4cbbf44..8cc768d 100644 --- a/test/roots/test-default-html/subcommand-a.rst +++ b/test/roots/test-default-html/subcommand-a.rst @@ -2,7 +2,7 @@ Command A ========= .. argparse:: - :filename: test/sample-directive-opts.py + :filename: sample-directive-opts.py :prog: sample-directive-opts :func: get_parser :path: A