>> def __cmp__(self, other): >> if self is other: >> return 0 >> try: >> return cmp( (self._container.__class__.__name__, >> self._id), >> (other._container.__class__.__name__, >> other._id) ) >> except AttributeError: >> return cmp(self._id, other) >> >> Because, the id can be the same for different items in different >> containers. > > Be aware that this means that a change of class name could then hose > your BTree. I'd just re-run rebuild_indices ? > the reliable-stable-total ordering requirement should > apply to the entire "domain" of the __cmp__. Thanks for the recommendations... I have therefore decided to change the cmp function again: def __cmp__(self, other): if self is other: return 0 if other is None: return 1 return cmp(( self._container.__class__.__name__, self._id), (other._container.__class__.__name__, other._id)) Item must be added to the container (for _container and _id to be set) but this is in any case a pre-condition for the container to be able to compare items (strictly speaking it is not the container that is doing the comparing... just happens that the btree whose keys are to be compared is a member of the container). There may be a better way to do this, but should I change anything, all I will need to do is to rebuild the indices for the db. The "main" index, based on the integer id, is never touched by all this, allowing freedom to experiment with the other indices. I handle the None case specifically, because comparing two p_items, where one could be None (returned from a call, for example), will cause it to throw. But, now all other problems will be raised. mario