[3.7] bpo-33169: Remove values of `None` from sys.path_importer_cache… · python/cpython@a09bb87

7 files changed

lines changed

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

Original file line numberDiff line numberDiff line change

@@ -561,7 +561,7 @@ importlib

561561

---------

562562
563563

The :class:`importlib.abc.ResourceReader` ABC was introduced to

564-

support the loading of resource from packages.

564+

support the loading of resources from packages.

565565
566566

locale

567567

------

@@ -1274,6 +1274,11 @@ Changes in the Python API

12741274

previous behaviour, or use

12751275

:attr:`STARTUPINFO.lpAttributeList <subprocess.STARTUPINFO.lpAttributeList>`.

12761276
1277+

* :meth:`importlib.machinery.PathFinder.invalidate_caches` -- which implicitly

1278+

affects :func:`importlib.invalidate_caches` -- now deletes entries

1279+

in :data:`sys.path_importer_cache` which are set to ``None``.

1280+

(Contributed by Brett Cannon in :issue:`33169`.)

1281+
12771282
12781283

Changes in the C API

12791284

--------------------

Original file line numberDiff line numberDiff line change

@@ -1179,8 +1179,10 @@ class PathFinder:

11791179

def invalidate_caches(cls):

11801180

"""Call the invalidate_caches() method on all path entry finders

11811181

stored in sys.path_importer_caches (where implemented)."""

1182-

for finder in sys.path_importer_cache.values():

1183-

if hasattr(finder, 'invalidate_caches'):

1182+

for name, finder in list(sys.path_importer_cache.items()):

1183+

if finder is None:

1184+

del sys.path_importer_cache[name]

1185+

elif hasattr(finder, 'invalidate_caches'):

11841186

finder.invalidate_caches()

11851187
11861188

@classmethod

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):

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
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.