Skip to content

Commit 2a675fa

Browse files
committed
Add some more tests and make it working.
1 parent 742dd93 commit 2a675fa

File tree

4 files changed

+199
-88
lines changed

4 files changed

+199
-88
lines changed

src/_pytask/execute.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from _pytask.exceptions import ExecutionError
2121
from _pytask.exceptions import NodeNotFoundError
2222
from _pytask.mark import Mark
23+
from _pytask.mark_utils import has_mark
2324
from _pytask.nodes import FilePathNode
2425
from _pytask.nodes import Task
2526
from _pytask.outcomes import count_outcomes
@@ -152,6 +153,10 @@ def pytask_execute_task_setup(session: Session, task: Task) -> None:
152153
if isinstance(node, FilePathNode):
153154
node.path.parent.mkdir(parents=True, exist_ok=True)
154155

156+
would_be_executed = has_mark(task, "would_be_executed")
157+
if would_be_executed:
158+
raise WouldBeExecuted
159+
155160

156161
@hookimpl(trylast=True)
157162
def pytask_execute_task(session: Session, task: Task) -> bool:
@@ -207,6 +212,16 @@ def pytask_execute_task_process_report(
207212
update_states_in_database(session.dag, task.name)
208213
elif report.exc_info and isinstance(report.exc_info[1], WouldBeExecuted):
209214
report.outcome = TaskOutcome.WOULD_BE_EXECUTED
215+
216+
for descending_task_name in descending_tasks(task.name, session.dag):
217+
descending_task = session.dag.nodes[descending_task_name]["task"]
218+
descending_task.markers.append(
219+
Mark(
220+
"would_be_executed",
221+
(),
222+
{"reason": f"Previous task {task.name!r} would be executed."},
223+
)
224+
)
210225
else:
211226
for descending_task_name in descending_tasks(task.name, session.dag):
212227
descending_task = session.dag.nodes[descending_task_name]["task"]

src/_pytask/skipping.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ def pytask_parse_config(config: dict[str, Any]) -> None:
4949
@hookimpl
5050
def pytask_execute_task_setup(task: Task) -> None:
5151
"""Take a short-cut for skipped tasks during setup with an exception."""
52-
is_unchanged = has_mark(task, "skip_unchanged")
52+
is_unchanged = has_mark(task, "skip_unchanged") and not has_mark(
53+
task, "would_be_executed"
54+
)
5355
if is_unchanged:
5456
raise SkippedUnchanged
5557

tests/test_dry_run.py

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
from __future__ import annotations
2+
3+
import textwrap
4+
5+
import pytest
6+
from pytask import cli
7+
from pytask import ExitCode
8+
9+
10+
@pytest.mark.end_to_end
11+
def test_dry_run(runner, tmp_path):
12+
source = """
13+
import pytask
14+
15+
@pytask.mark.produces("out.txt")
16+
def task_example(produces):
17+
produces.touch()
18+
"""
19+
tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source))
20+
21+
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
22+
23+
assert result.exit_code == ExitCode.OK
24+
assert "1 Would be executed" in result.output
25+
assert not tmp_path.joinpath("out.txt").exists()
26+
27+
28+
@pytest.mark.end_to_end
29+
def test_dry_run_w_subsequent_task(runner, tmp_path):
30+
source = """
31+
import pytask
32+
33+
@pytask.mark.depends_on("out.txt")
34+
@pytask.mark.produces("out_2.txt")
35+
def task_example(produces):
36+
produces.touch()
37+
"""
38+
tmp_path.joinpath("task_example_second.py").write_text(textwrap.dedent(source))
39+
40+
source = """
41+
import pytask
42+
43+
@pytask.mark.produces("out.txt")
44+
def task_example(produces):
45+
produces.touch()
46+
"""
47+
tmp_path.joinpath("task_example_first.py").write_text(textwrap.dedent(source))
48+
49+
result = runner.invoke(cli, [tmp_path.as_posix()])
50+
51+
assert result.exit_code == ExitCode.OK
52+
assert "2 Succeeded" in result.output
53+
54+
tmp_path.joinpath("task_example_first.py").write_text(textwrap.dedent(source))
55+
56+
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
57+
58+
assert result.exit_code == ExitCode.OK
59+
assert "2 Would be executed" in result.output
60+
61+
62+
@pytest.mark.end_to_end
63+
def test_dry_run_w_subsequent_skipped_task(runner, tmp_path):
64+
source = """
65+
import pytask
66+
67+
@pytask.mark.produces("out.txt")
68+
def task_example(produces):
69+
produces.touch()
70+
"""
71+
tmp_path.joinpath("task_example_first.py").write_text(textwrap.dedent(source))
72+
73+
source = """
74+
import pytask
75+
76+
@pytask.mark.depends_on("out.txt")
77+
@pytask.mark.produces("out_2.txt")
78+
def task_example(produces):
79+
produces.touch()
80+
"""
81+
tmp_path.joinpath("task_example_second.py").write_text(textwrap.dedent(source))
82+
83+
result = runner.invoke(cli, [tmp_path.as_posix()])
84+
85+
assert result.exit_code == ExitCode.OK
86+
assert "2 Succeeded" in result.output
87+
88+
source = """
89+
import pytask
90+
91+
@pytask.mark.produces("out.txt")
92+
def task_example(produces):
93+
produces.touch()
94+
"""
95+
tmp_path.joinpath("task_example_first.py").write_text(textwrap.dedent(source))
96+
97+
source = """
98+
import pytask
99+
100+
@pytask.mark.skip
101+
@pytask.mark.depends_on("out.txt")
102+
@pytask.mark.produces("out_2.txt")
103+
def task_example(produces):
104+
produces.touch()
105+
"""
106+
tmp_path.joinpath("task_example_second.py").write_text(textwrap.dedent(source))
107+
108+
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
109+
110+
assert result.exit_code == ExitCode.OK
111+
assert "1 Would be executed" in result.output
112+
assert "1 Skipped" in result.output
113+
114+
115+
@pytest.mark.end_to_end
116+
def test_dry_run_skip(runner, tmp_path):
117+
source = """
118+
import pytask
119+
120+
@pytask.mark.skip
121+
def task_example_skip(): ...
122+
123+
@pytask.mark.produces("out.txt")
124+
def task_example(produces):
125+
produces.touch()
126+
"""
127+
tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source))
128+
129+
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
130+
131+
assert result.exit_code == ExitCode.OK
132+
assert "1 Would be executed" in result.output
133+
assert "1 Skipped" in result.output
134+
assert not tmp_path.joinpath("out.txt").exists()
135+
136+
137+
@pytest.mark.end_to_end
138+
def test_dry_run_skipped_successul(runner, tmp_path):
139+
source = """
140+
import pytask
141+
142+
@pytask.mark.produces("out.txt")
143+
def task_example(produces):
144+
produces.touch()
145+
"""
146+
tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source))
147+
148+
result = runner.invoke(cli, [tmp_path.as_posix()])
149+
150+
assert result.exit_code == ExitCode.OK
151+
assert "1 Succeeded" in result.output
152+
153+
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
154+
155+
assert result.exit_code == ExitCode.OK
156+
assert "1 Skipped because unchanged" in result.output
157+
158+
159+
@pytest.mark.end_to_end
160+
def test_dry_run_persisted(runner, tmp_path):
161+
source = """
162+
import pytask
163+
164+
@pytask.mark.persist
165+
@pytask.mark.produces("out.txt")
166+
def task_example(produces):
167+
produces.touch()
168+
"""
169+
tmp_path.joinpath("task_example.py").write_text(textwrap.dedent(source))
170+
171+
result = runner.invoke(cli, [tmp_path.as_posix()])
172+
173+
assert result.exit_code == ExitCode.OK
174+
assert "1 Succeeded" in result.output
175+
176+
tmp_path.joinpath("out.txt").write_text("Changed text file.")
177+
178+
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
179+
180+
assert result.exit_code == ExitCode.OK
181+
assert "1 Persisted" in result.output

tests/test_execute.py

Lines changed: 0 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -349,90 +349,3 @@ def task_second(): pass
349349
assert ("Task task_example.py::task_second failed" in result.output) is (
350350
verbose == 2
351351
)
352-
353-
354-
@pytest.mark.end_to_end
355-
def test_dry_run(runner, tmp_path):
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))
385-
386-
result = runner.invoke(cli, ["--dry-run", tmp_path.as_posix()])
387-
388-
assert result.exit_code == ExitCode.OK
389-
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)