From 143a3e9f0716690be7343d4d083f65d7624b3d2e Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 3 Oct 2022 16:14:50 +0100 Subject: [PATCH] Fix compatibility with Python 3.12, importlib-metadata 5.0 importlib-metadata 5.0 has removed support for dict-style interaction with entrypoints [1]. This is going to eventually affect us when Python 3.12 is released but even before then anyone not properly using upper constraints with an older Python 3.7-based release (the only Python version where we require the third-party importlib-metadata package rather than the stdlib importlib.metadata package) will be bitten. Fix it now to address both. [1] https://github.com/python/importlib_metadata/commit/dde2b9de2973ce1c6fa9ba21dfe81069b0baa77b Signed-off-by: Stephen Finucane Change-Id: Ib9c2b0a14edea91e97d122d2ac93b650029f918e Closes-Bug: #1991559 (cherry picked from commit 28fc7164dace83abc3ecc06fcb56f7ca880d735a) (cherry picked from commit 1e4d71d4b552494ff33ad03b76d2a590d58efe77) --- stevedore/_cache.py | 12 ++++++++++-- stevedore/tests/test_cache.py | 8 ++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/stevedore/_cache.py b/stevedore/_cache.py index d0574f5..288d740 100644 --- a/stevedore/_cache.py +++ b/stevedore/_cache.py @@ -103,8 +103,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(): @@ -159,7 +167,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/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)