Add back list() when iterating over d.items() in a for statement #262
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.
Fix #176.
This reverts commit 8a1ef24 from #120. That commit’s commit message says, “For some reason, 2to3 only treats a for loop as a special context for iter* methods, so it will add a list() call to e.g.
for x in d.values()
.”There is a good reason that 2to3’s
fix_dict
considers for statements and for comprehensions a special context (wherelist()
is unnecessary) for iter dict methods but not list dict methods.fix_dict
is conservative in omittinglist()
ind.keys()
-->list(d.keys())
anditer()
ind.iterkeys()
-->iter(d.keys())
. For the list functions (python2’sd.keys()
,d.items()
,d.values()
), thelist
can be safely omitted if the result is consumed immediately by a function (e.g.sorted
). For the iterator functions (python2’sd.iterkeys()
,d.iteritems()
,d.itervalues()
), theiter
can be safely omitted from the view if the result is converted to an iterator or consumed immediately by a function or by a for statement or for comprehension.It is often incorrect to omit the
list()
when convertingfor x in d.items()
to python3 because if you omitlist()
, then adding or removing elements while iterating will raise “RuntimeError: dictionary changed size during iteration”. Example:Furthermore, the overridden
in_special_context
that considerskeys()
to be the same asiterkeys()
is incorrect because the super method implementation considersiter
to be a special context (where addingiter()
is not needed) whenisiter==True
. Soiter(d.keys())
should be converted toiter(list(d.keys()))
, not left unchanged as currently happens.