Skip to content

Commit 4964bf2

Browse files
committed
Merge pull request #36 from splunk/fross-feature/ordereddict
Added ordereddict.py so Python 2.6 in Splunk 4.2 will work.
2 parents 43156b1 + a5dc397 commit 4964bf2

File tree

4 files changed

+181
-0
lines changed

4 files changed

+181
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
.coverage.*
88
__stdout__
99
docs/_build
10+
build/
1011
proxypid
1112
proxy.log
1213
MANIFEST

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ are enabled by Splunk's unique capabilities.
2121
The Splunk Software Development Kit for Python is licensed under the Apache
2222
License 2.0. Details can be found in the file LICENSE.
2323

24+
For compatibility with Python 2.6, The Splunk Software Development Kit
25+
for Python ships with ordereddict.py from the ordereddict package on
26+
PyPI (http://pypi.python.org/pypi/ordereddict/1.1) which is licensed
27+
under the MIT license (see the top of splunklib/ordereddict.py).
28+
2429
## Getting Started
2530

2631
In order to use the SDK you are going to need a copy of Splunk. If you don't

splunklib/ordereddict.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Copyright (c) 2009 Raymond Hettinger
2+
#
3+
# Permission is hereby granted, free of charge, to any person
4+
# obtaining a copy of this software and associated documentation files
5+
# (the "Software"), to deal in the Software without restriction,
6+
# including without limitation the rights to use, copy, modify, merge,
7+
# publish, distribute, sublicense, and/or sell copies of the Software,
8+
# and to permit persons to whom the Software is furnished to do so,
9+
# subject to the following conditions:
10+
#
11+
# The above copyright notice and this permission notice shall be
12+
# included in all copies or substantial portions of the Software.
13+
#
14+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21+
# OTHER DEALINGS IN THE SOFTWARE.
22+
23+
from UserDict import DictMixin
24+
25+
class OrderedDict(dict, DictMixin):
26+
27+
def __init__(self, *args, **kwds):
28+
if len(args) > 1:
29+
raise TypeError('expected at most 1 arguments, got %d' % len(args))
30+
try:
31+
self.__end
32+
except AttributeError:
33+
self.clear()
34+
self.update(*args, **kwds)
35+
36+
def clear(self):
37+
self.__end = end = []
38+
end += [None, end, end] # sentinel node for doubly linked list
39+
self.__map = {} # key --> [key, prev, next]
40+
dict.clear(self)
41+
42+
def __setitem__(self, key, value):
43+
if key not in self:
44+
end = self.__end
45+
curr = end[1]
46+
curr[2] = end[1] = self.__map[key] = [key, curr, end]
47+
dict.__setitem__(self, key, value)
48+
49+
def __delitem__(self, key):
50+
dict.__delitem__(self, key)
51+
key, prev, next = self.__map.pop(key)
52+
prev[2] = next
53+
next[1] = prev
54+
55+
def __iter__(self):
56+
end = self.__end
57+
curr = end[2]
58+
while curr is not end:
59+
yield curr[0]
60+
curr = curr[2]
61+
62+
def __reversed__(self):
63+
end = self.__end
64+
curr = end[1]
65+
while curr is not end:
66+
yield curr[0]
67+
curr = curr[1]
68+
69+
def popitem(self, last=True):
70+
if not self:
71+
raise KeyError('dictionary is empty')
72+
if last:
73+
key = reversed(self).next()
74+
else:
75+
key = iter(self).next()
76+
value = self.pop(key)
77+
return key, value
78+
79+
def __reduce__(self):
80+
items = [[k, self[k]] for k in self]
81+
tmp = self.__map, self.__end
82+
del self.__map, self.__end
83+
inst_dict = vars(self).copy()
84+
self.__map, self.__end = tmp
85+
if inst_dict:
86+
return (self.__class__, (items,), inst_dict)
87+
return self.__class__, (items,)
88+
89+
def keys(self):
90+
return list(self)
91+
92+
setdefault = DictMixin.setdefault
93+
update = DictMixin.update
94+
pop = DictMixin.pop
95+
values = DictMixin.values
96+
items = DictMixin.items
97+
iterkeys = DictMixin.iterkeys
98+
itervalues = DictMixin.itervalues
99+
iteritems = DictMixin.iteritems
100+
101+
def __repr__(self):
102+
if not self:
103+
return '%s()' % (self.__class__.__name__,)
104+
return '%s(%r)' % (self.__class__.__name__, self.items())
105+
106+
def copy(self):
107+
return self.__class__(self)
108+
109+
@classmethod
110+
def fromkeys(cls, iterable, value=None):
111+
d = cls()
112+
for key in iterable:
113+
d[key] = value
114+
return d
115+
116+
def __eq__(self, other):
117+
if isinstance(other, OrderedDict):
118+
if len(self) != len(other):
119+
return False
120+
for p, q in zip(self.items(), other.items()):
121+
if p != q:
122+
return False
123+
return True
124+
return dict.__eq__(self, other)
125+
126+
def __ne__(self, other):
127+
return not self == other

tests/streaming_results.xml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<results preview='1'>
2+
<meta>
3+
<fieldOrder>
4+
<field>count</field>
5+
</fieldOrder>
6+
</meta>
7+
<messages>
8+
<msg type="DEBUG">search context: user="admin", app="search", bs-pathname="/an/obviously/bogus/path/to/splunk/etc"</msg>
9+
</messages>
10+
11+
<result offset='0'>
12+
<field k='count'>
13+
<value><text>1</text></value>
14+
</field>
15+
</result>
16+
</results>
17+
<results preview='1'>
18+
<meta>
19+
<fieldOrder>
20+
<field>count</field>
21+
</fieldOrder>
22+
</meta>
23+
<messages>
24+
<msg type="DEBUG">search context: user="admin", app="search", bs-pathname="/an/obviously/bogus/path/to/splunk/etc"</msg>
25+
</messages>
26+
27+
<result offset='0'>
28+
<field k='count'>
29+
<value><text>3</text></value>
30+
</field>
31+
</result>
32+
</results>
33+
<results preview='1'>
34+
<meta>
35+
<fieldOrder>
36+
<field>count</field>
37+
</fieldOrder>
38+
</meta>
39+
<messages>
40+
<msg type="DEBUG">search context: user="admin", app="search", bs-pathname="/an/obviously/bogus/path/to/splunk/etc"</msg>
41+
</messages>
42+
43+
<result offset='0'>
44+
<field k='count'>
45+
<value><text>54</text></value>
46+
</field>
47+
</result>
48+
</results>

0 commit comments

Comments
 (0)