summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2014-10-04 22:17:26 +0200
committerAntoine Pitrou <solipsis@pitrou.net>2014-10-04 22:17:26 +0200
commit5f6a7556bf3071cc1b1ad409cc3ae41379994df1 (patch)
tree10603bfd3e99b7101fa52acb75f83d61dff5a0e0
parent190517551b183c6e3cf2d333e2ccdcdf3f1d3655 (diff)
parente1618491adc5c0ef214c25d4e3b882e8586a2fee (diff)
downloadcpython-git-5f6a7556bf3071cc1b1ad409cc3ae41379994df1.tar.gz
Issue #21905: Avoid RuntimeError in pickle.whichmodule() when sys.modules is mutated while iterating.
Patch by Olivier Grisel.
-rw-r--r--Lib/pickle.py4
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
3 files changed, 7 insertions, 1 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py
index 3fc2596e67..663773f3d9 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -280,7 +280,9 @@ def whichmodule(obj, name, allow_qualname=False):
module_name = getattr(obj, '__module__', None)
if module_name is not None:
return module_name
- for module_name, module in sys.modules.items():
+ # Protect the iteration by using a list copy of sys.modules against dynamic
+ # modules that trigger imports of other modules upon calls to getattr.
+ for module_name, module in list(sys.modules.items()):
if module_name == '__main__' or module is None:
continue
try:
diff --git a/Misc/ACKS b/Misc/ACKS
index 84dfd024ab..ec8dc1ca81 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -498,6 +498,7 @@ Eddy De Greef
Grant Griffin
Andrea Griffini
Duncan Grisby
+Olivier Grisel
Fabian Groffen
Eric Groo
Dag Gruneau
diff --git a/Misc/NEWS b/Misc/NEWS
index 9e7efb9dfe..6b8ef3ec01 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -162,6 +162,9 @@ Core and Builtins
Library
-------
+- Issue #21905: Avoid RuntimeError in pickle.whichmodule() when sys.modules
+ is mutated while iterating. Patch by Olivier Grisel.
+
- Issue #11271: concurrent.futures.Executor.map() now takes a *chunksize*
argument to allow batching of tasks in child processes and improve
performance of ProcessPoolExecutor. Patch by Dan O'Reilly.