I looked at it sometime ago, if I remember correctly the object is explored in a recursive fashion and an IdDict is used to keep track of which objects have already been seen so that to be able to preserve object identities.
Indeed I learnt it by incorrectly assuming that it worked as you thought as well : see Possible performance improvements for `deepcopy`?