Skip to content

Commit 9b27ec5

Browse files
authored
Remove hooks related to the DAG. (#569)
1 parent 2dfb0f7 commit 9b27ec5

File tree

10 files changed

+30
-92
lines changed

10 files changed

+30
-92
lines changed

docs/source/changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and
1919
- {pull}`557` fixes an issue with `@task(after=...)` in notebooks and terminals.
2020
- {pull}`566` makes universal-pathlib an official dependency.
2121
- {pull}`568` restricts `task_files` to a list of patterns and raises a better error.
22+
- {pull}`569` removes the hooks related to the creation of the DAG.
2223

2324
## 0.4.5 - 2024-01-09
2425

docs/source/reference_guides/hookspecs.md

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,6 @@ The following hooks traverse directories and collect tasks from files.
6262
.. autofunction:: pytask_collect_log
6363
```
6464

65-
## Resolving Dependencies
66-
67-
The following hooks are designed to build a DAG from tasks and dependencies and check
68-
which files have changed and need to be re-run.
69-
70-
```{warning}
71-
This step is still experimental and likely to change in the future. If you are planning
72-
to write a plugin which extends pytask in this dimension, please, start a discussion
73-
before writing a plugin. It may make your life easier if changes in pytask anticipate
74-
your plugin.
75-
```
76-
77-
```{eval-rst}
78-
.. autofunction:: pytask_dag
79-
.. autofunction:: pytask_dag_create_dag
80-
.. autofunction:: pytask_dag_log
81-
82-
```
83-
8465
## Execution
8566

8667
The following hooks execute the tasks and log information on the result in the terminal.

src/_pytask/build.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from _pytask.config_utils import find_project_root_and_config
2222
from _pytask.config_utils import read_config
2323
from _pytask.console import console
24+
from _pytask.dag import create_dag
2425
from _pytask.exceptions import CollectionError
2526
from _pytask.exceptions import ConfigurationError
2627
from _pytask.exceptions import ExecutionError
@@ -265,7 +266,7 @@ def build( # noqa: C901, PLR0912, PLR0913, PLR0915
265266
try:
266267
session.hook.pytask_log_session_header(session=session)
267268
session.hook.pytask_collect(session=session)
268-
session.hook.pytask_dag(session=session)
269+
session.dag = create_dag(session=session)
269270
session.hook.pytask_execute(session=session)
270271

271272
except CollectionError:

src/_pytask/collect_command.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from _pytask.console import create_url_style_for_path
2020
from _pytask.console import format_node_name
2121
from _pytask.console import format_task_name
22+
from _pytask.dag import create_dag
2223
from _pytask.exceptions import CollectionError
2324
from _pytask.exceptions import ConfigurationError
2425
from _pytask.exceptions import ResolvingDependenciesError
@@ -70,7 +71,7 @@ def collect(**raw_config: Any | None) -> NoReturn:
7071
try:
7172
session.hook.pytask_log_session_header(session=session)
7273
session.hook.pytask_collect(session=session)
73-
session.hook.pytask_dag(session=session)
74+
session.dag = create_dag(session=session)
7475

7576
tasks = _select_tasks_by_expressions_and_marker(session)
7677
task_with_path = [t for t in tasks if isinstance(t, PTaskWithPath)]

src/_pytask/dag.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
from _pytask.console import render_to_string
2020
from _pytask.exceptions import ResolvingDependenciesError
2121
from _pytask.mark import select_by_after_keyword
22+
from _pytask.mark import select_tasks_by_marks_and_expressions
2223
from _pytask.node_protocols import PNode
2324
from _pytask.node_protocols import PTask
2425
from _pytask.nodes import PythonNode
25-
from _pytask.pluginmanager import hookimpl
2626
from _pytask.reports import DagReport
2727
from _pytask.shared import reduce_names_of_multiple_nodes
2828
from _pytask.tree_util import tree_map
@@ -33,28 +33,28 @@
3333
from _pytask.session import Session
3434

3535

36-
@hookimpl
37-
def pytask_dag(session: Session) -> bool | None:
36+
__all__ = ["create_dag"]
37+
38+
39+
def create_dag(session: Session) -> nx.DiGraph:
3840
"""Create a directed acyclic graph (DAG) for the workflow."""
3941
try:
40-
session.dag = session.hook.pytask_dag_create_dag(
41-
session=session, tasks=session.tasks
42-
)
43-
session.hook.pytask_dag_modify_dag(session=session, dag=session.dag)
42+
dag = _create_dag(tasks=session.tasks)
43+
_check_if_dag_has_cycles(dag)
44+
_check_if_tasks_have_the_same_products(dag, session.config["paths"])
45+
_modify_dag(session=session, dag=dag)
46+
select_tasks_by_marks_and_expressions(session=session, dag=dag)
4447

4548
except Exception: # noqa: BLE001
4649
report = DagReport.from_exception(sys.exc_info())
47-
session.hook.pytask_dag_log(session=session, report=report)
50+
_log_dag(report=report)
4851
session.dag_report = report
4952

5053
raise ResolvingDependenciesError from None
51-
52-
else:
53-
return True
54+
return dag
5455

5556

56-
@hookimpl
57-
def pytask_dag_create_dag(session: Session, tasks: list[PTask]) -> nx.DiGraph:
57+
def _create_dag(tasks: list[PTask]) -> nx.DiGraph:
5858
"""Create the DAG from tasks, dependencies and products."""
5959

6060
def _add_dependency(dag: nx.DiGraph, task: PTask, node: PNode) -> None:
@@ -90,15 +90,10 @@ def _add_product(dag: nx.DiGraph, task: PTask, node: PNode) -> None:
9090
else None,
9191
task.depends_on,
9292
)
93-
94-
_check_if_dag_has_cycles(dag)
95-
_check_if_tasks_have_the_same_products(dag, session.config["paths"])
96-
9793
return dag
9894

9995

100-
@hookimpl
101-
def pytask_dag_modify_dag(session: Session, dag: nx.DiGraph) -> None:
96+
def _modify_dag(session: Session, dag: nx.DiGraph) -> None:
10297
"""Create dependencies between tasks when using ``@task(after=...)``."""
10398
temporary_id_to_task = {
10499
task.attributes["collection_id"]: task
@@ -194,8 +189,7 @@ def _check_if_tasks_have_the_same_products(dag: nx.DiGraph, paths: list[Path]) -
194189
raise ResolvingDependenciesError(msg)
195190

196191

197-
@hookimpl
198-
def pytask_dag_log(report: DagReport) -> None:
192+
def _log_dag(report: DagReport) -> None:
199193
"""Log errors which happened while resolving dependencies."""
200194
console.print()
201195
console.rule(

src/_pytask/dag_command.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from _pytask.config_utils import find_project_root_and_config
2020
from _pytask.config_utils import read_config
2121
from _pytask.console import console
22+
from _pytask.dag import create_dag
2223
from _pytask.exceptions import CollectionError
2324
from _pytask.exceptions import ConfigurationError
2425
from _pytask.exceptions import ResolvingDependenciesError
@@ -101,7 +102,7 @@ def dag(**raw_config: Any) -> int:
101102
"can install with conda.",
102103
)
103104
session.hook.pytask_collect(session=session)
104-
session.hook.pytask_dag(session=session)
105+
session.dag = create_dag(session=session)
105106
dag = _refine_dag(session)
106107
_write_graph(dag, session.config["output_path"], session.config["layout"])
107108

@@ -198,7 +199,7 @@ def build_dag(raw_config: dict[str, Any]) -> nx.DiGraph:
198199
"can install with conda.",
199200
)
200201
session.hook.pytask_collect(session=session)
201-
session.hook.pytask_dag(session=session)
202+
session.dag = create_dag(session=session)
202203
session.hook.pytask_unconfigure(session=session)
203204
dag = _refine_dag(session)
204205

src/_pytask/hookspecs.py

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from pathlib import Path
1717

1818
import click
19-
import networkx as nx
2019
from pluggy import PluginManager
2120

2221
from _pytask.models import NodeInfo
@@ -25,7 +24,6 @@
2524
from _pytask.outcomes import CollectionOutcome
2625
from _pytask.outcomes import TaskOutcome
2726
from _pytask.reports import CollectionReport
28-
from _pytask.reports import DagReport
2927
from _pytask.reports import ExecutionReport
3028
from _pytask.session import Session
3129

@@ -212,44 +210,6 @@ def pytask_collect_log(
212210
"""
213211

214212

215-
# Hooks for resolving dependencies.
216-
217-
218-
@hookspec(firstresult=True)
219-
def pytask_dag(session: Session) -> None:
220-
"""Create a DAG.
221-
222-
The main hook implementation which controls the resolution of dependencies and calls
223-
subordinated hooks.
224-
225-
"""
226-
227-
228-
@hookspec(firstresult=True)
229-
def pytask_dag_create_dag(session: Session, tasks: list[PTask]) -> nx.DiGraph:
230-
"""Create the DAG.
231-
232-
This hook creates the DAG from tasks, dependencies and products. The DAG can be used
233-
by a scheduler to find an execution order.
234-
235-
"""
236-
237-
238-
@hookspec
239-
def pytask_dag_modify_dag(session: Session, dag: nx.DiGraph) -> None:
240-
"""Modify the DAG.
241-
242-
This hook allows to make some changes to the DAG before it is validated and tasks
243-
are selected.
244-
245-
"""
246-
247-
248-
@hookspec
249-
def pytask_dag_log(session: Session, report: DagReport) -> None:
250-
"""Log errors during resolving dependencies."""
251-
252-
253213
# Hooks for running tasks.
254214

255215

src/_pytask/mark/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"select_by_after_keyword",
4646
"select_by_keyword",
4747
"select_by_mark",
48+
"select_tasks_by_marks_and_expressions",
4849
]
4950

5051

@@ -234,8 +235,7 @@ def _deselect_others_with_mark(
234235
task.markers.append(mark)
235236

236237

237-
@hookimpl
238-
def pytask_dag_modify_dag(session: Session, dag: nx.DiGraph) -> None:
238+
def select_tasks_by_marks_and_expressions(session: Session, dag: nx.DiGraph) -> None:
239239
"""Modify the tasks which are executed with expressions and markers."""
240240
remaining = select_by_keyword(session, dag)
241241
if remaining is not None:

src/_pytask/profile.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from _pytask.click import EnumChoice
2222
from _pytask.console import console
2323
from _pytask.console import format_task_name
24+
from _pytask.dag import create_dag
2425
from _pytask.database_utils import BaseTable
2526
from _pytask.database_utils import DatabaseSession
2627
from _pytask.exceptions import CollectionError
@@ -128,7 +129,7 @@ def profile(**raw_config: Any) -> NoReturn:
128129
try:
129130
session.hook.pytask_log_session_header(session=session)
130131
session.hook.pytask_collect(session=session)
131-
session.hook.pytask_dag(session=session)
132+
session.dag = create_dag(session=session)
132133

133134
profile: dict[str, dict[str, Any]] = {
134135
task.name: {} for task in session.tasks

tests/test_dag.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,17 @@
55
from pathlib import Path
66

77
import pytest
8-
from _pytask.dag import pytask_dag_create_dag
8+
from _pytask.dag import _create_dag
99
from pytask import ExitCode
1010
from pytask import PathNode
11-
from pytask import Session
1211
from pytask import Task
1312
from pytask import build
1413
from pytask import cli
1514

1615

1716
@pytest.mark.unit()
1817
@pytest.mark.skipif(sys.platform == "win32", reason="Hashes match only on unix.")
19-
def test_pytask_dag_create_dag():
18+
def test_create_dag():
2019
root = Path("src")
2120
task = Task(
2221
base_name="task_dummy",
@@ -27,8 +26,7 @@ def test_pytask_dag_create_dag():
2726
1: PathNode.from_path(root / "node_2"),
2827
},
2928
)
30-
session = Session.from_config({"paths": (root,)})
31-
dag = pytask_dag_create_dag(session=session, tasks=[task])
29+
dag = _create_dag(tasks=[task])
3230

3331
for signature in (
3432
"90bb899a1b60da28ff70352cfb9f34a8bed485597c7f40eed9bd4c6449147525",

0 commit comments

Comments
 (0)