Skip to content

Commit 27ad3b2

Browse files
committed
Add validation that method was specified before in NoxTasks
1 parent cdb8d47 commit 27ad3b2

File tree

3 files changed

+38
-8
lines changed

3 files changed

+38
-8
lines changed

exasol/toolbox/config.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,29 @@
1111
computed_field,
1212
)
1313

14-
from exasol.toolbox.nox.plugin import PLUGIN_ATTR_NAME
14+
from exasol.toolbox.nox.plugin import (
15+
METHODS_SPECIFIED_FOR_HOOKS,
16+
PLUGIN_ATTR_NAME,
17+
)
1518
from exasol.toolbox.util.version import Version
1619

1720

1821
def validate_plugin_hook(plugin_class: object):
1922
"""
20-
Checks all methods in a class for at least one specific pluggy hookimpl marker.
21-
Raises ValueError if no methods are found with the marker.
23+
Checks methods in a class for at least one specific pluggy @hookimpl marker
24+
and verifies it is specified in `exasol.toolbox.nox.plugins.NoxTasks`.
2225
"""
2326
for name, method in inspect.getmembers(plugin_class, inspect.isroutine):
2427
if hasattr(method, PLUGIN_ATTR_NAME):
25-
return True
28+
if name in METHODS_SPECIFIED_FOR_HOOKS:
29+
return True
30+
raise ValueError(
31+
f"Method `{name}` in `{plugin_class.__name__}` was decorated with "
32+
"`@hookimpl`, but this is not defined in "
33+
"`exasol.toolbox.nox.plugins.NoxTasks`."
34+
)
2635
raise ValueError(
27-
f"No methods in {plugin_class.__name__} were found to be decorated"
36+
f"No methods in `{plugin_class.__name__}` were found to be decorated"
2837
"with `@hookimpl`"
2938
)
3039

@@ -92,8 +101,7 @@ class BaseConfig(BaseModel):
92101
by the python-toolbox. As described on the plugins pages:
93102
- https://exasol.github.io/python-toolbox/main/user_guide/customization.html#plugins
94103
- https://exasol.github.io/python-toolbox/main/developer_guide/plugins.html,
95-
possible plugin options are defined in the `exasol.toolbox.nox.plugins`
96-
namespace.
104+
possible plugin options are defined in `exasol.toolbox.nox.plugins.NoxTasks`.
97105
""",
98106
)
99107
model_config = ConfigDict(frozen=True, arbitrary_types_allowed=True)

exasol/toolbox/nox/plugin.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import inspect
2+
13
import pluggy
24

35
_PLUGIN_MARKER = "python-toolbox-nox"
@@ -109,3 +111,10 @@ def plugin_manager(config) -> pluggy.PluginManager:
109111
for plugin in getattr(config, "plugins", []):
110112
pm.register(plugin())
111113
return pm
114+
115+
116+
METHODS_SPECIFIED_FOR_HOOKS = [
117+
name
118+
for name, method in inspect.getmembers(NoxTasks, inspect.isroutine)
119+
if hasattr(method, f"{_PLUGIN_MARKER}_spec")
120+
]

test/unit/config_test.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ def prepare_release_update_version(self, session, config, version: Version) -> N
9696
print("This is a simple, silly hook.")
9797

9898

99+
class WithNotSpecifiedHook:
100+
@hookimpl
101+
def not_specified_anywhere(self, session, config, version: Version) -> None:
102+
print("This is not a properly prepared hook.")
103+
104+
99105
class WithoutHook:
100106
def prepare_release_update_version(self, session, config, version: Version) -> None:
101107
print("This is not a properly prepared hook.")
@@ -110,7 +116,14 @@ def test_works_when_empty():
110116
def test_works_for_hook(capsys):
111117
BaseConfig(plugins=(WithHook,))
112118

119+
@staticmethod
120+
def test_raises_exception_method_with_hook_not_specified():
121+
with pytest.raises(ValidationError) as ex:
122+
BaseConfig(plugins=(WithNotSpecifiedHook,))
123+
assert "Method `not_specified_anywhere`" in str(ex.value)
124+
113125
@staticmethod
114126
def test_raises_exception_without_hook():
115-
with pytest.raises(ValueError, match="with `@hookimpl`"):
127+
with pytest.raises(ValidationError) as ex:
116128
BaseConfig(plugins=(WithoutHook,))
129+
assert "No methods in `WithoutHook`" in str(ex.value)

0 commit comments

Comments
 (0)