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