bpo-13487: Use sys.modules.copy() in inspect.getmodule() for thread safety. (GH-18786)

`list(sys.modules.items())` was apparently not immune to "dictionary
changed size during iteration" errors.

Tested internally using an integration test that has run into this a couple of times in the past two years.  With this patch applied, the test is no longer flaky.
This commit is contained in:
Gregory P. Smith 2020-03-04 16:45:22 -08:00 committed by GitHub
parent d4a09c13dd
commit 85cf1d514b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 4 additions and 1 deletions

View File

@ -741,7 +741,7 @@ def getmodule(object, _filename=None):
return sys.modules.get(modulesbyfile[file])
# Update the filename to module name cache and check yet again
# Copy sys.modules in order to cope with changes while iterating
for modname, module in list(sys.modules.items()):
for modname, module in sys.modules.copy().items():
if ismodule(module) and hasattr(module, '__file__'):
f = module.__file__
if f == _filesbymodname.get(modname, None):

View File

@ -0,0 +1,3 @@
Avoid a possible *"RuntimeError: dictionary changed size during iteration"*
from :func:`inspect.getmodule` when it tried to loop through
:attr:`sys.modules`.