source file: /System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/UserDict.py
file stats: 142 lines, 3 executed: 2.1% covered
   1. """A more or less complete user-defined wrapper around dictionary objects."""
   2. 
   3. class UserDict:
   4.     def __init__(self, dict=None, **kwargs):
   5.         self.data = {}
   6.         if dict is not None:
   7.             if not hasattr(dict,'keys'):
   8.                 dict = type({})(dict)   # make mapping from a sequence
   9.             self.update(dict)
  10.         if len(kwargs):
  11.             self.update(kwargs)
  12.     def __repr__(self): return repr(self.data)
  13.     def __cmp__(self, dict):
  14.         if isinstance(dict, UserDict):
  15.             return cmp(self.data, dict.data)
  16.         else:
  17.             return cmp(self.data, dict)
  18.     def __len__(self): return len(self.data)
  19.     def __getitem__(self, key): return self.data[key]
  20.     def __setitem__(self, key, item): self.data[key] = item
  21.     def __delitem__(self, key): del self.data[key]
  22.     def clear(self): self.data.clear()
  23.     def copy(self):
  24.         if self.__class__ is UserDict:
  25.             return UserDict(self.data)
  26.         import copy
  27.         data = self.data
  28.         try:
  29.             self.data = {}
  30.             c = copy.copy(self)
  31.         finally:
  32.             self.data = data
  33.         c.update(self)
  34.         return c
  35.     def keys(self): return self.data.keys()
  36.     def items(self): return self.data.items()
  37.     def iteritems(self): return self.data.iteritems()
  38.     def iterkeys(self): return self.data.iterkeys()
  39.     def itervalues(self): return self.data.itervalues()
  40.     def values(self): return self.data.values()
  41.     def has_key(self, key): return self.data.has_key(key)
  42.     def update(self, dict):
  43.         if isinstance(dict, UserDict):
  44.             self.data.update(dict.data)
  45.         elif isinstance(dict, type(self.data)):
  46.             self.data.update(dict)
  47.         else:
  48.             for k, v in dict.items():
  49.                 self[k] = v
  50.     def get(self, key, failobj=None):
  51.         if not self.has_key(key):
  52.             return failobj
  53.         return self[key]
  54.     def setdefault(self, key, failobj=None):
  55.         if not self.has_key(key):
  56.             self[key] = failobj
  57.         return self[key]
  58.     def pop(self, key, *args):
  59.         return self.data.pop(key, *args)
  60.     def popitem(self):
  61.         return self.data.popitem()
  62.     def __contains__(self, key):
  63.         return key in self.data
  64.     def fromkeys(cls, iterable, value=None):
  65.         d = cls()
  66.         for key in iterable:
  67.             d[key] = value
  68.         return d
  69.     fromkeys = classmethod(fromkeys)
  70. 
  71. class IterableUserDict(UserDict):
  72.     def __iter__(self):
  73.         return iter(self.data)
  74. 
  75. class DictMixin:
  76.     # Mixin defining all dictionary methods for classes that already have
  77.     # a minimum dictionary interface including getitem, setitem, delitem,
  78.     # and keys. Without knowledge of the subclass constructor, the mixin
  79.     # does not define __init__() or copy().  In addition to the four base
  80.     # methods, progressively more efficiency comes with defining
  81.     # __contains__(), __iter__(), and iteritems().
  82. 
  83.     # second level definitions support higher levels
  84.     def __iter__(self):
  85.         for k in self.keys():
  86.             yield k
  87.     def has_key(self, key):
  88.         try:
  89.             value = self[key]
  90.         except KeyError:
  91.             return False
  92.         return True
  93.     def __contains__(self, key):
  94.         return self.has_key(key)
  95. 
  96.     # third level takes advantage of second level definitions
  97.     def iteritems(self):
  98.         for k in self:
  99.             yield (k, self[k])
 100.     def iterkeys(self):
 101.         return self.__iter__()
 102. 
 103.     # fourth level uses definitions from lower levels
 104.     def itervalues(self):
 105.         for _, v in self.iteritems():
 106.             yield v
 107.     def values(self):
 108.         return [v for _, v in self.iteritems()]
 109.     def items(self):
 110.         return list(self.iteritems())
 111.     def clear(self):
 112.         for key in self.keys():
 113.             del self[key]
 114.     def setdefault(self, key, default):
 115.         try:
 116.             return self[key]
 117.         except KeyError:
 118.             self[key] = default
 119.         return default
 120.     def pop(self, key, *args):
 121.         if len(args) > 1:
 122.             raise TypeError, "pop expected at most 2 arguments, got "\
 123.                               + repr(1 + len(args))
 124.         try:
 125.             value = self[key]
 126.         except KeyError:
 127.             if args:
 128.                 return args[0]
 129.             raise
 130.         del self[key]
 131.         return value
 132.     def popitem(self):
 133.         try:
 134.             k, v = self.iteritems().next()
 135.         except StopIteration:
 136.             raise KeyError, 'container is empty'
 137.         del self[k]
 138.         return (k, v)
 139.     def update(self, other):
 140.         # Make progressively weaker assumptions about "other"
 141.         if hasattr(other, 'iteritems'):  # iteritems saves memory and lookups
 142.             for k, v in other.iteritems():
 143.                 self[k] = v
 144.         elif hasattr(other, '__iter__'): # iter saves memory
 145.             for k in other:
 146.                 self[k] = other[k]
 147.         else:
 148.             for k in other.keys():
 149.                 self[k] = other[k]
 150.     def get(self, key, default=None):
 151.         try:
 152.             return self[key]
 153.         except KeyError:
 154.             return default
 155.     def __repr__(self):
 156.         return repr(dict(self.iteritems()))
 157.     def __cmp__(self, other):
 158.         if other is None:
 159.             return 1
 160.         if isinstance(other, DictMixin):
 161.             other = dict(other.iteritems())
 162.         return cmp(dict(self.iteritems()), other)
 163.     def __len__(self):
 164.         return len(self.keys())