New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using OrderedDict.move_to_end during iteration is problematic. #68557
Comments
While the dict/OrderedDict iterators already check for additions and deletions, using the OrderedDict.move_to_end during iteration can lead to surprising results. The following results in an infinite loop: od = OrderedDict.fromkeys('abc')
last = None
for k in od:
if last is not None:
od.move_to_end(last)
last = k Ideally we could disallow changing order during iteration, just like we disallow deletion. Since we've gone 3 minor versions already, would it be too late to break backward compatibility on this point? |
The C version should defend itself against any key-changes during iteration (see the state counter used in deque objects for an example of how to do this). The pure python version of OrderedDict has only minimal defenses against mutating during iteration, and it should be left as-is. FWIW, "surprising" is in the eye of the beholder. When it comes to mutating containers during iteration, all kinds of things can happen (that is why databases implement reader and writer locks). The following results in an infinite loop: s = list('abc')
for k in s:
s.append(k) |
Sounds good. Thanks, Raymond. |
Here's a patch that tracks changes to the C OrderedDict linked list, similar to how it's done in deque. I've left the pure Python OrderedDict alone. @Raymond, that state counter works great. :) |
This patch looks correct. Go ahead and apply. |
New changeset 0d8679858272 by Eric Snow in branch '3.5': |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: