Skip to content

Commit 52619d8

Browse files
committed
Make it pass and add more tests.
1 parent 6c6abdb commit 52619d8

File tree

3 files changed

+96
-10
lines changed

3 files changed

+96
-10
lines changed

src/_pytask/execute.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from _pytask.outcomes import count_outcomes
2626
from _pytask.outcomes import Exit
2727
from _pytask.outcomes import TaskOutcome
28+
from _pytask.outcomes import WouldBeExecuted
2829
from _pytask.report import ExecutionReport
2930
from _pytask.session import Session
3031
from _pytask.shared import get_first_non_none_value
@@ -153,17 +154,20 @@ def pytask_execute_task_setup(session: Session, task: Task) -> None:
153154

154155

155156
@hookimpl(trylast=True)
156-
def pytask_execute_task(task: Task) -> bool:
157+
def pytask_execute_task(session: Session, task: Task) -> bool:
157158
"""Execute task."""
158-
kwargs = {**task.kwargs}
159+
if session.config["dry_run"]:
160+
raise WouldBeExecuted()
161+
else:
162+
kwargs = {**task.kwargs}
159163

160-
func_arg_names = set(inspect.signature(task.function).parameters)
161-
for arg_name in ("depends_on", "produces"):
162-
if arg_name in func_arg_names:
163-
attribute = getattr(task, arg_name)
164-
kwargs[arg_name] = tree_map(lambda x: x.value, attribute)
164+
func_arg_names = set(inspect.signature(task.function).parameters)
165+
for arg_name in ("depends_on", "produces"):
166+
if arg_name in func_arg_names:
167+
attribute = getattr(task, arg_name)
168+
kwargs[arg_name] = tree_map(lambda x: x.value, attribute)
165169

166-
task.execute(**kwargs)
170+
task.execute(**kwargs)
167171
return True
168172

169173

@@ -201,6 +205,8 @@ def pytask_execute_task_process_report(
201205
task = report.task
202206
if report.outcome == TaskOutcome.SUCCESS:
203207
update_states_in_database(session.dag, task.name)
208+
elif report.exc_info and isinstance(report.exc_info[1], WouldBeExecuted):
209+
report.outcome = TaskOutcome.WOULD_BE_EXECUTED
204210
else:
205211
for descending_task_name in descending_tasks(task.name, session.dag):
206212
descending_task = session.dag.nodes[descending_task_name]["task"]

src/_pytask/outcomes.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ def symbol(self) -> str:
115115
TaskOutcome.SKIP: "s",
116116
TaskOutcome.SKIP_PREVIOUS_FAILED: "F",
117117
TaskOutcome.FAIL: "F",
118+
TaskOutcome.WOULD_BE_EXECUTED: "w",
118119
}
119120
assert len(symbols) == len(TaskOutcome)
120121
return symbols[self]
@@ -129,6 +130,7 @@ def description(self) -> str:
129130
TaskOutcome.SKIP: "Skipped",
130131
TaskOutcome.SKIP_PREVIOUS_FAILED: "Skipped because previous failed",
131132
TaskOutcome.FAIL: "Failed",
133+
TaskOutcome.WOULD_BE_EXECUTED: "Would be executed",
132134
}
133135
assert len(descriptions) == len(TaskOutcome)
134136
return descriptions[self]
@@ -143,6 +145,7 @@ def style(self) -> str:
143145
TaskOutcome.SKIP: "skipped",
144146
TaskOutcome.SKIP_PREVIOUS_FAILED: "failed",
145147
TaskOutcome.FAIL: "failed",
148+
TaskOutcome.WOULD_BE_EXECUTED: "success",
146149
}
147150
assert len(styles) == len(TaskOutcome)
148151
return styles[self]
@@ -157,6 +160,7 @@ def style_textonly(self) -> str:
157160
TaskOutcome.SKIP: "skipped.textonly",
158161
TaskOutcome.SKIP_PREVIOUS_FAILED: "failed.textonly",
159162
TaskOutcome.FAIL: "failed.textonly",
163+
TaskOutcome.WOULD_BE_EXECUTED: "success.textonly",
160164
}
161165
assert len(styles_textonly) == len(TaskOutcome)
162166
return styles_textonly[self]

tests/test_execute.py

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,86 @@ def task_second(): pass
353353

354354
@pytest.mark.end_to_end
355355
def test_dry_run(runner, tmp_path):
356-
tmp_path.joinpath("task_example.py").write_text("def task_example(): ...")
356+
source = """
357+
import pytask
358+
359+
@pytask.mark.produces("out.txt")
360+
def task_example(produces):
361+
produces.touch()
362+
"""
363+
tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source))
364+
365+
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
366+
367+
assert result.exit_code == ExitCode.OK
368+
assert "1 Would be executed" in result.output
369+
assert not tmp_path.joinpath("out.txt").exists()
370+
371+
372+
@pytest.mark.end_to_end
373+
def test_dry_run_skip(runner, tmp_path):
374+
source = """
375+
import pytask
376+
377+
@pytask.mark.skip
378+
def task_example_skip(): ...
379+
380+
@pytask.mark.produces("out.txt")
381+
def task_example(produces):
382+
produces.touch()
383+
"""
384+
tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source))
357385

358386
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
359387

360-
print(result.output)
361388
assert result.exit_code == ExitCode.OK
362389
assert "1 Would be executed" in result.output
390+
assert "1 Skipped" in result.output
391+
assert not tmp_path.joinpath("out.txt").exists()
392+
393+
394+
@pytest.mark.end_to_end
395+
def test_dry_run_skipped_successul(runner, tmp_path):
396+
source = """
397+
import pytask
398+
399+
@pytask.mark.produces("out.txt")
400+
def task_example(produces):
401+
produces.touch()
402+
"""
403+
tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source))
404+
405+
result = runner.invoke(cli, [tmp_path.as_posix()])
406+
407+
assert result.exit_code == ExitCode.OK
408+
assert "1 Succeeded" in result.output
409+
410+
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
411+
412+
assert result.exit_code == ExitCode.OK
413+
assert "1 Skipped because unchanged" in result.output
414+
415+
416+
@pytest.mark.end_to_end
417+
def test_dry_run_persisted(runner, tmp_path):
418+
source = """
419+
import pytask
420+
421+
@pytask.mark.persist
422+
@pytask.mark.produces("out.txt")
423+
def task_example(produces):
424+
produces.touch()
425+
"""
426+
tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source))
427+
428+
result = runner.invoke(cli, [tmp_path.as_posix()])
429+
430+
assert result.exit_code == ExitCode.OK
431+
assert "1 Succeeded" in result.output
432+
433+
tmp_path.joinpath("out.txt").write_text("Changed text file.")
434+
435+
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
436+
437+
assert result.exit_code == ExitCode.OK
438+
assert "1 Persisted" in result.output

0 commit comments

Comments
 (0)