Repository navigation
Fix RuntimeError when pretty-printing a dict mutated during iteration - #15471
Open
SakthivelMadhu wants to merge 1 commit into
Open
SakthivelMadhu wants to merge 1 commit into
SakthivelMadhu wants to merge 1 commit into
Conversation
Snapshot dict keys before iterating in _dict_pprinter_factory so that printing a value which mutates the dict (e.g. a module __dict__ gaining __builtins__ on first vars(posix)) no longer raises. Closes ipython#14541
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On the first
vars(posix)call, IPython raisesRuntimeError: dictionary changed size during iteration.Root cause
_dict_pprinter_factoryiterates over the liveobj.keys()view. While thevalues are being printed, the module's
__dict__gains__builtins__, so thedict changes size mid-iteration. On later calls the key already exists, which is
why only the first call fails.
Fix
Snapshot the keys with
list(obj.keys())before iterating. The output reflectsthe dict as it was when printing started.
Why not catch the error and retry: retrying hides the mutation and can loop;
a snapshot is deterministic. Cost is O(n) extra memory for the key list.
Tests
Added
test_dict_mutated_during_pretty_printing, which mutates the dict frominside a value's
__repr__.import posix; vars(posix)posixis unavailable)tests/test_pretty.py,tests/test_formatters.pyCloses #14541