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
     25 -def generalupper(str):
     26      """this uses the object's upper method - works with string and unicode"""
     27      if str is None:
     28          return str
     29      return str.upper()
     30
     31
     32 -class cidict(dict):
     33
     34 -    def __init__(self, fromdict=None):
     35          """constructs the cidict, optionally using another dict to do so"""
     36          if fromdict is not None:
     37              self.update(fromdict)
     38
     39 -    def __getitem__(self, key):
     40          if type(key) != str and type(key) != unicode:
     41              raise TypeError("cidict can only have str or unicode as key (got %r)" % type(key))
     42          for akey in self.iterkeys():
     43              if akey.lower() == key.lower():
     44                  return dict.__getitem__(self, akey)
     45          raise IndexError
     46
     47 -    def __setitem__(self, key, value):
     48          if type(key) != str and type(key) != unicode:
     49              raise TypeError("cidict can only have str or unicode as key (got %r)" % type(key))
     50          for akey in self.iterkeys():
     51              if akey.lower() == key.lower():
     52                  return dict.__setitem__(self, akey, value)
     53          return dict.__setitem__(self, key, value)
     54
     55 -    def update(self, updatedict):
     56          """D.update(E) -> None.  Update D from E: for k in E.keys(): D[k] = E[k]"""
     57          for key, value in updatedict.iteritems():
     58              self[key] = value
     59
     60 -    def __delitem__(self, key):
     61          if type(key) != str and type(key) != unicode:
     62              raise TypeError("cidict can only have str or unicode as key (got %r)" % type(key))
     63          for akey in self.iterkeys():
     64              if akey.lower() == key.lower():
     65                  return dict.__delitem__(self, akey)
     66          raise IndexError
     67
     68 -    def __contains__(self, key):
     69          if type(key) != str and type(key) != unicode:
     70              raise TypeError("cidict can only have str or unicode as key (got %r)" % type(key))
     71          for akey in self.iterkeys():
     72              if akey.lower() == key.lower():
     73                  return 1
     74          return 0
     75
     76 -    def has_key(self, key):
     77          return self.__contains__(key)
     78
     79 -    def get(self, key, default=None):
     80          if self.has_key(key):
     81              return self[key]
     82          else:
     83              return default
     84
     85
     86 -class ordereddict(dict):
     87      """a dictionary which remembers its keys in the order in which they were given"""
     88
     89 -    def __init__(self, *args):
     90          if len(args) == 0:
     91              super(ordereddict, self).__init__()
     92              self.order = []
     93          elif len(args) > 1:
     94              raise TypeError("ordereddict() takes at most 1 argument (%d given)" % len(args))
     95          else:
     96              initarg = args[0]
     97              apply(super(ordereddict, self).__init__, args)
     98              if hasattr(initarg, "keys"):
     99                  self.order = initarg.keys()
    100              else:
    101                  # danger: could have duplicate keys...
    102                  self.order = []
    103                  checkduplicates = {}
    104                  for key, value in initarg:
    105                      if not key in checkduplicates:
    106                          self.order.append(key)
    107                          checkduplicates[key] = None
    108
    109 -    def __setitem__(self, key, value):
    110          alreadypresent = key in self
    111          result = dict.__setitem__(self, key, value)
    112          if not alreadypresent:
    113              self.order.append(key)
    114          return result
    115
    116 -    def update(self, updatedict):
    117          """D.update(E) -> None.  Update D from E: for k in E.keys(): D[k] = E[k]"""
    118          for key, value in updatedict.iteritems():
    119              self[key] = value
    120
    121 -    def __delitem__(self, key):
    122          alreadypresent = key in self
    123          result = dict.__delitem__(self, key)
    124          if alreadypresent:
    125              del self.order[self.order.index(key)]
    126          return result
    127
    128 -    def copy(self):
    129          """D.copy() -> a shallow copy of D"""
    130          thecopy = ordereddict(super(ordereddict, self).copy())
    131          thecopy.order = self.order[:]
    132          return thecopy
    133
    134 -    def items(self):
    135          """D.items() -> list of D's (key, value) pairs, as 2-tuples"""
    136          return [(key, self[key]) for key in self.order]
    137
    138 -    def iteritems(self):
    139          """D.iteritems() -> an iterator over the (key, value) items of D"""
    140          for key in self.order:
    141              yield (key, self[key])
    142
    143 -    def iterkeys(self):
    144          """D.iterkeys() -> an iterator over the keys of D"""
    145          for key in self.order:
    146              yield key
    147
    148      __iter__ = iterkeys
    149
    150 -    def itervalues(self):
    151          """D.itervalues() -> an iterator over the values of D"""
    152          for key in self.order:
    153              yield self[key]
    154
    155 -    def keys(self):
    156          """D.keys() -> list of D's keys"""
    157          return self.order[:]
    158
    159 -    def popitem(self):
    160          """D.popitem() -> (k, v), remove and return some (key, value) pair as a 2-tuple; but raise KeyError if D is empty"""
    161          if len(self.order) == 0:
    162              raise KeyError("popitem(): ordered dictionary is empty")
    163          k = self.order.pop()
    164          v = self[k]
    165          del self[k]
    166          return (k, v)
    167
    168 -    def pop(self, key):
    169          """remove entry from dict and internal list"""
    170          value = super(ordereddict, self).pop(key)
    171          del self.order[self.order.index(key)]
    172          return value
    173