Skip to content

Commit efae907

Browse files
committed
Register profile plugin instance
1 parent ae329df commit efae907

2 files changed

Lines changed: 37 additions & 30 deletions

File tree

src/_pytask/pluginmanager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from pluggy import PluginManager
1212

1313
from _pytask import hookspecs
14+
from _pytask.profile import ProfilePlugin
1415

1516
if TYPE_CHECKING:
1617
from collections.abc import Iterable
@@ -58,12 +59,12 @@ def pytask_add_hooks(pm: PluginManager) -> None:
5859
"_pytask.nodes",
5960
"_pytask.parameters",
6061
"_pytask.persist",
61-
"_pytask.profile",
6262
"_pytask.skipping",
6363
"_pytask.task",
6464
"_pytask.warnings",
6565
)
6666
register_hook_impls_from_modules(pm, builtin_hook_impl_modules)
67+
pm.register(ProfilePlugin())
6768

6869

6970
def get_plugin_manager() -> PluginManager:

src/_pytask/profile.py

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import sys
99
import time
1010
from contextlib import suppress
11+
from dataclasses import dataclass
1112
from typing import TYPE_CHECKING
1213
from typing import Any
1314

@@ -32,6 +33,7 @@
3233
from _pytask.traceback import Traceback
3334

3435
if TYPE_CHECKING:
36+
from collections.abc import Callable
3537
from collections.abc import Generator
3638
from pathlib import Path
3739
from typing import NoReturn
@@ -45,57 +47,61 @@ class _ExportFormats(enum.Enum):
4547
CSV = "csv"
4648

4749

48-
@hookimpl(tryfirst=True)
49-
def pytask_extend_command_line_interface(cli: click.Group) -> None:
50-
"""Extend the command line interface."""
51-
cli.add_command(profile)
52-
53-
54-
@hookimpl
55-
def pytask_post_parse(config: dict[str, Any]) -> None:
56-
"""Register the export option."""
57-
runtime_state = RuntimeState.from_root(config["root"])
58-
config["pm"].register(ProfilePlugin(runtime_state))
59-
config["pm"].register(DurationNameSpace(runtime_state))
60-
config["pm"].register(ExportNameSpace)
61-
config["pm"].register(FileSizeNameSpace)
62-
63-
64-
@hookimpl(wrapper=True)
65-
def pytask_execute_task(task: PTask) -> Generator[None, None, None]:
66-
"""Attach the duration of the execution to the task."""
67-
start = time.time()
68-
result = yield
69-
end = time.time()
70-
task.attributes["duration"] = (start, end)
71-
return result
72-
73-
50+
@dataclass
7451
class ProfilePlugin:
7552
"""Collect and persist runtime profiling data."""
7653

77-
def __init__(self, runtime_state: RuntimeState) -> None:
54+
runtime_state: RuntimeState | None = None
55+
runtime_state_factory: Callable[[Path], RuntimeState] = RuntimeState.from_root
56+
57+
@hookimpl(tryfirst=True)
58+
def pytask_extend_command_line_interface(self, cli: click.Group) -> None:
59+
"""Extend the command line interface."""
60+
cli.add_command(profile)
61+
62+
@hookimpl
63+
def pytask_post_parse(self, config: dict[str, Any]) -> None:
64+
"""Register the export option."""
65+
runtime_state = self.runtime_state_factory(config["root"])
7866
self.runtime_state = runtime_state
67+
config["pm"].register(DurationNameSpace(runtime_state))
68+
config["pm"].register(ExportNameSpace)
69+
config["pm"].register(FileSizeNameSpace)
70+
71+
@hookimpl(wrapper=True)
72+
def pytask_execute_task(self, task: PTask) -> Generator[None, None, None]:
73+
"""Attach the duration of the execution to the task."""
74+
start = time.time()
75+
result = yield
76+
end = time.time()
77+
task.attributes["duration"] = (start, end)
78+
return result
7979

8080
@hookimpl
8181
def pytask_execute_task_process_report(
8282
self, session: Session, report: ExecutionReport
8383
) -> None:
8484
"""Store runtime of successfully finishing tasks."""
8585
_ = session
86+
runtime_state = self.runtime_state
87+
if runtime_state is None:
88+
return
8689
task = report.task
8790
duration = task.attributes.get("duration")
8891
if report.outcome == TaskOutcome.SUCCESS and duration is not None:
89-
self.runtime_state.update_task(task, *duration)
92+
runtime_state.update_task(task, *duration)
9093

9194
@hookimpl
9295
def pytask_unconfigure(self, session: Session) -> None:
9396
"""Flush runtime information on normal build exits."""
97+
runtime_state = self.runtime_state
98+
if runtime_state is None:
99+
return
94100
if session.config.get("command") != "build":
95101
return
96102
if session.config.get("dry_run") or session.config.get("explain"):
97103
return
98-
self.runtime_state.flush()
104+
runtime_state.flush()
99105

100106

101107
class DurationNameSpace:

0 commit comments

Comments
 (0)