10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""A more or less complete user-defined wrapper around dictionary objects."""
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass UserDict:
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, dict=None, **kwargs):
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.data = {}
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if dict is not None:
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.update(dict)
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if len(kwargs):
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.update(kwargs)
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __repr__(self): return repr(self.data)
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __cmp__(self, dict):
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if isinstance(dict, UserDict):
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return cmp(self.data, dict.data)
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return cmp(self.data, dict)
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    __hash__ = None # Avoid Py3k warning
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __len__(self): return len(self.data)
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __getitem__(self, key):
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if key in self.data:
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return self.data[key]
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if hasattr(self.__class__, "__missing__"):
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return self.__class__.__missing__(self, key)
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise KeyError(key)
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __setitem__(self, key, item): self.data[key] = item
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __delitem__(self, key): del self.data[key]
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def clear(self): self.data.clear()
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def copy(self):
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.__class__ is UserDict:
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return UserDict(self.data.copy())
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import copy
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        data = self.data
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.data = {}
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            c = copy.copy(self)
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.data = data
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        c.update(self)
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return c
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def keys(self): return self.data.keys()
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def items(self): return self.data.items()
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def iteritems(self): return self.data.iteritems()
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def iterkeys(self): return self.data.iterkeys()
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def itervalues(self): return self.data.itervalues()
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def values(self): return self.data.values()
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def has_key(self, key): return key in self.data
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def update(self, dict=None, **kwargs):
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if dict is None:
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif isinstance(dict, UserDict):
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.data.update(dict.data)
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif isinstance(dict, type({})) or not hasattr(dict, 'items'):
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.data.update(dict)
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for k, v in dict.items():
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self[k] = v
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if len(kwargs):
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.data.update(kwargs)
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def get(self, key, failobj=None):
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if key not in self:
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return failobj
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self[key]
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setdefault(self, key, failobj=None):
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if key not in self:
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self[key] = failobj
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self[key]
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def pop(self, key, *args):
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.data.pop(key, *args)
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def popitem(self):
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.data.popitem()
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __contains__(self, key):
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return key in self.data
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @classmethod
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def fromkeys(cls, iterable, value=None):
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = cls()
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for key in iterable:
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d[key] = value
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return d
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass IterableUserDict(UserDict):
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __iter__(self):
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return iter(self.data)
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport _abcoll
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_abcoll.MutableMapping.register(IterableUserDict)
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass DictMixin:
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Mixin defining all dictionary methods for classes that already have
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # a minimum dictionary interface including getitem, setitem, delitem,
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # and keys. Without knowledge of the subclass constructor, the mixin
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # does not define __init__() or copy().  In addition to the four base
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # methods, progressively more efficiency comes with defining
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # __contains__(), __iter__(), and iteritems().
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # second level definitions support higher levels
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __iter__(self):
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for k in self.keys():
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            yield k
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def has_key(self, key):
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self[key]
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except KeyError:
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return False
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return True
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __contains__(self, key):
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.has_key(key)
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # third level takes advantage of second level definitions
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def iteritems(self):
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for k in self:
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            yield (k, self[k])
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def iterkeys(self):
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.__iter__()
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # fourth level uses definitions from lower levels
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def itervalues(self):
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for _, v in self.iteritems():
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            yield v
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def values(self):
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return [v for _, v in self.iteritems()]
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def items(self):
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return list(self.iteritems())
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def clear(self):
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for key in self.keys():
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            del self[key]
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setdefault(self, key, default=None):
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return self[key]
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except KeyError:
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self[key] = default
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return default
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def pop(self, key, *args):
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if len(args) > 1:
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise TypeError, "pop expected at most 2 arguments, got "\
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              + repr(1 + len(args))
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            value = self[key]
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except KeyError:
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if args:
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return args[0]
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        del self[key]
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return value
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def popitem(self):
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            k, v = self.iteritems().next()
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except StopIteration:
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise KeyError, 'container is empty'
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        del self[k]
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return (k, v)
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def update(self, other=None, **kwargs):
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Make progressively weaker assumptions about "other"
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if other is None:
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif hasattr(other, 'iteritems'):  # iteritems saves memory and lookups
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for k, v in other.iteritems():
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self[k] = v
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif hasattr(other, 'keys'):
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for k in other.keys():
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self[k] = other[k]
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for k, v in other:
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self[k] = v
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if kwargs:
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.update(kwargs)
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def get(self, key, default=None):
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return self[key]
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except KeyError:
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return default
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __repr__(self):
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return repr(dict(self.iteritems()))
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __cmp__(self, other):
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if other is None:
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return 1
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if isinstance(other, DictMixin):
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            other = dict(other.iteritems())
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return cmp(dict(self.iteritems()), other)
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __len__(self):
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return len(self.keys())
181