From 870cf0114848f145f15a78415e3f4203c6338cd1 Mon Sep 17 00:00:00 2001
From: Doug Hellmann <doug@doughellmann.com>
Date: Sat, 4 Jul 2020 11:34:05 -0400
Subject: [PATCH] switch to stevedore for entry points

Importing pkg_resources scans every installed distribution to find
all of the entry points. Stevedore is adding a new caching layer using
importlib.metadata, which will not.  Switching to the stevedore should
eventually speed up load times, especially for command line apps. This
change makes the switch now to ensure API compatibility.

We were already using stevedore for tests, so this moves the dependency
from test-requirements.txt to requirements.txt and raises the minimum
version to something more recent.

Change-Id: I3e3632783bc745979b6db73e610df8a77ffaceb0
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
---
 lower-constraints.txt                   |  2 +-
 openstackclient/common/clientmanager.py | 23 ++++++++++++++++-------
 requirements.txt                        |  1 +
 test-requirements.txt                   |  1 -
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/lower-constraints.txt b/lower-constraints.txt
index f16eca4184..c320edbe6e 100644
--- a/lower-constraints.txt
+++ b/lower-constraints.txt
@@ -124,7 +124,7 @@ six==1.10.0
 smmap==0.9.0
 statsd==3.2.1
 stestr==1.0.0
-stevedore==1.20.0
+stevedore==2.0.1
 sushy==0.1.0
 tempest==17.1.0
 tenacity==3.2.1
diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index c1118ad3ef..66dc880e07 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -15,12 +15,13 @@
 
 """Manage access to the clients, including authenticating when needed."""
 
+import importlib
 import logging
 import sys
 
 from osc_lib import clientmanager
 from osc_lib import shell
-import pkg_resources
+import stevedore
 
 
 LOG = logging.getLogger(__name__)
@@ -143,17 +144,25 @@ class ClientManager(clientmanager.ClientManager):
 def get_plugin_modules(group):
     """Find plugin entry points"""
     mod_list = []
-    for ep in pkg_resources.iter_entry_points(group):
+    mgr = stevedore.ExtensionManager(group)
+    for ep in mgr:
         LOG.debug('Found plugin %s', ep.name)
 
+        # Different versions of stevedore use different
+        # implementations of EntryPoint from other libraries, which
+        # are not API-compatible.
         try:
-            __import__(ep.module_name)
-        except Exception:
+            module_name = ep.entry_point.module_name
+        except AttributeError:
+            module_name = ep.entry_point.module
+
+        try:
+            module = importlib.import_module(module_name)
+        except Exception as err:
             sys.stderr.write(
-                "WARNING: Failed to import plugin %s.\n" % ep.name)
+                "WARNING: Failed to import plugin %s: %s.\n" % (ep.name, err))
             continue
 
-        module = sys.modules[ep.module_name]
         mod_list.append(module)
         init_func = getattr(module, 'Initialize', None)
         if init_func:
@@ -164,7 +173,7 @@ def get_plugin_modules(group):
             clientmanager.ClientManager,
             module.API_NAME,
             clientmanager.ClientCache(
-                getattr(sys.modules[ep.module_name], 'make_client', None)
+                getattr(sys.modules[module_name], 'make_client', None)
             ),
         )
     return mod_list
diff --git a/requirements.txt b/requirements.txt
index 3aac36af2f..b1421a831f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,3 +12,4 @@ oslo.utils>=3.33.0 # Apache-2.0
 python-keystoneclient>=3.22.0 # Apache-2.0
 python-novaclient>=15.1.0 # Apache-2.0
 python-cinderclient>=3.3.0 # Apache-2.0
+stevedore>=2.0.1 # Apache-2.0
diff --git a/test-requirements.txt b/test-requirements.txt
index f2b6a13402..3dce687bc7 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -8,7 +8,6 @@ flake8-import-order>=0.13 # LGPLv3
 oslotest>=3.2.0 # Apache-2.0
 requests>=2.14.2 # Apache-2.0
 requests-mock>=1.2.0 # Apache-2.0
-stevedore>=1.20.0 # Apache-2.0
 stestr>=1.0.0 # Apache-2.0
 testtools>=2.2.0 # MIT
 tempest>=17.1.0 # Apache-2.0