Skip to content

Commit

Permalink
Replace use of pkg_resources with importlib.metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
tysmith committed Jun 25, 2024
1 parent 90584bc commit 9e2a432
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 39 deletions.
16 changes: 6 additions & 10 deletions grizzly/common/plugins.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from importlib.metadata import entry_points
from logging import getLogger
from typing import Any, Dict, List, Tuple

from pkg_resources import iter_entry_points

__all__ = ("load", "scan", "PluginLoadError")


Expand All @@ -28,13 +27,10 @@ def load(name: str, group: str, base_type: type) -> Any:
Loaded plug-in object.
"""
assert isinstance(base_type, type)
for entry in iter_entry_points(group):
if entry.name == name:
LOG.debug("loading %r (%s)", name, base_type.__name__)
plugin = entry.load()
break
else:
entry = entry_points(group=group, name=name)
if not entry:
raise PluginLoadError(f"{name!r} not found in {group!r}")
plugin = entry[0].load()
if not issubclass(plugin, base_type):
raise PluginLoadError(f"{name!r} doesn't inherit from {base_type.__name__}")
return plugin
Expand All @@ -51,7 +47,7 @@ def scan(group: str) -> List[str]:
"""
found = []
LOG.debug("scanning %r", group)
for entry in iter_entry_points(group):
for entry in entry_points(group=group):
if entry.name in found:
# not sure if this can even happen
raise PluginLoadError(f"Duplicate entry {entry.name!r} in {group!r}")
Expand All @@ -69,6 +65,6 @@ def scan_target_assets() -> Dict[str, Tuple[str, ...]]:
Name of target and list of supported assets.
"""
assets = {}
for entry in iter_entry_points("grizzly_targets"):
for entry in entry_points(group="grizzly_targets"):
assets[entry.name] = entry.load().SUPPORTED_ASSETS
return assets
39 changes: 18 additions & 21 deletions grizzly/common/test_plugins.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from pkg_resources import EntryPoint
from importlib.metadata import EntryPoint

from pytest import raises

from ..target import Target
Expand All @@ -18,82 +19,78 @@ class FakeType2:

def test_load_01(mocker):
"""test load() - nothing to load"""
mocker.patch(
"grizzly.common.plugins.iter_entry_points", autospec=True, return_value=[]
)
mocker.patch("grizzly.common.plugins.entry_points", autospec=True, return_value=())
with raises(PluginLoadError, match="'test-name' not found in 'test-group'"):
load("test-name", "test-group", FakeType1)


def test_load_02(mocker):
"""test load() - successful load"""
# Note: Mock.name cannot be set via the constructor so spec_set cannot be used
entry = mocker.Mock(spec=EntryPoint)
entry = mocker.Mock(spec_set=EntryPoint)
entry.name = "test-name"
entry.load.return_value = FakeType1
mocker.patch(
"grizzly.common.plugins.iter_entry_points", autospec=True, return_value=[entry]
"grizzly.common.plugins.entry_points", autospec=True, return_value=(entry,)
)
assert load("test-name", "test-group", FakeType1)


def test_load_03(mocker):
"""test load() - invalid type"""
entry = mocker.Mock(spec=EntryPoint)
entry = mocker.Mock(spec_set=EntryPoint)
entry.name = "test-name"
entry.load.return_value = FakeType1
mocker.patch(
"grizzly.common.plugins.iter_entry_points", autospec=True, return_value=[entry]
"grizzly.common.plugins.entry_points", autospec=True, return_value=(entry,)
)
with raises(PluginLoadError, match="'test-name' doesn't inherit from FakeType2"):
load("test-name", "test-group", FakeType2)


def test_scan_01(mocker):
"""test scan() - no entries found"""
mocker.patch(
"grizzly.common.plugins.iter_entry_points", autospec=True, return_value=[]
)
mocker.patch("grizzly.common.plugins.entry_points", autospec=True, return_value=())
assert not scan("test_group")


def test_scan_02(mocker):
"""test scan() - duplicate entry"""
entry = mocker.Mock(spec=EntryPoint)
entry = mocker.Mock(spec_set=EntryPoint)
entry.name = "test_entry"
mocker.patch(
"grizzly.common.plugins.iter_entry_points",
"grizzly.common.plugins.entry_points",
autospec=True,
return_value=[entry, entry],
return_value=(entry, entry),
)
with raises(PluginLoadError, match="Duplicate entry 'test_entry' in 'test_group'"):
scan("test_group")


def test_scan_03(mocker):
"""test scan() - success"""
entry = mocker.Mock(spec=EntryPoint)
entry = mocker.Mock(spec_set=EntryPoint)
entry.name = "test-name"
mocker.patch(
"grizzly.common.plugins.iter_entry_points",
"grizzly.common.plugins.entry_points",
autospec=True,
return_value=[entry],
return_value=(entry,),
)
assert "test-name" in scan("test_group")


def test_scan_target_assets_01(mocker):
"""test scan_target_assets() - success"""
targ1 = mocker.Mock(spec=EntryPoint)
targ1 = mocker.Mock(spec_set=EntryPoint)
targ1.name = "t1"
targ1.load.return_value = mocker.Mock(spec_set=Target, SUPPORTED_ASSETS=None)
targ2 = mocker.Mock(spec=EntryPoint)
targ2 = mocker.Mock(spec_set=EntryPoint)
targ2.name = "t2"
targ2.load.return_value = mocker.Mock(spec_set=Target, SUPPORTED_ASSETS=("a", "B"))
mocker.patch(
"grizzly.common.plugins.iter_entry_points",
"grizzly.common.plugins.entry_points",
autospec=True,
return_value=[targ1, targ2],
return_value=(targ1, targ2),
)
assets = scan_target_assets()
assert "t1" in assets
Expand Down
5 changes: 2 additions & 3 deletions grizzly/reduce/strategies/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"""
from abc import ABC, abstractmethod
from hashlib import sha512
from importlib.metadata import entry_points
from logging import DEBUG, getLogger
from pathlib import Path
from shutil import rmtree
Expand All @@ -30,8 +31,6 @@
cast,
)

from pkg_resources import iter_entry_points

from ...common.storage import TestCase
from ...common.utils import grz_tmp

Expand Down Expand Up @@ -204,7 +203,7 @@ def _load_strategies() -> Dict[str, Type[Strategy]]:
A mapping of strategy names to strategy class.
"""
strategies: Dict[str, Type[Strategy]] = {}
for entry_point in iter_entry_points("grizzly_reduce_strategies"):
for entry_point in entry_points(group="grizzly_reduce_strategies"):
try:
strategy_cls = cast(Type[Strategy], entry_point.load())
assert (
Expand Down
9 changes: 4 additions & 5 deletions grizzly/reduce/test_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,10 @@ class _BadStrategy:
def load(cls):
raise RuntimeError("oops")

def entries(_):
yield _BadStrategy
yield _GoodStrategy

mocker.patch("grizzly.reduce.strategies.iter_entry_points", side_effect=entries)
mocker.patch(
"grizzly.reduce.strategies.entry_points",
return_value=(_BadStrategy, _GoodStrategy),
)
mocker.patch("grizzly.reduce.strategies.DEFAULT_STRATEGIES", new=("good",))
result = _load_strategies()
assert result == {"good": _GoodStrategy}
Expand Down

0 comments on commit 9e2a432

Please sign in to comment.