[3.13] gh-148660: Fix use-after-free in OrderedDict.copy() on reentrant mutation (GH-151573) (#152542)
OrderedDict.copy() walks the internal linked list while building the new
dict. The loop body can run arbitrary Python (a key's __eq__/__hash__, or
a subclass __getitem__/__setitem__) which can clear the source dict and
free the nodes being iterated.
Detect this the same way OrderedDict.__eq__ already does (gh-119004):
snapshot od_state before the loop, hold a strong reference to the key and
read the hash before any reentrant call, and raise RuntimeError if the
state changed before advancing to the next node.
(cherry picked from commit
7d128e319f3730e776a9161a4b5e9de95c802eaf)