Skip to content

Commit 0dd7795

Browse files
authored
Remove dynamic plugin support (#113)
* Remove dynamic plugin support Block dynamic plugins, remove relevant tests. No API changes yet. Signed-off-by: Michał Górny <mgorny@quansight.com> * Remove `known_properties` from variantlib API Signed-off-by: Michał Górny <mgorny@quansight.com> * Disallow version operators from property values Now that we don't allow dynamic plugins anymore, there is no reason to allow full version specifier syntax. We still allow `.` for versions themselves, though. Signed-off-by: Michał Górny <mgorny@quansight.com> * Remove `known_properties` argument to `get_supported_configs()` Signed-off-by: Michał Górny <mgorny@quansight.com> * Return to `get_all_configs()` API Signed-off-by: Michał Górny <mgorny@quansight.com> * Remove leftover dynamic check We've broken the API anyway. Signed-off-by: Michał Górny <mgorny@quansight.com> * Rework the PluginLoader API to expose `get_all_configs()`, fix bugs Signed-off-by: Michał Górny <mgorny@quansight.com> * Inline `_display_configs` into `get_supported_configs` There is only one command remaining, so no point in splitting it. Signed-off-by: Michał Górny <mgorny@quansight.com> * Make `variantlib plugins get-configs` into a generic method Signed-off-by: Michał Górny <mgorny@quansight.com> * Remove unused `VariantPropertyType` protocol Signed-off-by: Michał Górny <mgorny@quansight.com> * Address review comments Signed-off-by: Michał Górny <mgorny@quansight.com> --------- Signed-off-by: Michał Górny <mgorny@quansight.com>
1 parent 146ba02 commit 0dd7795

18 files changed

Lines changed: 294 additions & 502 deletions

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ show = "variantlib.commands.config.show:show"
7676

7777
[project.entry-points."variantlib.actions.plugins"]
7878
list = "variantlib.commands.plugins.list_plugins:list_plugins"
79-
get-supported-configs = "variantlib.commands.plugins.get_supported_configs:get_supported_configs"
80-
validate-property = "variantlib.commands.plugins.validate_property:validate_property"
79+
get-configs = "variantlib.commands.plugins.get_configs:get_configs"
8180

8281
[tool.pytest.ini_options]
8382
testpaths = ["tests/"]
Binary file not shown.
Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
from __future__ import annotations
22

33
from dataclasses import dataclass
4-
from typing import TYPE_CHECKING
5-
6-
if TYPE_CHECKING:
7-
from variantlib.protocols import VariantPropertyType
84

95

106
@dataclass
@@ -14,23 +10,18 @@ class FeatConfig:
1410

1511

1612
namespace = "installable_plugin"
17-
dynamic = False
1813

1914

20-
def validate_property(
21-
variant_property: VariantPropertyType,
22-
) -> bool:
23-
assert variant_property.namespace == namespace
24-
return (
25-
(variant_property.feature == "feat1" and variant_property.value in ["val1a", "val1b", "val1c"])
26-
or (variant_property.feature == "feat2" and variant_property.value in ["val2a", "val2b"])
27-
)
15+
def get_all_configs(
16+
) -> list[FeatConfig]:
17+
return [
18+
FeatConfig("feat1", ["val1a", "val1b", "val1c"]),
19+
FeatConfig("feat2", ["val2a", "val2b",]),
20+
]
2821

2922

3023
def get_supported_configs(
31-
known_properties: frozenset[VariantPropertyType] | None,
3224
) -> list[FeatConfig]:
33-
assert known_properties is None
3425
return [
3526
FeatConfig("feat1", ["val1c", "val1b"]),
3627
]

tests/commands/test_plugins.py

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,76 +23,103 @@ def test_plugins_list(
2323
)
2424

2525

26-
def test_plugins_get_supported_configs(
26+
def test_plugins_get_all_configs(
2727
capsys: pytest.CaptureFixture[str],
2828
mocked_entry_points: None,
2929
) -> None:
30-
main(["plugins", "get-supported-configs"])
30+
main(["plugins", "get-configs", "--all"])
3131
assert (
3232
capsys.readouterr().out
3333
== """\
3434
test_namespace :: name1 :: val1a
3535
test_namespace :: name1 :: val1b
36+
test_namespace :: name1 :: val1c
37+
test_namespace :: name1 :: val1d
3638
test_namespace :: name2 :: val2a
3739
test_namespace :: name2 :: val2b
3840
test_namespace :: name2 :: val2c
3941
second_namespace :: name3 :: val3a
42+
second_namespace :: name3 :: val3b
43+
second_namespace :: name3 :: val3c
44+
incompatible_namespace :: flag1 :: on
45+
incompatible_namespace :: flag2 :: on
46+
incompatible_namespace :: flag3 :: on
47+
incompatible_namespace :: flag4 :: on
4048
"""
4149
)
4250

4351

44-
def test_plugins_get_supported_configs_filter_namespace(
52+
def test_plugins_get_all_configs_filter_namespace(
4553
capsys: pytest.CaptureFixture[str],
4654
mocked_entry_points: None,
4755
) -> None:
48-
main(["plugins", "get-supported-configs", "-n", "second_namespace"])
56+
main(["plugins", "get-configs", "--all", "-n", "second_namespace"])
4957
assert (
5058
capsys.readouterr().out
5159
== """\
5260
second_namespace :: name3 :: val3a
61+
second_namespace :: name3 :: val3b
62+
second_namespace :: name3 :: val3c
5363
"""
5464
)
5565

5666

57-
def test_plugins_get_supported_configs_filter_feature(
67+
def test_plugins_get_all_configs_filter_feature(
68+
capsys: pytest.CaptureFixture[str],
69+
mocked_entry_points: None,
70+
) -> None:
71+
main(["plugins", "get-configs", "--all", "-f", "name1"])
72+
assert (
73+
capsys.readouterr().out
74+
== """\
75+
test_namespace :: name1 :: val1a
76+
test_namespace :: name1 :: val1b
77+
test_namespace :: name1 :: val1c
78+
test_namespace :: name1 :: val1d
79+
"""
80+
)
81+
82+
83+
def test_plugins_get_supported_configs(
5884
capsys: pytest.CaptureFixture[str],
5985
mocked_entry_points: None,
6086
) -> None:
61-
main(["plugins", "get-supported-configs", "-f", "name1"])
87+
main(["plugins", "get-configs", "--supported"])
6288
assert (
6389
capsys.readouterr().out
6490
== """\
6591
test_namespace :: name1 :: val1a
6692
test_namespace :: name1 :: val1b
93+
test_namespace :: name2 :: val2a
94+
test_namespace :: name2 :: val2b
95+
test_namespace :: name2 :: val2c
96+
second_namespace :: name3 :: val3a
6797
"""
6898
)
6999

70100

71-
def test_plugins_validate_property(
72-
capsys: pytest.CaptureFixture[str], mocked_entry_points: None
101+
def test_plugins_get_supported_configs_filter_namespace(
102+
capsys: pytest.CaptureFixture[str],
103+
mocked_entry_points: None,
73104
) -> None:
74-
main(
75-
[
76-
"plugins",
77-
"validate-property",
78-
"test_namespace :: name1 :: val1a",
79-
"test_namespace :: name1::val1b",
80-
"test_namespace :: name2 :: val2a",
81-
"second_namespace:: name1:: val1a",
82-
"second_namespace::name3 :: val3a",
83-
"test_namespace :: name3 :: val3a",
84-
"unknown_namespace::foo::bar",
85-
]
105+
main(["plugins", "get-configs", "--supported", "-n", "second_namespace"])
106+
assert (
107+
capsys.readouterr().out
108+
== """\
109+
second_namespace :: name3 :: val3a
110+
"""
86111
)
112+
113+
114+
def test_plugins_get_supported_configs_filter_feature(
115+
capsys: pytest.CaptureFixture[str],
116+
mocked_entry_points: None,
117+
) -> None:
118+
main(["plugins", "get-configs", "--supported", "-f", "name1"])
87119
assert (
88120
capsys.readouterr().out
89121
== """\
90-
test_namespace :: name1 :: val1a : valid
91-
test_namespace :: name1 :: val1b : valid
92-
test_namespace :: name2 :: val2a : valid
93-
second_namespace :: name1 :: val1a : invalid
94-
second_namespace :: name3 :: val3a : valid
95-
test_namespace :: name3 :: val3a : invalid
96-
unknown_namespace :: foo :: bar : no-plugin
122+
test_namespace :: name1 :: val1a
123+
test_namespace :: name1 :: val1b
97124
"""
98125
)

tests/mocked_plugin_as_module.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
11
from __future__ import annotations
22

3+
from dataclasses import dataclass
34
from typing import TYPE_CHECKING
45

56
if TYPE_CHECKING:
67
from variantlib.protocols import VariantFeatureConfigType
7-
from variantlib.protocols import VariantPropertyType
8+
9+
10+
@dataclass
11+
class VariantFeatureConfig:
12+
name: str
13+
values: list[str]
814

915

1016
namespace = "module_namespace"
11-
dynamic = False
1217

1318

14-
def validate_property(
15-
variant_property: VariantPropertyType,
16-
) -> bool:
17-
assert variant_property.namespace == namespace
18-
return variant_property.feature == "feature" and variant_property.value in [
19-
"a",
20-
"b",
21-
]
19+
def get_all_configs() -> list[VariantFeatureConfigType]:
20+
return [VariantFeatureConfig("feature", ["a", "b"])]
2221

2322

24-
def get_supported_configs(
25-
known_properties: frozenset[VariantPropertyType] | None,
26-
) -> list[VariantFeatureConfigType]:
27-
assert known_properties is None
23+
def get_supported_configs() -> list[VariantFeatureConfigType]:
2824
return []

tests/mocked_plugins.py

Lines changed: 24 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from variantlib.models.provider import VariantFeatureConfig
77
from variantlib.protocols import PluginType
88
from variantlib.protocols import VariantFeatureConfigType
9-
from variantlib.protocols import VariantPropertyType
109

1110

1211
@dataclass
@@ -18,22 +17,14 @@ class MockedEntryPoint:
1817

1918
class MockedPluginA(PluginType):
2019
namespace = "test_namespace" # pyright: ignore[reportAssignmentType,reportIncompatibleMethodOverride]
21-
dynamic = False # pyright: ignore[reportAssignmentType,reportIncompatibleMethodOverride]
22-
23-
def validate_property(self, variant_property: VariantPropertyType) -> bool:
24-
assert variant_property.namespace == self.namespace
25-
return (
26-
variant_property.feature == "name1"
27-
and variant_property.value in ["val1a", "val1b", "val1c", "val1d"]
28-
) or (
29-
variant_property.feature == "name2"
30-
and variant_property.value in ["val2a", "val2b", "val2c"]
31-
)
32-
33-
def get_supported_configs(
34-
self, known_properties: frozenset[VariantPropertyType] | None
35-
) -> list[VariantFeatureConfigType]:
36-
assert known_properties is None
20+
21+
def get_all_configs(self) -> list[VariantFeatureConfigType]:
22+
return [
23+
VariantFeatureConfig("name1", ["val1a", "val1b", "val1c", "val1d"]),
24+
VariantFeatureConfig("name2", ["val2a", "val2b", "val2c"]),
25+
]
26+
27+
def get_supported_configs(self) -> list[VariantFeatureConfigType]:
3728
return [
3829
VariantFeatureConfig("name1", ["val1a", "val1b"]),
3930
VariantFeatureConfig("name2", ["val2a", "val2b", "val2c"]),
@@ -47,25 +38,15 @@ def get_supported_configs(
4738
# to test that we don't rely on that inheritance
4839
class MockedPluginB:
4940
namespace = "second_namespace"
50-
dynamic = True
51-
52-
def validate_property(self, variant_property: VariantPropertyType) -> bool:
53-
assert variant_property.namespace == self.namespace
54-
return variant_property.feature == "name3"
55-
56-
def get_supported_configs(
57-
self, known_properties: frozenset[VariantPropertyType] | None
58-
) -> list[MyVariantFeatureConfig]:
59-
assert known_properties is not None
60-
assert all(prop.namespace == self.namespace for prop in known_properties)
61-
vals3 = ["val3a"]
62-
vals3.extend(
63-
x.value
64-
for x in known_properties
65-
if x.feature == "name3" and x.value not in vals3
66-
)
41+
42+
def get_all_configs(self) -> list[MyVariantFeatureConfig]:
6743
return [
68-
MyVariantFeatureConfig("name3", vals3),
44+
MyVariantFeatureConfig("name3", ["val3a", "val3b", "val3c"]),
45+
]
46+
47+
def get_supported_configs(self) -> list[MyVariantFeatureConfig]:
48+
return [
49+
MyVariantFeatureConfig("name3", ["val3a"]),
6950
]
7051

7152

@@ -80,19 +61,14 @@ def __init__(self, name: str) -> None:
8061

8162
class MockedPluginC(PluginType):
8263
namespace = "incompatible_namespace"
83-
dynamic = False
84-
85-
def validate_property(self, variant_property: VariantPropertyType) -> bool:
86-
assert variant_property.namespace == self.namespace
87-
return (
88-
variant_property.feature in ("flag1", "flag2", "flag3", "flag4")
89-
and variant_property.value == "on"
90-
)
91-
92-
def get_supported_configs(
93-
self, known_properties: frozenset[VariantPropertyType] | None
94-
) -> list[VariantFeatureConfigType]:
95-
assert known_properties is None
64+
65+
def get_all_configs(self) -> list[VariantFeatureConfigType]:
66+
return [
67+
MyVariantFeatureConfig(x, ["on"])
68+
for x in ("flag1", "flag2", "flag3", "flag4")
69+
]
70+
71+
def get_supported_configs(self) -> list[VariantFeatureConfigType]:
9672
return []
9773

9874

0 commit comments

Comments
 (0)