Skip to content

Commit b2d7cd8

Browse files
Fix module name retrieval in backend.plugins.remove_duplicates(), plugin tests (pydata#5959)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent a883ed0 commit b2d7cd8

File tree

3 files changed

+44
-26
lines changed

3 files changed

+44
-26
lines changed

doc/whats-new.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ Bug fixes
3636
~~~~~~~~~
3737
- Fix plot.line crash for data of shape ``(1, N)`` in _title_for_slice on format_item (:pull:`5948`).
3838
By `Sebastian Weigand <https://github.com/s-weigand>`_.
39+
- Fix a regression in the removal of duplicate backend entrypoints (:issue:`5944`, :pull:`5959`)
40+
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
3941

4042
Documentation
4143
~~~~~~~~~~~~~
@@ -49,6 +51,10 @@ Documentation
4951
Internal Changes
5052
~~~~~~~~~~~~~~~~
5153

54+
- Use ``importlib`` to replace functionality of ``pkg_resources`` in
55+
backend plugins tests. (:pull:`5959`).
56+
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
57+
5258

5359
.. _whats-new.0.20.1:
5460

xarray/backends/plugins.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,17 @@ def remove_duplicates(entrypoints):
2323
# check if there are multiple entrypoints for the same name
2424
unique_entrypoints = []
2525
for name, matches in entrypoints_grouped:
26-
matches = list(matches)
26+
# remove equal entrypoints
27+
matches = list(set(matches))
2728
unique_entrypoints.append(matches[0])
2829
matches_len = len(matches)
2930
if matches_len > 1:
30-
selected_module_name = matches[0].module_name
31-
all_module_names = [e.module_name for e in matches]
31+
all_module_names = [e.value.split(":")[0] for e in matches]
32+
selected_module_name = all_module_names[0]
3233
warnings.warn(
3334
f"Found {matches_len} entrypoints for the engine name {name}:"
34-
f"\n {all_module_names}.\n It will be used: {selected_module_name}.",
35+
f"\n {all_module_names}.\n "
36+
f"The entrypoint {selected_module_name} will be used.",
3537
RuntimeWarning,
3638
)
3739
return unique_entrypoints

xarray/tests/test_plugins.py

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
1+
import sys
12
from unittest import mock
23

3-
import pkg_resources
44
import pytest
55

66
from xarray.backends import common, plugins
77

8+
if sys.version_info >= (3, 8):
9+
from importlib.metadata import EntryPoint
10+
11+
importlib_metadata_mock = "importlib.metadata"
12+
else:
13+
# if the fallback library is missing, we are doomed.
14+
from importlib_metadata import EntryPoint
15+
16+
importlib_metadata_mock = "importlib_metadata"
17+
818

919
class DummyBackendEntrypointArgs(common.BackendEntrypoint):
1020
def open_dataset(filename_or_obj, *args):
@@ -29,12 +39,12 @@ def open_dataset(self, filename_or_obj, *, decoder):
2939
@pytest.fixture
3040
def dummy_duplicated_entrypoints():
3141
specs = [
32-
"engine1 = xarray.tests.test_plugins:backend_1",
33-
"engine1 = xarray.tests.test_plugins:backend_2",
34-
"engine2 = xarray.tests.test_plugins:backend_1",
35-
"engine2 = xarray.tests.test_plugins:backend_2",
42+
["engine1", "xarray.tests.test_plugins:backend_1", "xarray.backends"],
43+
["engine1", "xarray.tests.test_plugins:backend_2", "xarray.backends"],
44+
["engine2", "xarray.tests.test_plugins:backend_1", "xarray.backends"],
45+
["engine2", "xarray.tests.test_plugins:backend_2", "xarray.backends"],
3646
]
37-
eps = [pkg_resources.EntryPoint.parse(spec) for spec in specs]
47+
eps = [EntryPoint(name, value, group) for name, value, group in specs]
3848
return eps
3949

4050

@@ -46,8 +56,10 @@ def test_remove_duplicates(dummy_duplicated_entrypoints) -> None:
4656

4757

4858
def test_broken_plugin() -> None:
49-
broken_backend = pkg_resources.EntryPoint.parse(
50-
"broken_backend = xarray.tests.test_plugins:backend_1"
59+
broken_backend = EntryPoint(
60+
"broken_backend",
61+
"xarray.tests.test_plugins:backend_1",
62+
"xarray.backends",
5163
)
5264
with pytest.warns(RuntimeWarning) as record:
5365
_ = plugins.build_engines([broken_backend])
@@ -68,13 +80,15 @@ def test_remove_duplicates_warnings(dummy_duplicated_entrypoints) -> None:
6880
assert "entrypoints" in message1
6981

7082

71-
@mock.patch("pkg_resources.EntryPoint.load", mock.MagicMock(return_value=None))
83+
@mock.patch(
84+
f"{importlib_metadata_mock}.EntryPoint.load", mock.MagicMock(return_value=None)
85+
)
7286
def test_backends_dict_from_pkg() -> None:
7387
specs = [
74-
"engine1 = xarray.tests.test_plugins:backend_1",
75-
"engine2 = xarray.tests.test_plugins:backend_2",
88+
["engine1", "xarray.tests.test_plugins:backend_1", "xarray.backends"],
89+
["engine2", "xarray.tests.test_plugins:backend_2", "xarray.backends"],
7690
]
77-
entrypoints = [pkg_resources.EntryPoint.parse(spec) for spec in specs]
91+
entrypoints = [EntryPoint(name, value, group) for name, value, group in specs]
7892
engines = plugins.backends_dict_from_pkg(entrypoints)
7993
assert len(engines) == 2
8094
assert engines.keys() == set(("engine1", "engine2"))
@@ -114,12 +128,12 @@ def test_set_missing_parameters_raise_error() -> None:
114128

115129

116130
@mock.patch(
117-
"pkg_resources.EntryPoint.load",
131+
f"{importlib_metadata_mock}.EntryPoint.load",
118132
mock.MagicMock(return_value=DummyBackendEntrypoint1),
119133
)
120134
def test_build_engines() -> None:
121-
dummy_pkg_entrypoint = pkg_resources.EntryPoint.parse(
122-
"cfgrib = xarray.tests.test_plugins:backend_1"
135+
dummy_pkg_entrypoint = EntryPoint(
136+
"cfgrib", "xarray.tests.test_plugins:backend_1", "xarray_backends"
123137
)
124138
backend_entrypoints = plugins.build_engines([dummy_pkg_entrypoint])
125139

@@ -131,17 +145,13 @@ def test_build_engines() -> None:
131145

132146

133147
@mock.patch(
134-
"pkg_resources.EntryPoint.load",
148+
f"{importlib_metadata_mock}.EntryPoint.load",
135149
mock.MagicMock(return_value=DummyBackendEntrypoint1),
136150
)
137151
def test_build_engines_sorted() -> None:
138152
dummy_pkg_entrypoints = [
139-
pkg_resources.EntryPoint.parse(
140-
"dummy2 = xarray.tests.test_plugins:backend_1",
141-
),
142-
pkg_resources.EntryPoint.parse(
143-
"dummy1 = xarray.tests.test_plugins:backend_1",
144-
),
153+
EntryPoint("dummy2", "xarray.tests.test_plugins:backend_1", "xarray.backends"),
154+
EntryPoint("dummy1", "xarray.tests.test_plugins:backend_1", "xarray.backends"),
145155
]
146156
backend_entrypoints = plugins.build_engines(dummy_pkg_entrypoints)
147157
backend_entrypoints = list(backend_entrypoints)

0 commit comments

Comments
 (0)