[Guido]
... I'm expecting (though don't have much proof) that most loops over dicts don't mutate the dict.
Safe bet! I do recall writing one once: it del'ed keys for which the associated count was 1, because the rest of the algorithm was only interested in duplicates.
Maybe we could add a flag to the dict that issues an error when a new key is inserted during such a for loop? (I don't think the key order can be affected when a key is *deleted*.)
That latter is true but specific to this implementation. "Can't mutate the dict period" is easier to keep straight, and probably harmless in practice (if not, it could be relaxed later). Recall that a similar trick is played during list.sort(), replacing the list's type pointer for the duration (to point to an internal "immutable list" type, same as the list type except the "dangerous" slots point to a function that raises an "immutable list" TypeError). Then no runtime expense is incurred for regular lists to keep checking flags. I thought of this as an elegant use for switching types at runtime; you may still be appalled by it, though!