Skip to content

Commit df7dc73

Browse files
committed
commit with hidden circular import error.
1 parent c83300d commit df7dc73

File tree

14 files changed

+46
-40
lines changed

14 files changed

+46
-40
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Homepage = "https://pytask-dev.readthedocs.io/en/stable"
8787
Tracker = "https://github.com/pytask-dev/pytask/issues"
8888

8989
[project.scripts]
90-
pytask = "_pytask.cli:cli"
90+
pytask = "pytask:cli"
9191

9292
[tool.setuptools]
9393
include-package-data = true

src/_pytask/build.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
from _pytask.exceptions import ResolvingDependenciesError
2525
from _pytask.outcomes import ExitCode
2626
from _pytask.path import HashPathCache
27-
from _pytask.pluginmanager import get_plugin_manager
2827
from _pytask.pluginmanager import hookimpl
28+
from _pytask.pluginmanager import plugin_manager as pm
2929
from _pytask.session import Session
3030
from _pytask.shared import parse_paths
3131
from _pytask.shared import to_list
@@ -177,8 +177,6 @@ def build( # noqa: C901, PLR0912, PLR0913
177177
178178
"""
179179
try:
180-
pm = get_plugin_manager()
181-
182180
raw_config = {
183181
"capture": capture,
184182
"check_casing_of_paths": check_casing_of_paths,

src/_pytask/clean.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
from _pytask.outcomes import ExitCode
2626
from _pytask.path import find_common_ancestor
2727
from _pytask.path import relative_to
28-
from _pytask.pluginmanager import get_plugin_manager
2928
from _pytask.pluginmanager import hookimpl
29+
from _pytask.pluginmanager import plugin_manager as pm
3030
from _pytask.session import Session
3131
from _pytask.shared import to_list
3232
from _pytask.traceback import Traceback
@@ -101,7 +101,6 @@ def clean(**raw_config: Any) -> NoReturn: # noqa: C901, PLR0912
101101

102102
try:
103103
# Duplication of the same mechanism in :func:`pytask.build`.
104-
pm = get_plugin_manager()
105104

106105
config = pm.hook.pytask_configure(pm=pm, raw_config=raw_config)
107106
session = Session.from_config(config)

src/_pytask/cli.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import click
77
from _pytask.click import ColoredGroup
8-
from _pytask.pluginmanager import get_plugin_manager
8+
from _pytask.pluginmanager import plugin_manager as pm
99
from packaging.version import parse as parse_version
1010

1111

@@ -23,7 +23,6 @@
2323

2424
def _extend_command_line_interface(cli: click.Group) -> click.Group:
2525
"""Add parameters from plugins to the commandline interface."""
26-
pm = get_plugin_manager()
2726
pm.hook.pytask_extend_command_line_interface.call_historic(kwargs={"cli": cli})
2827
_sort_options_for_each_command_alphabetically(cli)
2928
return cli

src/_pytask/collect_command.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
from _pytask.outcomes import ExitCode
2727
from _pytask.path import find_common_ancestor
2828
from _pytask.path import relative_to
29-
from _pytask.pluginmanager import get_plugin_manager
3029
from _pytask.pluginmanager import hookimpl
30+
from _pytask.pluginmanager import plugin_manager as pm
3131
from _pytask.session import Session
3232
from _pytask.tree_util import tree_leaves
3333
from rich.text import Text
@@ -57,7 +57,6 @@ def collect(**raw_config: Any | None) -> NoReturn:
5757
raw_config["command"] = "collect"
5858

5959
try:
60-
pm = get_plugin_manager()
6160
config = pm.hook.pytask_configure(pm=pm, raw_config=raw_config)
6261
session = Session.from_config(config)
6362

src/_pytask/dag_command.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
from _pytask.exceptions import ConfigurationError
2020
from _pytask.exceptions import ResolvingDependenciesError
2121
from _pytask.outcomes import ExitCode
22-
from _pytask.pluginmanager import get_plugin_manager
2322
from _pytask.pluginmanager import hookimpl
23+
from _pytask.pluginmanager import plugin_manager as pm
2424
from _pytask.session import Session
2525
from _pytask.shared import parse_paths
2626
from _pytask.shared import reduce_names_of_multiple_nodes
@@ -80,7 +80,6 @@ def pytask_extend_command_line_interface(cli: click.Group) -> None:
8080
def dag(**raw_config: Any) -> int:
8181
"""Create a visualization of the project's directed acyclic graph."""
8282
try:
83-
pm = get_plugin_manager()
8483
config = pm.hook.pytask_configure(pm=pm, raw_config=raw_config)
8584
session = Session.from_config(config)
8685

@@ -142,8 +141,6 @@ def build_dag(raw_config: dict[str, Any]) -> nx.DiGraph:
142141
143142
"""
144143
try:
145-
pm = get_plugin_manager()
146-
147144
# If someone called the programmatic interface, we need to do some parsing.
148145
if "command" not in raw_config:
149146
raw_config["command"] = "dag"

src/_pytask/data_catalog.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from _pytask.node_protocols import PNode
1717
from _pytask.node_protocols import PPathNode
1818
from _pytask.nodes import PickleNode
19-
from _pytask.pluginmanager import get_plugin_manager
19+
from _pytask.pluginmanager import plugin_manager as pm
2020
from _pytask.session import Session
2121
from attrs import define
2222
from attrs import field
@@ -36,9 +36,7 @@ def _get_parent_path_of_data_catalog_module(stacklevel: int = 2) -> Path:
3636

3737
def _create_default_session() -> Session:
3838
"""Create a default session to use the hooks and collect nodes."""
39-
return Session(
40-
config={"check_casing_of_paths": True}, hook=get_plugin_manager().hook
41-
)
39+
return Session(config={"check_casing_of_paths": True}, hook=pm.hook)
4240

4341

4442
@define(kw_only=True)

src/_pytask/hookspecs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
hookspec = pluggy.HookspecMarker("pytask")
3131

3232

33-
@hookspec
33+
@hookspec(historic=True)
3434
def pytask_add_hooks(pm: pluggy.PluginManager) -> None:
3535
"""Add hook specifications and implementations to the plugin manager.
3636

src/_pytask/mark/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
from _pytask.mark.structures import MarkDecorator
1919
from _pytask.mark.structures import MarkGenerator
2020
from _pytask.outcomes import ExitCode
21-
from _pytask.pluginmanager import get_plugin_manager
2221
from _pytask.pluginmanager import hookimpl
22+
from _pytask.pluginmanager import plugin_manager as pm
2323
from _pytask.session import Session
2424
from _pytask.shared import parse_markers
2525
from attrs import define
@@ -51,7 +51,6 @@ def markers(**raw_config: Any) -> NoReturn:
5151
raw_config["command"] = "markers"
5252

5353
try:
54-
pm = get_plugin_manager()
5554
config = pm.hook.pytask_configure(pm=pm, raw_config=raw_config)
5655
session = Session.from_config(config)
5756

src/_pytask/parameters.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,22 @@
33

44
from pathlib import Path
55
from typing import Iterable
6+
from typing import TYPE_CHECKING
67

78
import click
89
from _pytask.config_utils import set_defaults_from_config
910
from _pytask.path import import_path
1011
from _pytask.pluginmanager import hookimpl
12+
from _pytask.pluginmanager import plugin_manager as pm
13+
from _pytask.pluginmanager import register_hook_impls_from_modules
1114
from click import Context
1215
from sqlalchemy.engine import make_url
1316
from sqlalchemy.engine import URL
1417
from sqlalchemy.exc import ArgumentError
1518

19+
if TYPE_CHECKING:
20+
from pluggy import PluginManager
21+
1622

1723
_CONFIG_OPTION = click.Option(
1824
["-c", "--config"],
@@ -110,7 +116,7 @@ def _hook_module_callback(
110116
name: str, # noqa: ARG001
111117
value: tuple[str, ...],
112118
) -> Iterable[str | Path]:
113-
"""Check the hook module."""
119+
"""Register the user's hook modules from the configuration file."""
114120
if not value:
115121
return value
116122

@@ -124,6 +130,21 @@ def _hook_module_callback(
124130
parsed_modules.append(module.__name__)
125131
else:
126132
parsed_modules.append(module_name)
133+
134+
# If there are hook modules, we register a hook implementation to add them.
135+
# ``pytask_add_hooks`` is a historic hook specification, so even command line
136+
# options can be added.
137+
if parsed_modules:
138+
139+
class HookModule:
140+
@staticmethod
141+
@hookimpl
142+
def pytask_add_hooks(pm: PluginManager) -> None:
143+
"""Add hooks."""
144+
register_hook_impls_from_modules(pm, parsed_modules)
145+
146+
pm.register(HookModule)
147+
127148
return parsed_modules
128149

129150

src/_pytask/pluginmanager.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from __future__ import annotations
33

44
import importlib
5-
from typing import Any
65
from typing import Iterable
76

87
import pluggy
@@ -46,26 +45,28 @@ def pytask_add_hooks(pm: pluggy.PluginManager) -> None:
4645
"_pytask.collect",
4746
"_pytask.collect_command",
4847
"_pytask.config",
48+
"_pytask.dag",
49+
"_pytask.dag_command",
4950
"_pytask.database",
5051
"_pytask.debugging",
5152
"_pytask.execute",
52-
"_pytask.dag_command",
5353
"_pytask.live",
5454
"_pytask.logging",
5555
"_pytask.mark",
5656
"_pytask.nodes",
5757
"_pytask.parameters",
5858
"_pytask.persist",
5959
"_pytask.profile",
60-
"_pytask.dag",
6160
"_pytask.skipping",
6261
"_pytask.task",
6362
"_pytask.warnings",
6463
)
6564
register_hook_impls_from_modules(pm, builtin_hook_impl_modules)
6665

67-
@staticmethod
68-
@hookimpl(tryfirst=True)
69-
def pytask_parse_config(config: dict[str, Any]) -> None:
70-
"""Parse the configuration."""
71-
register_hook_impls_from_modules(config["pm"], config["hook_module"])
66+
67+
plugin_manager = pluggy.PluginManager("pytask")
68+
plugin_manager.add_hookspecs(hookspecs)
69+
plugin_manager.load_setuptools_entrypoints("pytask")
70+
71+
plugin_manager.register(BuiltinPlugins)
72+
plugin_manager.hook.pytask_add_hooks.call_historic(kwargs={"pm": plugin_manager})

src/_pytask/profile.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
from _pytask.node_protocols import PTask
2525
from _pytask.outcomes import ExitCode
2626
from _pytask.outcomes import TaskOutcome
27-
from _pytask.pluginmanager import get_plugin_manager
2827
from _pytask.pluginmanager import hookimpl
28+
from _pytask.pluginmanager import plugin_manager as pm
2929
from _pytask.session import Session
3030
from _pytask.traceback import Traceback
3131
from rich.table import Table
@@ -114,7 +114,6 @@ def profile(**raw_config: Any) -> NoReturn:
114114
raw_config["command"] = "profile"
115115

116116
try:
117-
pm = get_plugin_manager()
118117
config = pm.hook.pytask_configure(pm=pm, raw_config=raw_config)
119118
session = Session.from_config(config)
120119

src/_pytask/traceback.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ class Traceback:
4747

4848
show_locals: ClassVar[bool] = False
4949
suppress: ClassVar[tuple[Path, ...]] = (
50-
_PLUGGY_DIRECTORY,
51-
TREE_UTIL_LIB_DIRECTORY,
52-
_PYTASK_DIRECTORY,
50+
# _PLUGGY_DIRECTORY,
51+
# TREE_UTIL_LIB_DIRECTORY,
52+
# _PYTASK_DIRECTORY,
5353
)
5454

5555
def __rich_console__(

src/pytask/__init__.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from _pytask.build import build
77
from _pytask.capture_utils import CaptureMethod
88
from _pytask.capture_utils import ShowCapture
9+
from _pytask.cli import cli
910
from _pytask.click import ColoredCommand
1011
from _pytask.click import ColoredGroup
1112
from _pytask.click import EnumChoice
@@ -73,11 +74,6 @@
7374
from _pytask.warnings_utils import warning_record_to_str
7475
from _pytask.warnings_utils import WarningReport
7576

76-
77-
# This import must come last, otherwise a circular import occurs.
78-
from _pytask.cli import cli # noreorder
79-
80-
8177
__all__ = [
8278
"BaseTable",
8379
"CaptureMethod",

0 commit comments

Comments
 (0)