Hi everyone.
I made custom dictionaries (inheriting from python dict) logging and controling the setitem function (and other functions depending to it). Serious side-effects occur when comparing embedded custom dictionaries and SON objects: many calls to setitem are done, including some I forbid.
The reason is this peace of code in bson/son.py:
def __eq__(self, other): """Comparison to another SON is order-sensitive while comparison to a regular dictionary is order-insensitive. """ if isinstance(other, SON): return len(self) == len(other) and self.items() == other.items() return self.to_dict() == other
If the other object is also a SON, they are compared with order. But if it's not, the SON object is deeply converted to dict, performing so many calls to setitem !
So then, the SON object starts to modifying everything (making dirty side-effects everywhere), make costy operation before even comparing, whereas this small peace of code works well:
dict.__eq__(SON([('b',1),('a',2)]), {'b':1, 'a':2}) # -> True dict.__eq__(SON([('a',2),('b',1)]), {'b':1, 'a':2}) # -> True
This means that by comparing this way:
def __eq__(self, other): """Comparison to another SON is order-sensitive while comparison to a regular dictionary is order-insensitive. """ if isinstance(other, SON): return len(self) == len(other) and self.items() == other.items() return dict.__eq__(self, other)
Nobody is edited (avoiding dirty side-effects), comparison can be very fast if the two objects are really different, and comparison is order aware if when at a point both side are SON.