Permalink
Browse files

Merge pull request #3 from dhellmann/feature/cache-entry-points

Cache the entry points discovered within a namespace
  • Loading branch information...
2 parents b01eb69 + 7bdc14c commit 2106ab5e26a502971a4d5166b273fb52fb53f20c @markmcclain markmcclain committed Nov 26, 2012
Showing with 44 additions and 1 deletion.
  1. +9 −1 stevedore/extension.py
  2. +35 −0 stevedore/tests/test_extension.py
View
@@ -56,9 +56,17 @@ def __init__(self, namespace,
invoke_args,
invoke_kwds)
+ ENTRY_POINT_CACHE = {}
+
+ def _find_entry_points(self, namespace):
+ if namespace not in self.ENTRY_POINT_CACHE:
+ eps = list(pkg_resources.iter_entry_points(namespace))
+ self.ENTRY_POINT_CACHE[namespace] = eps
+ return self.ENTRY_POINT_CACHE[namespace]
+
def _load_plugins(self, invoke_on_load, invoke_args, invoke_kwds):
extensions = []
- for ep in pkg_resources.iter_entry_points(self.namespace):
+ for ep in self._find_entry_points(self.namespace):
LOG.debug('found extension %r', ep)
try:
ext = self._load_one_plugin(ep,
@@ -1,6 +1,8 @@
"""Tests for stevedore.extension
"""
+import mock
+
from stevedore import extension
@@ -16,6 +18,39 @@ def test_detect_plugins():
assert names == ['t1', 't2']
+def test_load_multiple_times_entry_points():
+ # We expect to get the same EntryPoint object because we save them
+ # in the cache.
+ em1 = extension.ExtensionManager('stevedore.test.extension')
+ eps1 = [ext.entry_point for ext in em1]
+ em2 = extension.ExtensionManager('stevedore.test.extension')
+ eps2 = [ext.entry_point for ext in em2]
+ assert eps1[0] is eps2[0]
+
+
+def test_load_multiple_times_plugins():
+ # We expect to get the same plugin object (module or class)
+ # because the underlying import machinery will cache the values.
+ em1 = extension.ExtensionManager('stevedore.test.extension')
+ plugins1 = [ext.plugin for ext in em1]
+ em2 = extension.ExtensionManager('stevedore.test.extension')
+ plugins2 = [ext.plugin for ext in em2]
+ assert plugins1[0] is plugins2[0]
+
+
+def test_use_cache():
+ # If we insert something into the cache of entry points,
+ # the manager should not have to call into pkg_resources
+ # to find the plugins.
+ cache = extension.ExtensionManager.ENTRY_POINT_CACHE
+ cache['stevedore.test.faux'] = []
+ with mock.patch('pkg_resources.iter_entry_points',
+ side_effect=AssertionError('called iter_entry_points')):
+ em = extension.ExtensionManager('stevedore.test.faux')
+ names = em.names()
+ assert names == []
+
+
def test_iterable():
em = extension.ExtensionManager('stevedore.test.extension')
names = sorted(e.name for e in em)

0 comments on commit 2106ab5

Please sign in to comment.