diff options
-rw-r--r-- | doc/source/conf.py | 12 | ||||
-rw-r--r-- | releasenotes/source/conf.py | 16 | ||||
-rw-r--r-- | stevedore/_cache.py | 12 | ||||
-rw-r--r-- | stevedore/extension.py | 30 | ||||
-rw-r--r-- | stevedore/tests/test_cache.py | 8 |
5 files changed, 51 insertions, 27 deletions
diff --git a/doc/source/conf.py b/doc/source/conf.py index 5f3e370..8926b14 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -74,8 +74,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'stevedore' -copyright = u'2016, DreamHost' +project = 'stevedore' +copyright = '2016, DreamHost' # List of patterns, relative to source directory, that match files and @@ -107,8 +107,8 @@ latex_documents = [ ( 'index', 'stevedore.tex', - u'stevedore Documentation', - u'DreamHost', + 'stevedore Documentation', + 'DreamHost', 'manual' ), ] @@ -122,8 +122,8 @@ texinfo_documents = [ ( 'index', 'stevedore', - u'stevedore Documentation', - u'DreamHost', + 'stevedore Documentation', + 'DreamHost', 'stevedore', 'One line description of project.', 'Miscellaneous' diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py index 6d53444..1368071 100644 --- a/releasenotes/source/conf.py +++ b/releasenotes/source/conf.py @@ -60,8 +60,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'stevedore Release Notes' -copyright = u'2016, stevedore Developers' +project = 'stevedore Release Notes' +copyright = '2016, stevedore Developers' # Release do not need a version number in the title, they # cover multiple versions. @@ -208,8 +208,8 @@ latex_elements = { # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'stevedoreReleaseNotes.tex', - u'stevedore Release Notes Documentation', - u'stevedore Developers', 'manual'), + 'stevedore Release Notes Documentation', + 'stevedore Developers', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -239,8 +239,8 @@ latex_documents = [ # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'stevedoreReleaseNotes', - u'stevedore Release Notes Documentation', - [u'stevedore Developers'], 1) + 'stevedore Release Notes Documentation', + ['stevedore Developers'], 1) ] # If true, show URL addresses after external links. @@ -254,8 +254,8 @@ man_pages = [ # dir menu entry, description, category) texinfo_documents = [ ('index', 'stevedoreReleaseNotes', - u'stevedore Release Notes Documentation', - u'stevedore Developers', 'stevedoreReleaseNotes', + 'stevedore Release Notes Documentation', + 'stevedore Developers', 'stevedoreReleaseNotes', 'One line description of project.', 'Miscellaneous'), ] diff --git a/stevedore/_cache.py b/stevedore/_cache.py index 20b631d..6a76bc8 100644 --- a/stevedore/_cache.py +++ b/stevedore/_cache.py @@ -97,8 +97,16 @@ def _hash_settings_for_path(path): return (h.hexdigest(), paths) -def _build_cacheable_data(path): +def _build_cacheable_data(): real_groups = importlib_metadata.entry_points() + + if not isinstance(real_groups, dict): + # importlib-metadata 4.0 or later (or stdlib importlib.metadata in + # Python 3.9 or later) + real_groups = { + name: real_groups.select(name=name) for name in real_groups.names + } + # Convert the namedtuple values to regular tuples groups = {} for name, group_data in real_groups.items(): @@ -153,7 +161,7 @@ class Cache: with open(filename, 'r') as f: data = json.load(f) except (IOError, json.JSONDecodeError): - data = _build_cacheable_data(path) + data = _build_cacheable_data() data['path_values'] = path_values if not self._disable_caching: try: diff --git a/stevedore/extension.py b/stevedore/extension.py index 06ac067..d9ee084 100644 --- a/stevedore/extension.py +++ b/stevedore/extension.py @@ -61,17 +61,25 @@ class Extension(object): @property def extras(self): """The 'extras' settings for the plugin.""" - # NOTE: The underlying package returns re.Match objects for - # some reason. Translate those to the matched strings, which - # seem more useful. - return [ - # Python 3.6 returns _sre.SRE_Match objects. Later - # versions of python return re.Match objects. Both types - # have a 'string' attribute containing the text that - # matched the pattern. - getattr(e, 'string', e) - for e in self.entry_point.extras - ] + # NOTE: The underlying package returned re.Match objects until this was + # fixed in importlib-metadata 4.11.3. This was fixed in Python 3.10 and + # backported to Python 3.9.11. For older versions without this fix, + # translate the re.Match objects to the matched strings, which seem + # more useful. + extras = [] + for extra in self.entry_point.extras: + if isinstance(extra, str): + # We were previously returning the whole string including + # backets. We need to continue doing so to preserve API + # compatibility. + extras.append(f'[{extra}]') + else: + # Python 3.6 returns _sre.SRE_Match objects. Later + # versions of python return re.Match objects. Both types + # have a 'string' attribute containing the text that + # matched the pattern. + extras.append(getattr(extra, 'string', extra)) + return extras @property def attr(self): diff --git a/stevedore/tests/test_cache.py b/stevedore/tests/test_cache.py index 8bf49c8..0c5af67 100644 --- a/stevedore/tests/test_cache.py +++ b/stevedore/tests/test_cache.py @@ -54,3 +54,11 @@ class TestCache(utils.TestCase): mock_open.side_effect = IOError sot._get_data_for_path('fake') mock_mkdir.assert_not_called() + + def test__build_cacheable_data(self): + # this is a rubbish test as we don't actually do anything with the + # data, but it's too hard to script since it's totally environmentally + # dependent and mocking out the underlying calls would remove the value + # of this test (we want to test those underlying API calls) + ret = _cache._build_cacheable_data() + self.assertIsInstance(ret['groups'], dict) |