Package translate :: Package misc :: Module dictutils

[hide private]
[frames] | no frames]

# Source Code for Module translate.misc.dictutils

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3
      4  """Implements a case-insensitive (on keys) dictionary and order-sensitive dictionary"""
      5
      6  # Copyright 2002, 2003 St James Software
      7  #
      8  # This file is part of translate.
      9  #
     10  # translate is free software; you can redistribute it and/or modify
     11  # it under the terms of the GNU General Public License as published by
     12  # the Free Software Foundation; either version 2 of the License, or
     13  # (at your option) any later version.
     14  #
     15  # translate is distributed in the hope that it will be useful,
     16  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  # GNU General Public License for more details.
     19  #
     20  # You should have received a copy of the GNU General Public License
     21  # along with translate; if not, write to the Free Software
     22  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     23
     24 -def generalupper(str):
     25      """this uses the object's upper method - works with string and unicode"""
     26      if str is None:
     27          return str
     28      return str.upper()
     29
     30 -class cidict(dict):
     31 -    def __init__(self, fromdict = None):
     32          """constructs the cidict, optionally using another dict to do so"""
     33          if fromdict is not None:
     34              self.update(fromdict)
     35
     36 -    def __getitem__(self, key):
     37          if type(key) != str and type(key) != unicode:
     38              raise TypeError, "cidict can only have str or unicode as key (got %r)" % type(key)
     39          for akey in self.iterkeys():
     40              if akey.lower() == key.lower():
     41                  return dict.__getitem__(self, akey)
     42          raise IndexError
     43
     44 -    def __setitem__(self, key, value):
     45          if type(key) != str and type(key) != unicode:
     46              raise TypeError, "cidict can only have str or unicode as key (got %r)" % type(key)
     47          for akey in self.iterkeys():
     48              if akey.lower() == key.lower():
     49                  return dict.__setitem__(self, akey, value)
     50          return dict.__setitem__(self, key, value)
     51
     52 -    def update(self, updatedict):
     53          """D.update(E) -> None.  Update D from E: for k in E.keys(): D[k] = E[k]"""
     54          for key, value in updatedict.iteritems():
     55              self[key] = value
     56
     57 -    def __delitem__(self, key):
     58          if type(key) != str and type(key) != unicode:
     59              raise TypeError, "cidict can only have str or unicode as key (got %r)" % type(key)
     60          for akey in self.iterkeys():
     61              if akey.lower() == key.lower():
     62                  return dict.__delitem__(self, akey)
     63          raise IndexError
     64
     65 -    def __contains__(self, key):
     66          if type(key) != str and type(key) != unicode:
     67              raise TypeError, "cidict can only have str or unicode as key (got %r)" % type(key)
     68          for akey in self.iterkeys():
     69              if akey.lower() == key.lower():
     70                  return 1
     71          return 0
     72
     73 -    def has_key(self, key):
     74          return self.__contains__(key)
     75
     76 -    def get(self, key, default=None):
     77          if self.has_key(key):
     78              return self[key]
     79          else:
     80              return default
     81
     82 -class ordereddict(dict):
     83      """a dictionary which remembers its keys in the order in which they were given"""
     84 -    def __init__(self, *args):
     85          if len(args) == 0:
     86              super(ordereddict, self).__init__()
     87              self.order = []
     88          elif len(args) > 1:
     89              raise TypeError("ordereddict() takes at most 1 argument (%d given)" % len(args))
     90          else:
     91              initarg = args[0]
     92              apply(super(ordereddict, self).__init__, args)
     93              if hasattr(initarg, "keys"):
     94                  self.order = initarg.keys()
     95              else:
     96                  # danger: could have duplicate keys...
     97                  self.order = []
     98                  checkduplicates = {}
     99                  for key, value in initarg:
    100                      if not key in checkduplicates:
    101                          self.order.append(key)
    102                          checkduplicates[key] = None
    103
    104 -    def __setitem__(self, key, value):
    105          alreadypresent = key in self
    106          result = dict.__setitem__(self, key, value)
    107          if not alreadypresent:
    108              self.order.append(key)
    109          return result
    110
    111 -    def update(self, updatedict):
    112          """D.update(E) -> None.  Update D from E: for k in E.keys(): D[k] = E[k]"""
    113          for key, value in updatedict.iteritems():
    114              self[key] = value
    115
    116 -    def __delitem__(self, key):
    117          alreadypresent = key in self
    118          result = dict.__delitem__(self, key)
    119          if alreadypresent:
    120              del self.order[self.order.index(key)]
    121          return result
    122
    123 -    def copy(self):
    124          """D.copy() -> a shallow copy of D"""
    125          thecopy = ordereddict(super(ordereddict, self).copy())
    126          thecopy.order = self.order[:]
    127          return thecopy
    128
    129 -    def items(self):
    130          """D.items() -> list of D's (key, value) pairs, as 2-tuples"""
    131          return [(key, self[key]) for key in self.order]
    132
    133 -    def iteritems(self):
    134          """D.iteritems() -> an iterator over the (key, value) items of D"""
    135          for key in self.order:
    136              yield (key, self[key])
    137
    138 -    def iterkeys(self):
    139          """D.iterkeys() -> an iterator over the keys of D"""
    140          for key in self.order:
    141              yield key
    142
    143      __iter__ = iterkeys
    144
    145 -    def itervalues(self):
    146          """D.itervalues() -> an iterator over the values of D"""
    147          for key in self.order:
    148              yield self[key]
    149
    150 -    def keys(self):
    151          """D.keys() -> list of D's keys"""
    152          return self.order[:]
    153
    154 -    def popitem(self):
    155          """D.popitem() -> (k, v), remove and return some (key, value) pair as a 2-tuple; but raise KeyError if D is empty"""
    156          if len(self.order) == 0:
    157              raise KeyError("popitem(): ordered dictionary is empty")
    158          k = self.order.pop()
    159          v = self[k]
    160          del self[k]
    161          return (k, v)
    162
    163 -    def pop(self, key):
    164          """remove entry from dict and internal list"""
    165          value = super(ordereddict, self).pop(key)
    166          del self.order[self.order.index(key)]
    167          return value
    168