From a1b63f659952bf90fe49364ec480a3187be16e80 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Fri, 8 Mar 2024 21:13:49 +0100 Subject: [PATCH 1/5] Improve handling of task_files. --- docs/source/changes.md | 1 + docs/source/reference_guides/configuration.md | 2 +- pyproject.toml | 3 +++ src/_pytask/build.py | 2 +- src/_pytask/config.py | 7 +++++- tests/test_collect.py | 22 ++++++++++++++----- 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/docs/source/changes.md b/docs/source/changes.md index ab7a8e23..13fb80e4 100644 --- a/docs/source/changes.md +++ b/docs/source/changes.md @@ -18,6 +18,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and - {pull}`555` uses new-style hook wrappers and requires pluggy 1.3 for typing. - {pull}`557` fixes an issue with `@task(after=...)` in notebooks and terminals. - {pull}`566` makes universal-pathlib an official dependency. +- {pull}`567` restricts `task_files` to a list of patterns and raises a better error. ## 0.4.5 - 2024-01-09 diff --git a/docs/source/reference_guides/configuration.md b/docs/source/reference_guides/configuration.md index 9564298f..da8ece2b 100644 --- a/docs/source/reference_guides/configuration.md +++ b/docs/source/reference_guides/configuration.md @@ -242,7 +242,7 @@ strict_markers = true Change the pattern which identify task files. ```toml -task_files = "task_*.py" # default +task_files = ["task_*.py"] # default task_files = ["task_*.py", "tasks_*.py"] ``` diff --git a/pyproject.toml b/pyproject.toml index 9a0ef132..64881f75 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -209,3 +209,6 @@ exclude_also = [ [tool.mdformat] wrap = 88 end_of_line = "keep" + +[tool.pytask.ini_options] +task_files = "askds.py" diff --git a/src/_pytask/build.py b/src/_pytask/build.py index fe0c2c1e..e8f1abf6 100644 --- a/src/_pytask/build.py +++ b/src/_pytask/build.py @@ -95,7 +95,7 @@ def build( # noqa: C901, PLR0912, PLR0913, PLR0915 stop_after_first_failure: bool = False, strict_markers: bool = False, tasks: Callable[..., Any] | PTask | Iterable[Callable[..., Any] | PTask] = (), - task_files: str | Iterable[str] = "task_*.py", + task_files: Iterable[str] = ["task_*.py"], trace: bool = False, verbose: int = 1, **kwargs: Any, diff --git a/src/_pytask/config.py b/src/_pytask/config.py index ac4775da..c9a07a3e 100644 --- a/src/_pytask/config.py +++ b/src/_pytask/config.py @@ -92,7 +92,12 @@ def pytask_parse_config(config: dict[str, Any]) -> None: + IGNORED_TEMPORARY_FILES_AND_FOLDERS ) - config["task_files"] = to_list(config.get("task_files", "task_*.py")) + config["task_files"] = config.get("task_files", ["task_*.py"]) + if not isinstance(config["task_files"], list) or not all( + isinstance(p, str) for p in config["task_files"] + ): + msg = "'task_files' must be a list of patterns." + raise ValueError(msg) if config["stop_after_first_failure"]: config["max_failures"] = 1 diff --git a/tests/test_collect.py b/tests/test_collect.py index 5ef6f6c0..a8008aca 100644 --- a/tests/test_collect.py +++ b/tests/test_collect.py @@ -103,10 +103,10 @@ def test_collect_same_task_different_ways(tmp_path, path_extension): @pytest.mark.parametrize( ("task_files", "pattern", "expected_collected_tasks"), [ - (["example_task.py"], "'*_task.py'", 1), - (["tasks_example.py"], "'tasks_*'", 1), - (["example_tasks.py"], "'*_tasks.py'", 1), - (["task_module.py", "tasks_example.py"], "'tasks_*.py'", 1), + (["example_task.py"], "['*_task.py']", 1), + (["tasks_example.py"], "['tasks_*']", 1), + (["example_tasks.py"], "['*_tasks.py']", 1), + (["task_module.py", "tasks_example.py"], "['tasks_*.py']", 1), (["task_module.py", "tasks_example.py"], "['task_*.py', 'tasks_*.py']", 2), ], ) @@ -117,8 +117,8 @@ def test_collect_files_w_custom_file_name_pattern( f"[tool.pytask.ini_options]\ntask_files = {pattern}" ) - for file in task_files: - tmp_path.joinpath(file).write_text("def task_example(): pass") + for file_ in task_files: + tmp_path.joinpath(file_).write_text("def task_example(): pass") session = build(paths=tmp_path) @@ -126,6 +126,16 @@ def test_collect_files_w_custom_file_name_pattern( assert len(session.tasks) == expected_collected_tasks +def test_error_with_invalid_file_name_pattern(runner, tmp_path): + tmp_path.joinpath("pyproject.toml").write_text( + "[tool.pytask.ini_options]\ntask_files = 'asds'" + ) + + result = runner.invoke(cli, [tmp_path.as_posix()]) + assert result.exit_code == ExitCode.CONFIGURATION_FAILED + assert "'task_files' must be a list of patterns." in result.output + + @pytest.mark.unit() @pytest.mark.parametrize( ("session", "path", "node_info", "expected"), From b013179e801e50aa3358a3ce724fd0587dd29bce Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Fri, 8 Mar 2024 21:18:06 +0100 Subject: [PATCH 2/5] Add test with session. --- tests/test_collect.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_collect.py b/tests/test_collect.py index a8008aca..d6f3c139 100644 --- a/tests/test_collect.py +++ b/tests/test_collect.py @@ -136,6 +136,11 @@ def test_error_with_invalid_file_name_pattern(runner, tmp_path): assert "'task_files' must be a list of patterns." in result.output +def test_error_with_invalid_file_name_pattern_(tmp_path): + session = build(paths=tmp_path, task_files=[1]) + assert session.exit_code == ExitCode.CONFIGURATION_FAILED + + @pytest.mark.unit() @pytest.mark.parametrize( ("session", "path", "node_info", "expected"), From 0a3ccb61c9de6bea1e771b00db0bf546641eaa79 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Fri, 8 Mar 2024 21:19:25 +0100 Subject: [PATCH 3/5] Fix. --- docs/source/changes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/changes.md b/docs/source/changes.md index 13fb80e4..7f826fec 100644 --- a/docs/source/changes.md +++ b/docs/source/changes.md @@ -18,7 +18,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and - {pull}`555` uses new-style hook wrappers and requires pluggy 1.3 for typing. - {pull}`557` fixes an issue with `@task(after=...)` in notebooks and terminals. - {pull}`566` makes universal-pathlib an official dependency. -- {pull}`567` restricts `task_files` to a list of patterns and raises a better error. +- {pull}`568` restricts `task_files` to a list of patterns and raises a better error. ## 0.4.5 - 2024-01-09 From 0204572b36486a3d0ec3ada7d86c895034a979b4 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Fri, 8 Mar 2024 21:49:33 +0100 Subject: [PATCH 4/5] fix. --- src/_pytask/build.py | 2 +- src/_pytask/config.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/_pytask/build.py b/src/_pytask/build.py index e8f1abf6..5c598705 100644 --- a/src/_pytask/build.py +++ b/src/_pytask/build.py @@ -95,7 +95,7 @@ def build( # noqa: C901, PLR0912, PLR0913, PLR0915 stop_after_first_failure: bool = False, strict_markers: bool = False, tasks: Callable[..., Any] | PTask | Iterable[Callable[..., Any] | PTask] = (), - task_files: Iterable[str] = ["task_*.py"], + task_files: Iterable[str] = ("task_*.py",), trace: bool = False, verbose: int = 1, **kwargs: Any, diff --git a/src/_pytask/config.py b/src/_pytask/config.py index c9a07a3e..86423ac3 100644 --- a/src/_pytask/config.py +++ b/src/_pytask/config.py @@ -92,12 +92,13 @@ def pytask_parse_config(config: dict[str, Any]) -> None: + IGNORED_TEMPORARY_FILES_AND_FOLDERS ) - config["task_files"] = config.get("task_files", ["task_*.py"]) - if not isinstance(config["task_files"], list) or not all( - isinstance(p, str) for p in config["task_files"] + value = config.get("task_files", ["task_*.py"]) + if not isinstance(value, (list, tuple)) or not all( + isinstance(p, str) for p in value ): msg = "'task_files' must be a list of patterns." raise ValueError(msg) + config["task_files"] = value if config["stop_after_first_failure"]: config["max_failures"] = 1 From 9bf95291867279a9a3554e0db5000280d2c8d1da Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Fri, 8 Mar 2024 21:50:25 +0100 Subject: [PATCH 5/5] Fix. --- pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 64881f75..9a0ef132 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -209,6 +209,3 @@ exclude_also = [ [tool.mdformat] wrap = 88 end_of_line = "keep" - -[tool.pytask.ini_options] -task_files = "askds.py"