2 # -*- coding: utf-8 -*-
4 """Implements a case-insensitive (on keys) dictionary and order-sensitive dictionary"""
6 # Copyright 2002, 2003 St James Software
8 # This file is part of translate.
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.
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.
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
24 def generalupper(str):
25 """this uses the object's upper method - works with string and unicode"""
26 if str is None: return str
30 def __init__(self
, fromdict
= None):
31 """constructs the cidict, optionally using another dict to do so"""
32 if fromdict
is not None:
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
)
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
)
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():
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
)
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():
72 def has_key(self
, key
):
73 return self
.__contains
__(key
)
75 def get(self
, key
, default
=None):
81 class ordereddict(dict):
82 """a dictionary which remembers its keys in the order in which they were given"""
83 def __init__(self
, *args
):
85 super(ordereddict
, self
).__init
__()
88 raise TypeError("ordereddict() takes at most 1 argument (%d given)" % len(args
))
91 apply(super(ordereddict
, self
).__init
__, args
)
92 if hasattr(initarg
, "keys"):
93 self
.order
= initarg
.keys()
95 # danger: could have duplicate keys...
98 for key
, value
in initarg
:
99 if not key
in checkduplicates
:
100 self
.order
.append(key
)
101 checkduplicates
[key
] = None
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
)
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():
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
)]
121 """D.copy() -> a shallow copy of D"""
122 thecopy
= ordereddict(super(ordereddict
, self
).copy())
123 thecopy
.order
= self
.order
[:]
127 """D.items() -> list of D's (key, value) pairs, as 2-tuples"""
128 return [(key
, self
[key
]) for key
in self
.order
]
131 """D.iteritems() -> an iterator over the (key, value) items of D"""
132 for key
in self
.order
:
133 yield (key
, self
[key
])
136 """D.iterkeys() -> an iterator over the keys of D"""
137 for key
in self
.order
:
142 def itervalues(self
):
143 """D.itervalues() -> an iterator over the values of D"""
144 for key
in self
.order
:
148 """D.keys() -> list of D's keys"""
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")
161 """remove entry from dict and internal list"""
162 value
= super(ordereddict
, self
).pop(key
)
163 del self
.order
[self
.order
.index(key
)]