diff --git a/CHANGELOG.md b/CHANGELOG.md index 52edc207..3d7de53a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and ## Unreleased +- [#997](https://github.com/pytask-dev/pytask/pull/997) documents how task generators + behave in dry-run and explain modes and adds regression tests for both modes. - [#995](https://github.com/pytask-dev/pytask/pull/995) documents that return values from task generators are ignored and adds a regression test for this behavior. - [#996](https://github.com/pytask-dev/pytask/pull/996) raises collection errors when diff --git a/tests/test_provisional.py b/tests/test_provisional.py index cc26fb91..d9140df1 100644 --- a/tests/test_provisional.py +++ b/tests/test_provisional.py @@ -275,6 +275,41 @@ def task_child(produces=Path("child.txt")): assert "return" not in generator.produces +@pytest.mark.parametrize("mode", ["dry_run", "explain"]) +def test_task_generator_in_simulation_mode(tmp_path, mode): + source = """ + from pathlib import Path + from pytask import task + + @task(is_generator=True) + def task_generator(): + counter = Path(__file__).parent / "counter.txt" + count = int(counter.read_text()) if counter.exists() else 0 + counter.write_text(str(count + 1)) + + @task + def task_generated(produces=Path(__file__).parent / "generated.txt"): + produces.write_text("generated") + """ + tmp_path.joinpath("task_module.py").write_text(textwrap.dedent(source)) + + session = build( + paths=tmp_path, dry_run=mode == "dry_run", explain=mode == "explain" + ) + + outcomes = { + report.task.name.rsplit("::", maxsplit=1)[-1]: report.outcome + for report in session.execution_reports + } + assert session.exit_code == ExitCode.OK + assert outcomes == { + "task_generator": TaskOutcome.WOULD_BE_EXECUTED, + "task_generated": TaskOutcome.WOULD_BE_EXECUTED, + } + assert tmp_path.joinpath("counter.txt").read_text() == "1" + assert not tmp_path.joinpath("generated.txt").exists() + + def test_failed_generated_task_collection_is_atomic(tmp_path): source = """ from pathlib import Path