diff options
author | Brett Cannon <brettcannon@users.noreply.github.com> | 2018-04-06 23:10:18 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-06 23:10:18 (GMT) |
commit | 9e2be60634914f23db2ae5624e4acc9335bf5fea (patch) | |
tree | 9b1613b2c8bdad0fd942222c07a72e90e8dd509e /Lib | |
parent | 3a9ccee0e5dbf7d67f5ab79f6095755969db117c (diff) | |
download | cpython-9e2be60634914f23db2ae5624e4acc9335bf5fea.zip cpython-9e2be60634914f23db2ae5624e4acc9335bf5fea.tar.gz cpython-9e2be60634914f23db2ae5624e4acc9335bf5fea.tar.bz2 |
bpo-33169: Remove values of `None` from sys.path_importer_cache when invalidating caches (GH-6402)
An entry of None in sys.path_importer_cache represents a negative/missing finder for a path, so clearing it out makes sense.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/importlib/_bootstrap_external.py | 6 | ||||
-rw-r--r-- | Lib/test/test_importlib/import_/test_path.py | 21 | ||||
-rw-r--r-- | Lib/test/test_importlib/test_api.py | 2 |
3 files changed, 26 insertions, 3 deletions
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 420ecc8..da9a75c 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1181,8 +1181,10 @@ class PathFinder: def invalidate_caches(cls): """Call the invalidate_caches() method on all path entry finders stored in sys.path_importer_caches (where implemented).""" - for finder in sys.path_importer_cache.values(): - if hasattr(finder, 'invalidate_caches'): + for name, finder in list(sys.path_importer_cache.items()): + if finder is None: + del sys.path_importer_cache[name] + elif hasattr(finder, 'invalidate_caches'): finder.invalidate_caches() @classmethod diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py index 7aa26b0..18c81dd 100644 --- a/Lib/test/test_importlib/import_/test_path.py +++ b/Lib/test/test_importlib/import_/test_path.py @@ -184,6 +184,27 @@ class FinderTests: # Do not want FileNotFoundError raised. self.assertIsNone(self.machinery.PathFinder.find_spec('whatever')) + def test_invalidate_caches_finders(self): + # Finders with an invalidate_caches() method have it called. + class FakeFinder: + def __init__(self): + self.called = False + + def invalidate_caches(self): + self.called = True + + cache = {'leave_alone': object(), 'finder_to_invalidate': FakeFinder()} + with util.import_state(path_importer_cache=cache): + self.machinery.PathFinder.invalidate_caches() + self.assertTrue(cache['finder_to_invalidate'].called) + + def test_invalidate_caches_clear_out_None(self): + # Clear out None in sys.path_importer_cache() when invalidating caches. + cache = {'clear_out': None} + with util.import_state(path_importer_cache=cache): + self.machinery.PathFinder.invalidate_caches() + self.assertEqual(len(cache), 0) + class FindModuleTests(FinderTests): def find(self, *args, **kwargs): diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py index 8beb424..edb745c 100644 --- a/Lib/test/test_importlib/test_api.py +++ b/Lib/test/test_importlib/test_api.py @@ -406,7 +406,7 @@ class InvalidateCacheTests: # There should be no issues if the method is not defined. key = 'gobbledeegook' sys.path_importer_cache[key] = None - self.addCleanup(lambda: sys.path_importer_cache.__delitem__(key)) + self.addCleanup(lambda: sys.path_importer_cache.pop(key, None)) self.init.invalidate_caches() # Shouldn't trigger an exception. |