Use importlib.metadata instead of pkg_resources for entrypoint processing
authorKarl O. Pinc <kop@karlpinc.com>
Thu, 21 Mar 2024 19:43:39 +0000 (14:43 -0500)
committerKarl O. Pinc <kop@karlpinc.com>
Thu, 21 Mar 2024 19:43:39 +0000 (14:43 -0500)
setup.py
src/pgwui_common/plugin.py
tests/test_plugin.py

index cdd4ad6d640d48b061bbbeaf5c32910f218df308..98dc527e2f55f699287452fba67398bc5e88cd86 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -143,6 +143,8 @@ setup(
     # Run-time dependencies.
     install_requires=[
         'pgwui_core==' + version,
+        # for plugin.py's entrypoint processing.
+        'importlib_metadata > 3.6 ; python_version < "3.10"',
         'pyramid',
         'pyramid_beaker',
         'pyramid_mako',
index ab7215f61cd0bd41f3bdf629495b6efe990b37db..f69bafc50731dd51cf1fa9cbb88d93048277c2de 100644 (file)
 '''Plugin support library for PGWUI
 '''
 
-import pkg_resources
+import sys
+
+if sys.version_info < (3, 10):
+    import importlib_metadata
+
+    class importlib:
+        pass
+    setattr(importlib, 'metadata', importlib_metadata)
+else:
+    import importlib.metadata
 
 
 def get_component(module):
@@ -34,8 +43,8 @@ def get_component(module):
 def find_pgwui_components():
     '''Return list of all pgwui component names as strings
     '''
-    return [get_component(entry_point.resolve().__name__) for entry_point in
-            pkg_resources.iter_entry_points('pgwui.components')]
+    return [get_component(entry_point.module) for entry_point in
+            importlib.metadata.entry_points(group='pgwui.components')]
 
 
 def find_pgwui_check_settings():
@@ -43,7 +52,8 @@ def find_pgwui_check_settings():
     component
     '''
     check_settings = dict()
-    for entry_point in pkg_resources.iter_entry_points('pgwui.check_settings'):
-        callable = entry_point.resolve()
+    for entry_point in importlib.metadata.entry_points(
+            group='pgwui.check_settings'):
+        callable = entry_point.load()
         check_settings[get_component(callable.__module__)] = callable
     return check_settings
index bd1fa8eeeab68e4b400672ef50b120712c40bc16..439bb5a3a2292bac2c1e26a741262e11e7959162 100644 (file)
@@ -26,23 +26,16 @@ from pgwui_common import plugin
 
 
 # Helper classes
+# (We might want to mock this, but what module defines EntryPoint()?)
 class MockEntryPoint():
     def __init__(self, val):
+        self.module = val
         self.__module__ = val
-        self.__name__ = val
 
-    def resolve(self):
+    def load(self):
         return self
 
 
-class MockPkgResources():
-    def __init__(self, entry_points):
-        self.entry_points = entry_points
-
-    def iter_entry_points(self, *args):
-        return [MockEntryPoint(name) for name in self.entry_points]
-
-
 # get_component()
 
 @pytest.mark.unittest
@@ -59,33 +52,45 @@ mock_get_component = testing.make_mock_fixture(
 
 # find_pgwui_components()
 
+# Use late binding; eaiser since the module hierarchy is sometimes constructed
+# because importlib.metadata sometimes uses a compatibility module.
+mock_importlib_metadata_entry_points = testing.late_instance_mock_fixture(
+    'entry_points')
+
+
 @pytest.mark.unittest
-def test_find_pgwui_components(mock_get_component, monkeypatch):
-    '''Returns list of entry points via iter_entry_points()
+def test_find_pgwui_components(
+        mock_get_component, mock_importlib_metadata_entry_points):
+    '''Returns collection of entry points via entry_points()
     '''
-    entry_points = ['a', 'b', 'c']
+    entry_point_modules = ['a', 'b', 'c']
+    entry_points = [MockEntryPoint(mod) for mod in entry_point_modules]
 
     mock_get_component.side_effect = lambda x: x
-    monkeypatch.setattr(
-        plugin, 'pkg_resources', MockPkgResources(entry_points))
+    mocked_importlib_metadata_entry_points = (
+        mock_importlib_metadata_entry_points(plugin.importlib.metadata))
+    mocked_importlib_metadata_entry_points.return_value = entry_points
 
     result = plugin.find_pgwui_components()
 
-    assert result == entry_points
+    assert result == entry_point_modules
 
 
 # find_pgwui_check_settings
 @pytest.mark.unittest
-def test_find_pgwui_check_settings(mock_get_component, monkeypatch):
+def test_find_pgwui_check_settings(
+        mock_get_component, mock_importlib_metadata_entry_points):
     '''Returns a dict, keyed by name, of entry points
     '''
-    entry_points = ['a', 'b', 'c']
+    entry_point_modules = ['a', 'b', 'c']
+    entry_points = [MockEntryPoint(mod) for mod in entry_point_modules]
 
     mock_get_component.side_effect = lambda x: x
-    monkeypatch.setattr(
-        plugin, 'pkg_resources', MockPkgResources(entry_points))
+    mocked_importlib_metadata_entry_points = (
+        mock_importlib_metadata_entry_points(plugin.importlib.metadata))
+    mocked_importlib_metadata_entry_points.return_value = entry_points
 
     result = plugin.find_pgwui_check_settings()
 
     assert isinstance(result, dict)
-    assert list(result.keys()).sort() == entry_points.sort()
+    assert list(result.keys()).sort() == entry_point_modules.sort()