Skip to content

Commit 875d0f5

Browse files
committed
remove our ordereddict code and make it an external dependency.
this brings our coverage percentage closer to reality.
1 parent 7e9438d commit 875d0f5

3 files changed

Lines changed: 6 additions & 265 deletions

File tree

setup.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55

66
install_requires = []
77

8+
try:
9+
from collections import OrderedDict
10+
except ImportError:
11+
install_requires.extend(['ordereddict>=1.1'])
12+
813
if 'develop' in sys.argv:
914
install_requires.extend([
1015
'tox',

textile/functions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
try:
3131
from collections import OrderedDict
3232
except ImportError:
33-
from textile.tools import OrderedDict
33+
from ordereddict import OrderedDict
3434

3535

3636
try:

textile/tools/__init__.py

Lines changed: 0 additions & 264 deletions
Original file line numberDiff line numberDiff line change
@@ -1,264 +0,0 @@
1-
# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
2-
# Passes Python2.7's test suite and incorporates all the latest updates.
3-
# taken from: http://code.activestate.com/recipes/576693/
4-
5-
try:
6-
# This will fail in versions that don't have OrderedDict
7-
from collections import OrderedDict
8-
9-
except ImportError:
10-
try:
11-
from thread import get_ident as _get_ident
12-
except ImportError:
13-
from dummy_thread import get_ident as _get_ident
14-
15-
try:
16-
from _abcoll import KeysView, ValuesView, ItemsView
17-
except ImportError:
18-
pass
19-
20-
21-
class OrderedDict(dict):
22-
'Dictionary that remembers insertion order'
23-
# An inherited dict maps keys to values.
24-
# The inherited dict provides __getitem__, __len__, __contains__, and get.
25-
# The remaining methods are order-aware.
26-
# Big-O running times for all methods are the same as for regular dictionaries.
27-
28-
# The internal self.__map dictionary maps keys to links in a doubly linked list.
29-
# The circular doubly linked list starts and ends with a sentinel element.
30-
# The sentinel element never gets deleted (this simplifies the algorithm).
31-
# Each link is stored as a list of length three: [PREV, NEXT, KEY].
32-
33-
def __init__(self, *args, **kwds):
34-
'''Initialize an ordered dictionary. Signature is the same as for
35-
regular dictionaries, but keyword arguments are not recommended
36-
because their insertion order is arbitrary.
37-
38-
'''
39-
if len(args) > 1:
40-
raise TypeError('expected at most 1 arguments, got %d' % len(args))
41-
try:
42-
self.__root
43-
except AttributeError:
44-
self.__root = root = [] # sentinel node
45-
root[:] = [root, root, None]
46-
self.__map = {}
47-
self.__update(*args, **kwds)
48-
49-
def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
50-
'od.__setitem__(i, y) <==> od[i]=y'
51-
# Setting a new item creates a new link which goes at the end of the linked
52-
# list, and the inherited dictionary is updated with the new key/value pair.
53-
if key not in self:
54-
root = self.__root
55-
last = root[0]
56-
last[1] = root[0] = self.__map[key] = [last, root, key]
57-
dict_setitem(self, key, value)
58-
59-
def __delitem__(self, key, dict_delitem=dict.__delitem__):
60-
'od.__delitem__(y) <==> del od[y]'
61-
# Deleting an existing item uses self.__map to find the link which is
62-
# then removed by updating the links in the predecessor and successor nodes.
63-
dict_delitem(self, key)
64-
link_prev, link_next, key = self.__map.pop(key)
65-
link_prev[1] = link_next
66-
link_next[0] = link_prev
67-
68-
def __iter__(self):
69-
'od.__iter__() <==> iter(od)'
70-
root = self.__root
71-
curr = root[1]
72-
while curr is not root:
73-
yield curr[2]
74-
curr = curr[1]
75-
76-
def __reversed__(self):
77-
'od.__reversed__() <==> reversed(od)'
78-
root = self.__root
79-
curr = root[0]
80-
while curr is not root:
81-
yield curr[2]
82-
curr = curr[0]
83-
84-
def clear(self):
85-
'od.clear() -> None. Remove all items from od.'
86-
try:
87-
for node in self.__map.itervalues():
88-
del node[:]
89-
root = self.__root
90-
root[:] = [root, root, None]
91-
self.__map.clear()
92-
except AttributeError:
93-
pass
94-
dict.clear(self)
95-
96-
def popitem(self, last=True):
97-
'''od.popitem() -> (k, v), return and remove a (key, value) pair.
98-
Pairs are returned in LIFO order if last is true or FIFO order if false.
99-
100-
'''
101-
if not self:
102-
raise KeyError('dictionary is empty')
103-
root = self.__root
104-
if last:
105-
link = root[0]
106-
link_prev = link[0]
107-
link_prev[1] = root
108-
root[0] = link_prev
109-
else:
110-
link = root[1]
111-
link_next = link[1]
112-
root[1] = link_next
113-
link_next[0] = root
114-
key = link[2]
115-
del self.__map[key]
116-
value = dict.pop(self, key)
117-
return key, value
118-
119-
# -- the following methods do not depend on the internal structure --
120-
121-
def keys(self):
122-
'od.keys() -> list of keys in od'
123-
return list(self)
124-
125-
def values(self):
126-
'od.values() -> list of values in od'
127-
return [self[key] for key in self]
128-
129-
def items(self):
130-
'od.items() -> list of (key, value) pairs in od'
131-
return [(key, self[key]) for key in self]
132-
133-
def iterkeys(self):
134-
'od.iterkeys() -> an iterator over the keys in od'
135-
return iter(self)
136-
137-
def itervalues(self):
138-
'od.itervalues -> an iterator over the values in od'
139-
for k in self:
140-
yield self[k]
141-
142-
def iteritems(self):
143-
'od.iteritems -> an iterator over the (key, value) items in od'
144-
for k in self:
145-
yield (k, self[k])
146-
147-
def update(*args, **kwds):
148-
'''od.update(E, **F) -> None. Update od from dict/iterable E and F.
149-
150-
If E is a dict instance, does: for k in E: od[k] = E[k]
151-
If E has a .keys() method, does: for k in E.keys(): od[k] = E[k]
152-
Or if E is an iterable of items, does: for k, v in E: od[k] = v
153-
In either case, this is followed by: for k, v in F.items(): od[k] = v
154-
155-
'''
156-
if len(args) > 2:
157-
raise TypeError('update() takes at most 2 positional '
158-
'arguments (%d given)' % (len(args),))
159-
elif not args:
160-
raise TypeError('update() takes at least 1 argument (0 given)')
161-
self = args[0]
162-
# Make progressively weaker assumptions about "other"
163-
other = ()
164-
if len(args) == 2:
165-
other = args[1]
166-
if isinstance(other, dict):
167-
for key in other:
168-
self[key] = other[key]
169-
elif hasattr(other, 'keys'):
170-
for key in other.keys():
171-
self[key] = other[key]
172-
else:
173-
for key, value in other:
174-
self[key] = value
175-
for key, value in kwds.items():
176-
self[key] = value
177-
178-
__update = update # let subclasses override update without breaking __init__
179-
180-
__marker = object()
181-
182-
def pop(self, key, default=__marker):
183-
'''od.pop(k[,d]) -> v, remove specified key and return the corresponding value.
184-
If key is not found, d is returned if given, otherwise KeyError is raised.
185-
186-
'''
187-
if key in self:
188-
result = self[key]
189-
del self[key]
190-
return result
191-
if default is self.__marker:
192-
raise KeyError(key)
193-
return default
194-
195-
def setdefault(self, key, default=None):
196-
'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
197-
if key in self:
198-
return self[key]
199-
self[key] = default
200-
return default
201-
202-
def __repr__(self, _repr_running={}):
203-
'od.__repr__() <==> repr(od)'
204-
call_key = id(self), _get_ident()
205-
if call_key in _repr_running:
206-
return '...'
207-
_repr_running[call_key] = 1
208-
try:
209-
if not self:
210-
return '%s()' % (self.__class__.__name__,)
211-
return '%s(%r)' % (self.__class__.__name__, self.items())
212-
finally:
213-
del _repr_running[call_key]
214-
215-
def __reduce__(self):
216-
'Return state information for pickling'
217-
items = [[k, self[k]] for k in self]
218-
inst_dict = vars(self).copy()
219-
for k in vars(OrderedDict()):
220-
inst_dict.pop(k, None)
221-
if inst_dict:
222-
return (self.__class__, (items,), inst_dict)
223-
return self.__class__, (items,)
224-
225-
def copy(self):
226-
'od.copy() -> a shallow copy of od'
227-
return self.__class__(self)
228-
229-
@classmethod
230-
def fromkeys(cls, iterable, value=None):
231-
'''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
232-
and values equal to v (which defaults to None).
233-
234-
'''
235-
d = cls()
236-
for key in iterable:
237-
d[key] = value
238-
return d
239-
240-
def __eq__(self, other):
241-
'''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
242-
while comparison to a regular mapping is order-insensitive.
243-
244-
'''
245-
if isinstance(other, OrderedDict):
246-
return len(self)==len(other) and self.items() == other.items()
247-
return dict.__eq__(self, other)
248-
249-
def __ne__(self, other):
250-
return not self == other
251-
252-
# -- the following methods are only used in Python 2.7 --
253-
254-
def viewkeys(self):
255-
"od.viewkeys() -> a set-like object providing a view on od's keys"
256-
return KeysView(self)
257-
258-
def viewvalues(self):
259-
"od.viewvalues() -> an object providing a view on od's values"
260-
return ValuesView(self)
261-
262-
def viewitems(self):
263-
"od.viewitems() -> a set-like object providing a view on od's items"
264-
return ItemsView(self)

0 commit comments

Comments
 (0)