diff --git a/docs/source/changes.md b/docs/source/changes.md index 51e38be2..67626f22 100644 --- a/docs/source/changes.md +++ b/docs/source/changes.md @@ -8,6 +8,9 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and ## 0.4.5 - 2023-12-xx - {pull}`515` enables tests with graphviz in CI. Thanks to {user}`NickCrews`. +- {pull}`517` raises an error when the configuration file contains a non-existing path + (fixes #514). Also adds a warning if the path is configured as a string and not a list + of strings. ## 0.4.4 - 2023-12-04 diff --git a/src/_pytask/shared.py b/src/_pytask/shared.py index 4afdc0ff..5fbd167d 100644 --- a/src/_pytask/shared.py +++ b/src/_pytask/shared.py @@ -2,6 +2,7 @@ from __future__ import annotations import glob +import warnings from pathlib import Path from typing import Any from typing import Iterable @@ -46,17 +47,29 @@ def to_list(scalar_or_iter: Any) -> list[Any]: def parse_paths(x: Any | None) -> list[Path] | None: """Parse paths.""" - if x is not None: - paths = [Path(p) for p in to_list(x)] - paths = [ - Path(p).resolve() - for path in paths - for p in glob.glob(path.as_posix()) # noqa: PTH207 - ] - out = paths - else: - out = None - return out + if x is None: + return None + + if isinstance(x, str): + msg = ( + "Specifying paths as a string in 'pyproject.toml' is deprecated and will " + "result in an error in v0.5. Please use a list of strings instead: " + f'["{x}"].' + ) + warnings.warn(msg, category=FutureWarning, stacklevel=1) + x = [x] + + paths = [Path(p) for p in to_list(x)] + for p in paths: + if not p.exists(): + msg = f"The path '{p}' does not exist." + raise FileNotFoundError(msg) + + return [ + Path(p).resolve() + for path in paths + for p in glob.glob(path.as_posix()) # noqa: PTH207 + ] def reduce_names_of_multiple_nodes( diff --git a/tests/test_config.py b/tests/test_config.py index ed45baec..5e7adf29 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -4,6 +4,7 @@ import pytest from pytask import build +from pytask import cli from pytask import ExitCode @@ -59,3 +60,15 @@ def test_passing_paths_via_configuration_file(tmp_path, file_or_folder): assert session.exit_code == ExitCode.OK assert len(session.tasks) == 1 + + +def test_not_existing_path_in_config(runner, tmp_path): + config = """ + [tool.pytask.ini_options] + paths = "not_existing_path" + """ + tmp_path.joinpath("pyproject.toml").write_text(textwrap.dedent(config)) + + with pytest.warns(FutureWarning, match="Specifying paths as a string"): + result = runner.invoke(cli, [tmp_path.as_posix()]) + assert result.exit_code == ExitCode.CONFIGURATION_FAILED