-
Notifications
You must be signed in to change notification settings - Fork 11
/
tokenargs.py
172 lines (143 loc) · 5.41 KB
/
tokenargs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/bin/env python
# coding: utf-8
class tokenargs(object):
'''Wraps builtin list with checks for illegal characters in token arguments.'''
# Disallow these characters inside token arguments
illegal = '[]:'
# Replace simple inputs with illegal characters with their legal equivalents
replace = {
"':'": '58',
"'['": '91',
"']'": '93'
}
def __init__(self, items=None):
'''Construct a new list of token arguments.'''
self.list = list()
if items is not None: self.reset(items)
def __setitem__(self, item, value):
'''Set an item in the list.'''
self.list[item] = self.sanitize(value)
def __getitem__(self, item):
'''Get an item from the list.'''
result = self.list[item]
if isinstance(result, list):
return tokenargs(result)
else:
return result
def __delitem__(self, item):
'''Remove an item from the list.'''
del self.list[item]
def __str__(self):
'''Get a string representation.'''
return ':'.join(self.list)
def __add__(self, items):
'''Concatenate two lists of arguments.'''
result = tokenargs(self.list)
result.add(tokenargs(items))
return result
def __radd__(self, items):
'''Concatenate two lists of arguments.'''
return tokenargs(tokenargs(items) + self.list)
def __iadd__(self, item):
'''Add an item or items to the end of the list.'''
self.add(item)
return self
def __isub__(self, item):
'''Remove some number of items from the end of the list.'''
self.sub(item)
return self
def __contains__(self, item):
'''Check if the list contains an item.'''
try:
item = self.sanitize(item)
except:
return False
else:
return item in self.list
def __iter__(self):
'''Iterate through items in the list.'''
return self.list.__iter__()
def __len__(self):
'''Get the number of items in the list.'''
return self.list.__len__()
def __mul__(self, count):
'''Concatenate the list with itself some number of times.'''
return tokenargs(self.list * count)
def __imul__(self, count):
'''Concatenate the list with itself some number of times.'''
self.list *= count
return self
def __eq__(self, other):
'''Check equivalency with another list of arguments.'''
return len(self.list) == len(other) and all(self.list[index] == str(item) for index, item in enumerate(other))
def copy(self):
'''Make a copy of the argument list.'''
return tokenargs(self.list)
def reset(self, items):
'''Reset list to contain specified items.'''
if items is None:
self.clear()
elif isinstance(items, basestring):
self.reset(items.split(':'))
else:
self.list[:] = self.sanitize(items)
def set(self, index, item=None):
'''
Set a single argument given an index or, if no index is given, set
the argument at index 0.
'''
if item is None:
item = index
index = 0
self.list[index] = self.sanitize(item)
def clear(self):
'''Remove all items from the list.'''
del self.list[:]
def sanitize(self, value, replace=True):
'''
Internal: Utility method for sanitizing a string intended to be
evaluated as an arugment for a token.
'''
if isinstance(value, basestring):
value = str(value)
if replace and value in tokenargs.replace:
value = tokenargs.replace[value]
else:
if any([char in value for char in tokenargs.illegal]):
raise ValueError('Illegal character in argument %s.' % value)
return value
else:
try:
return (self.sanitize(item, replace) for item in value)
except:
return self.sanitize(str(value), replace)
def append(self, item):
'''Append a single item to the list.'''
self.list.append(self.sanitize(item))
def extend(self, items):
'''Append multiple items to the list.'''
if isinstance(items, basestring):
self.extend(items.split(':'))
else:
self.list.extend(self.sanitize(items))
def insert(self, index, item):
'''Insert an item at some index.'''
self.list.insert(index, self.sanitize(item))
def add(self, item, *args):
'''Add an item or items to the end of the list.'''
if isinstance(item, basestring):
self.extend(item.split(':'))
elif hasattr(item, '__iter__') or hasattr(item, '__getitem__'):
self.extend(item)
else:
self.add(str(item))
if args:
self.add(args)
def remove(self, item):
self.list.remove(self.sanitize(item))
def sub(self, item):
'''Remove some number of items from the end of the list.'''
try:
self.list[:] = self.list[:-item]
except:
self.remove(item)