classification
Title: Python 3.6 change in dict iteration when inserting keys
Type: behavior Stage: resolved
Components: Versions: Python 3.6
process
Status: closed Resolution: duplicate
Dependencies: Superseder: Guard against changing dict during iteration
View: 19332
Assigned To: Nosy List: matthew.brett, r.david.murray
Priority: normal Keywords:

Created on 2017-02-02 14:10 by matthew.brett, last changed 2017-02-02 15:23 by matthew.brett. This issue is now closed.

Messages (3)
msg286794 - (view) Author: Matthew Brett (matthew.brett) Date: 2017-02-02 14:10
The behavior of dict iteration has changed in Python 3.6, in that inserting keys during iteration has a different and unpredictable affect.  For this code:

d = {'foo': 1}
for key in d:
   print(key)
   d.pop(key)
   d[key] = 1

Python 3.5 prints a single 'foo' (one pass through the loop).  Python 3.6 generates five lines of 'foo' (five passes through the loop).  Of course this code is pathological, but I found this behavior from a bug in code where the pathology was a lot less obvious - see https://github.com/nipy/nipy/issues/420
msg286797 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-02-02 14:38
This "bug" has always existed, its just that its manifestation has changed.  See issue 19332 for background.
msg286804 - (view) Author: Matthew Brett (matthew.brett) Date: 2017-02-02 15:23
To clarify from comments on issue 19332:

"""
* The normal rule (not just for Python) is that a data structures have undefined behavior for mutating while iterating, unless there is a specific guarantee
"""

The change in Python 3.6 is just a different undefined behavior.
History
Date User Action Args
2017-02-02 15:23:38matthew.brettsetmessages: + msg286804
2017-02-02 14:38:17r.david.murraysetstatus: open -> closed

superseder: Guard against changing dict during iteration

nosy: + r.david.murray
messages: + msg286797
resolution: duplicate
stage: resolved
2017-02-02 14:10:45matthew.brettcreate