• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Misc dict tools."""
2
3
4__all__ = ['hashdict']
5
6# https://stackoverflow.com/questions/1151658/python-hashable-dicts
7class hashdict(dict):
8    """
9    hashable dict implementation, suitable for use as a key into
10    other dicts.
11
12        >>> h1 = hashdict({"apples": 1, "bananas":2})
13        >>> h2 = hashdict({"bananas": 3, "mangoes": 5})
14        >>> h1+h2
15        hashdict(apples=1, bananas=3, mangoes=5)
16        >>> d1 = {}
17        >>> d1[h1] = "salad"
18        >>> d1[h1]
19        'salad'
20        >>> d1[h2]
21        Traceback (most recent call last):
22        ...
23        KeyError: hashdict(bananas=3, mangoes=5)
24
25    based on answers from
26       http://stackoverflow.com/questions/1151658/python-hashable-dicts
27
28    """
29    def __key(self):
30        return tuple(sorted(self.items()))
31    def __repr__(self):
32        return "{0}({1})".format(self.__class__.__name__,
33            ", ".join("{0}={1}".format(
34                    str(i[0]),repr(i[1])) for i in self.__key()))
35
36    def __hash__(self):
37        return hash(self.__key())
38    def __setitem__(self, key, value):
39        raise TypeError("{0} does not support item assignment"
40                         .format(self.__class__.__name__))
41    def __delitem__(self, key):
42        raise TypeError("{0} does not support item assignment"
43                         .format(self.__class__.__name__))
44    def clear(self):
45        raise TypeError("{0} does not support item assignment"
46                         .format(self.__class__.__name__))
47    def pop(self, *args, **kwargs):
48        raise TypeError("{0} does not support item assignment"
49                         .format(self.__class__.__name__))
50    def popitem(self, *args, **kwargs):
51        raise TypeError("{0} does not support item assignment"
52                         .format(self.__class__.__name__))
53    def setdefault(self, *args, **kwargs):
54        raise TypeError("{0} does not support item assignment"
55                         .format(self.__class__.__name__))
56    def update(self, *args, **kwargs):
57        raise TypeError("{0} does not support item assignment"
58                         .format(self.__class__.__name__))
59    # update is not ok because it mutates the object
60    # __add__ is ok because it creates a new object
61    # while the new object is under construction, it's ok to mutate it
62    def __add__(self, right):
63        result = hashdict(self)
64        dict.update(result, right)
65        return result
66
67