From 6b452ff97f70eca79ab956987cc04b6586feca00 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 4 Mar 2020 17:04:38 -0800 Subject: [PATCH] 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. (cherry picked from commit 85cf1d514b84dc9a4bcb40e20a12e1d82ff19f20) Co-authored-by: Gregory P. Smith --- Lib/inspect.py | 2 +- .../next/Library/2020-03-04-16-10-59.bpo-13487.gqe4Fb.rst | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-03-04-16-10-59.bpo-13487.gqe4Fb.rst diff --git a/Lib/inspect.py b/Lib/inspect.py index 3ff395ca333..e8ea8c221f8 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -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): diff --git a/Misc/NEWS.d/next/Library/2020-03-04-16-10-59.bpo-13487.gqe4Fb.rst b/Misc/NEWS.d/next/Library/2020-03-04-16-10-59.bpo-13487.gqe4Fb.rst new file mode 100644 index 00000000000..5a1f02a7bdf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-04-16-10-59.bpo-13487.gqe4Fb.rst @@ -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`.