8000 bpo-33169: Remove values of `None` from sys.path_importer_cache when … · python/cpython@9e2be60 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9e2be60

Browse files
authored
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.
1 parent 3a9ccee commit 9e2be60

File tree

6 files changed

+652
-620
lines changed

6 files changed

+652
-620
lines changed

Doc/library/importlib.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,12 @@ find and load modules.
10811081
.. classmethod:: invalidate_caches()
10821082

10831083
Calls :meth:`importlib.abc.PathEntryFinder.invalidate_caches` on all
1084-
finders stored in :attr:`sys.path_importer_cache`.
1084+
finders stored in :data:`sys.path_importer_cache` that define the method.
1085+
Otherwise entries in :data:`sys.path_importer_cache` set to ``None`` are
1086+
deleted.
1087+
1088+
.. versionchanged:: 3.7
1089+
Entries of ``None`` in :data:`sys.path_importer_cache` are deleted.
10851090

10861091
.. versionchanged:: 3.4
10871092
Calls objects in :data:`sys.path_hooks` with the current working

Lib/importlib/_bootstrap_external.py

-2Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,8 +1181,10 @@ class PathFinder:
11811181
def invalidate_caches(cls):
11821182
"""Call the invalidate_caches() method on all path entry finders
11831183
stored in sys.path_importer_caches (where implemented)."""
1184-
for finder in sys.path_importer_cache.values():
1185-
if hasattr(finder, 'invalidate_caches'):
1184+
for name, finder in list(sys.path_importer_cache.items()):
1185+
if finder is None:
1186+
del sys.path_importer_cache[name]
1187+
elif hasattr(finder, 'invalidate_caches'):
11861188
finder.invalidate_caches()
11871189

11881190
@classmethod

Lib/test/test_importlib/import_/test_path.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,27 @@ def test_deleted_cwd(self):
184184
# Do not want FileNotFoundError raised.
185185
self.assertIsNone(self.machinery.PathFinder.find_spec('whatever'))
186186

187+
def test_invalidate_caches_finders(self):
188+
# Finders with an invalidate_caches() method have it called.
189+
class FakeFinder:
190+
def __init__(self):
191+
self.called = False
192+
193+
def invalidate_caches(self):
194+
self.called = True
195+
196+
cache = {'leave_alone': object(), 'finder_to_invalidate': FakeFinder()}
197+
with util.import_state(path_importer_cache=cache):
198+
self.machinery.PathFinder.invalidate_caches()
199+
self.assertTrue(cache['finder_to_invalidate'].called)
200+
201+
def test_invalidate_caches_clear_out_None(self):
202+
# Clear out None in sys.path_importer_cache() when invalidating caches.
203+
cache = {'clear_out': None}
204+
with util.import_state(path_importer_cache=cache):
205+
self.machinery.PathFinder.invalidate_caches()
206+
self.assertEqual(len(cache), 0)
207+
187208

188209
class FindModuleTests(FinderTests):
189210
def find(self, *args, **kwargs):

Lib/test/test_importlib/test_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ def test_method_lacking(self):
406406
# There should be no issues if the method is not defined.
407407
key = 'gobbledeegook'
408408
sys.path_importer_cache[key] = None
409-
self.addCleanup(lambda: sys.path_importer_cache.__delitem__(key))
409+
self.addCleanup(lambda: sys.path_importer_cache.pop(key, None))
410410
self.init.invalidate_caches() # Shouldn't trigger an exception.
411411

412412

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Delete entries of ``None`` in :data:`sys.path_importer_cache` when
2+
:meth:`importlib.machinery.invalidate_caches` is called.

0 commit comments

Comments
 (0)
0