I think the problem is here:
for color in self.domains[var]:
if not self._valid(var, color):
continue
self.map[var].color = color
for key in node.neighbors:
if color in self.domains[key]:
self.domains[key].remove(color) # This is potentially bad.
if key == var
when self.domains[key].remove(color)
is called, you change the size of the set you’re currently iterating over. You can avoid this by using
for color in self.domains[var].copy():
Using copy() will allow you to iterate over a copy of the set, while removing items from the original.