rapydscript-ns 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agignore +1 -0
- package/.gitattributes +4 -0
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/web-repl-page-deploy.yml +42 -0
- package/=template.pyj +5 -0
- package/CHANGELOG.md +456 -0
- package/CONTRIBUTORS +13 -0
- package/HACKING.md +103 -0
- package/LICENSE +24 -0
- package/README.md +2512 -0
- package/TODO.md +327 -0
- package/add-toc-to-readme +2 -0
- package/bin/export +75 -0
- package/bin/rapydscript +70 -0
- package/bin/web-repl-export +102 -0
- package/build +3 -0
- package/package.json +46 -0
- package/publish.py +37 -0
- package/release/baselib-plain-pretty.js +4370 -0
- package/release/baselib-plain-ugly.js +3 -0
- package/release/compiler.js +18394 -0
- package/release/signatures.json +31 -0
- package/session.vim +4 -0
- package/setup.cfg +2 -0
- package/src/ast.pyj +1356 -0
- package/src/baselib-builtins.pyj +279 -0
- package/src/baselib-containers.pyj +723 -0
- package/src/baselib-errors.pyj +37 -0
- package/src/baselib-internal.pyj +421 -0
- package/src/baselib-itertools.pyj +97 -0
- package/src/baselib-str.pyj +798 -0
- package/src/compiler.pyj +36 -0
- package/src/errors.pyj +30 -0
- package/src/lib/aes.pyj +646 -0
- package/src/lib/collections.pyj +695 -0
- package/src/lib/elementmaker.pyj +83 -0
- package/src/lib/encodings.pyj +126 -0
- package/src/lib/functools.pyj +148 -0
- package/src/lib/gettext.pyj +569 -0
- package/src/lib/itertools.pyj +580 -0
- package/src/lib/math.pyj +193 -0
- package/src/lib/numpy.pyj +2101 -0
- package/src/lib/operator.pyj +11 -0
- package/src/lib/pythonize.pyj +20 -0
- package/src/lib/random.pyj +118 -0
- package/src/lib/re.pyj +470 -0
- package/src/lib/traceback.pyj +63 -0
- package/src/lib/uuid.pyj +77 -0
- package/src/monaco-language-service/analyzer.js +526 -0
- package/src/monaco-language-service/builtins.js +543 -0
- package/src/monaco-language-service/completions.js +498 -0
- package/src/monaco-language-service/diagnostics.js +643 -0
- package/src/monaco-language-service/dts.js +550 -0
- package/src/monaco-language-service/hover.js +121 -0
- package/src/monaco-language-service/index.js +386 -0
- package/src/monaco-language-service/scope.js +162 -0
- package/src/monaco-language-service/signature.js +144 -0
- package/src/output/__init__.pyj +0 -0
- package/src/output/classes.pyj +296 -0
- package/src/output/codegen.pyj +492 -0
- package/src/output/comments.pyj +45 -0
- package/src/output/exceptions.pyj +105 -0
- package/src/output/functions.pyj +491 -0
- package/src/output/literals.pyj +109 -0
- package/src/output/loops.pyj +444 -0
- package/src/output/modules.pyj +329 -0
- package/src/output/operators.pyj +429 -0
- package/src/output/statements.pyj +463 -0
- package/src/output/stream.pyj +309 -0
- package/src/output/treeshake.pyj +182 -0
- package/src/output/utils.pyj +72 -0
- package/src/parse.pyj +3106 -0
- package/src/string_interpolation.pyj +72 -0
- package/src/tokenizer.pyj +702 -0
- package/src/unicode_aliases.pyj +576 -0
- package/src/utils.pyj +192 -0
- package/test/_import_one.pyj +37 -0
- package/test/_import_two/__init__.pyj +11 -0
- package/test/_import_two/level2/__init__.pyj +0 -0
- package/test/_import_two/level2/deep.pyj +4 -0
- package/test/_import_two/other.pyj +6 -0
- package/test/_import_two/sub.pyj +13 -0
- package/test/aes_vectors.pyj +421 -0
- package/test/annotations.pyj +80 -0
- package/test/baselib.pyj +319 -0
- package/test/classes.pyj +452 -0
- package/test/collections.pyj +152 -0
- package/test/decorators.pyj +77 -0
- package/test/dict_spread.pyj +76 -0
- package/test/docstrings.pyj +39 -0
- package/test/elementmaker_test.pyj +45 -0
- package/test/ellipsis.pyj +49 -0
- package/test/functions.pyj +151 -0
- package/test/generators.pyj +41 -0
- package/test/generic.pyj +370 -0
- package/test/imports.pyj +72 -0
- package/test/internationalization.pyj +73 -0
- package/test/lint.pyj +164 -0
- package/test/loops.pyj +85 -0
- package/test/numpy.pyj +734 -0
- package/test/omit_function_metadata.pyj +20 -0
- package/test/regexp.pyj +55 -0
- package/test/repl.pyj +121 -0
- package/test/scoped_flags.pyj +76 -0
- package/test/starargs.pyj +506 -0
- package/test/starred_assign.pyj +104 -0
- package/test/str.pyj +198 -0
- package/test/subscript_tuple.pyj +53 -0
- package/test/unit/fixtures/fibonacci_expected.js +46 -0
- package/test/unit/index.js +2989 -0
- package/test/unit/language-service-builtins.js +815 -0
- package/test/unit/language-service-completions.js +1067 -0
- package/test/unit/language-service-dts.js +543 -0
- package/test/unit/language-service-hover.js +455 -0
- package/test/unit/language-service-scope.js +833 -0
- package/test/unit/language-service-signature.js +458 -0
- package/test/unit/language-service.js +705 -0
- package/test/unit/run-language-service.js +41 -0
- package/test/unit/web-repl.js +484 -0
- package/tools/build-language-service.js +190 -0
- package/tools/cli.js +547 -0
- package/tools/compile.js +219 -0
- package/tools/compiler.js +108 -0
- package/tools/completer.js +131 -0
- package/tools/embedded_compiler.js +251 -0
- package/tools/export.js +316 -0
- package/tools/gettext.js +185 -0
- package/tools/ini.js +65 -0
- package/tools/lint.js +705 -0
- package/tools/msgfmt.js +187 -0
- package/tools/repl.js +223 -0
- package/tools/self.js +162 -0
- package/tools/test.js +118 -0
- package/tools/utils.js +128 -0
- package/tools/web_repl.js +95 -0
- package/try +41 -0
- package/web-repl/env.js +74 -0
- package/web-repl/index.html +163 -0
- package/web-repl/language-service.js +4084 -0
- package/web-repl/main.js +254 -0
- package/web-repl/prism.css +139 -0
- package/web-repl/prism.js +113 -0
- package/web-repl/rapydscript.js +435 -0
- package/web-repl/sha1.js +25 -0
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD
|
|
3
|
+
# RapydScript implementation of Python's collections standard library.
|
|
4
|
+
#
|
|
5
|
+
# Supported: namedtuple, deque, Counter, OrderedDict, defaultdict
|
|
6
|
+
#
|
|
7
|
+
# Note: Counter, OrderedDict, and defaultdict use __getitem__/__setitem__.
|
|
8
|
+
# For Python-compatible subscript syntax (obj[key]) in user code, add:
|
|
9
|
+
# from __python__ import overload_getitem
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def namedtuple(typename, field_names):
|
|
13
|
+
"""Return a new class with named fields, like Python's collections.namedtuple."""
|
|
14
|
+
if isinstance(field_names, str):
|
|
15
|
+
# Use explicit JS regex split for cross-environment safety
|
|
16
|
+
fields = v"field_names.replace(/,/g, ' ').trim().split(/\\s+/).filter(function(s){return s.length>0;})"
|
|
17
|
+
else:
|
|
18
|
+
fields = list(field_names)
|
|
19
|
+
n = fields.length
|
|
20
|
+
|
|
21
|
+
# Build the constructor using raw JS so we can use `instanceof` and `new`.
|
|
22
|
+
v"""
|
|
23
|
+
function constructor() {
|
|
24
|
+
if (!(this instanceof constructor)) {
|
|
25
|
+
var inst = Object.create(constructor.prototype);
|
|
26
|
+
constructor.apply(inst, arguments);
|
|
27
|
+
return inst;
|
|
28
|
+
}
|
|
29
|
+
var args = Array.prototype.slice.call(arguments);
|
|
30
|
+
// Strip trailing RapydScript kwargs sentinel if present
|
|
31
|
+
if (args.length > 0 && args[args.length-1] !== null && typeof args[args.length-1] === 'object' && args[args.length-1][ρσ_kwargs_symbol] === true) {
|
|
32
|
+
args = args.slice(0, -1);
|
|
33
|
+
}
|
|
34
|
+
if (args.length !== n) {
|
|
35
|
+
throw new TypeError(typename + '() takes ' + n + ' positional arguments but ' + args.length + ' were given');
|
|
36
|
+
}
|
|
37
|
+
for (var _i = 0; _i < n; _i++) {
|
|
38
|
+
this[fields[_i]] = args[_i];
|
|
39
|
+
this[_i] = args[_i];
|
|
40
|
+
}
|
|
41
|
+
this.length = n;
|
|
42
|
+
}
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
constructor.__name__ = typename
|
|
46
|
+
constructor._fields = fields
|
|
47
|
+
|
|
48
|
+
v"""constructor.prototype[Symbol.iterator] = function() {
|
|
49
|
+
var self = this, i = 0;
|
|
50
|
+
return {
|
|
51
|
+
next: function() {
|
|
52
|
+
if (i < n) return { value: self[fields[i++]], done: false };
|
|
53
|
+
return { value: undefined, done: true };
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
};"""
|
|
57
|
+
|
|
58
|
+
constructor.prototype._asdict = def():
|
|
59
|
+
d = {}
|
|
60
|
+
for f in fields:
|
|
61
|
+
d[f] = this[f]
|
|
62
|
+
return d
|
|
63
|
+
|
|
64
|
+
constructor.prototype._replace = def(**kwargs):
|
|
65
|
+
_self = this
|
|
66
|
+
args = []
|
|
67
|
+
for f in fields:
|
|
68
|
+
if f in kwargs:
|
|
69
|
+
args.push(kwargs[f])
|
|
70
|
+
else:
|
|
71
|
+
args.push(_self[f])
|
|
72
|
+
v"""var _inst = Object.create(constructor.prototype); constructor.apply(_inst, args); return _inst;"""
|
|
73
|
+
|
|
74
|
+
constructor.prototype.__repr__ = def():
|
|
75
|
+
_self = this
|
|
76
|
+
parts = [f + '=' + repr(_self[f]) for f in fields]
|
|
77
|
+
return typename + '(' + parts.join(', ') + ')'
|
|
78
|
+
|
|
79
|
+
constructor.prototype.__eq__ = def(other):
|
|
80
|
+
v"""if (!(other instanceof constructor)) return false;"""
|
|
81
|
+
for f in fields:
|
|
82
|
+
if this[f] is not other[f]:
|
|
83
|
+
return False
|
|
84
|
+
return True
|
|
85
|
+
|
|
86
|
+
constructor.prototype.__getitem__ = def(i):
|
|
87
|
+
if i < 0:
|
|
88
|
+
i = n + i
|
|
89
|
+
if i < 0 or i >= n:
|
|
90
|
+
raise IndexError('index out of range')
|
|
91
|
+
return this[fields[i]]
|
|
92
|
+
|
|
93
|
+
constructor._make = def(iterable):
|
|
94
|
+
args = list(iterable)
|
|
95
|
+
v"""var _inst = Object.create(constructor.prototype); constructor.apply(_inst, args); return _inst;"""
|
|
96
|
+
|
|
97
|
+
return constructor
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class deque:
|
|
101
|
+
"""Double-ended queue with optional maximum length."""
|
|
102
|
+
|
|
103
|
+
def __init__(self, iterable=None, maxlen=None):
|
|
104
|
+
self._data = []
|
|
105
|
+
self._maxlen = maxlen
|
|
106
|
+
if iterable is not None:
|
|
107
|
+
for item in iterable:
|
|
108
|
+
self.append(item)
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def maxlen(self):
|
|
112
|
+
return self._maxlen
|
|
113
|
+
|
|
114
|
+
def _trim_left(self):
|
|
115
|
+
if self._maxlen is not None:
|
|
116
|
+
while len(self._data) > self._maxlen:
|
|
117
|
+
self._data.shift()
|
|
118
|
+
|
|
119
|
+
def _trim_right(self):
|
|
120
|
+
if self._maxlen is not None:
|
|
121
|
+
while len(self._data) > self._maxlen:
|
|
122
|
+
self._data.pop()
|
|
123
|
+
|
|
124
|
+
def append(self, x):
|
|
125
|
+
self._data.push(x)
|
|
126
|
+
self._trim_left()
|
|
127
|
+
|
|
128
|
+
def appendleft(self, x):
|
|
129
|
+
self._data.unshift(x)
|
|
130
|
+
self._trim_right()
|
|
131
|
+
|
|
132
|
+
def extend(self, iterable):
|
|
133
|
+
for item in iterable:
|
|
134
|
+
self.append(item)
|
|
135
|
+
|
|
136
|
+
def extendleft(self, iterable):
|
|
137
|
+
for item in iterable:
|
|
138
|
+
self.appendleft(item)
|
|
139
|
+
|
|
140
|
+
def pop(self):
|
|
141
|
+
if not self._data.length:
|
|
142
|
+
raise IndexError('pop from an empty deque')
|
|
143
|
+
return self._data.pop()
|
|
144
|
+
|
|
145
|
+
def popleft(self):
|
|
146
|
+
if not self._data.length:
|
|
147
|
+
raise IndexError('pop from an empty deque')
|
|
148
|
+
return self._data.shift()
|
|
149
|
+
|
|
150
|
+
def rotate(self, n=1):
|
|
151
|
+
size = len(self._data)
|
|
152
|
+
if size == 0:
|
|
153
|
+
return
|
|
154
|
+
n = n % size
|
|
155
|
+
if n == 0:
|
|
156
|
+
return
|
|
157
|
+
if n > 0:
|
|
158
|
+
for i in range(n):
|
|
159
|
+
self._data.unshift(self._data.pop())
|
|
160
|
+
else:
|
|
161
|
+
for i in range(-n):
|
|
162
|
+
self._data.push(self._data.shift())
|
|
163
|
+
|
|
164
|
+
def clear(self):
|
|
165
|
+
self._data = []
|
|
166
|
+
|
|
167
|
+
def copy(self):
|
|
168
|
+
return deque(self._data, self._maxlen)
|
|
169
|
+
|
|
170
|
+
def count(self, x):
|
|
171
|
+
c = 0
|
|
172
|
+
for item in self._data:
|
|
173
|
+
if item == x:
|
|
174
|
+
c += 1
|
|
175
|
+
return c
|
|
176
|
+
|
|
177
|
+
def remove(self, value):
|
|
178
|
+
for i in range(len(self._data)):
|
|
179
|
+
if self._data[i] == value:
|
|
180
|
+
self._data.splice(i, 1)
|
|
181
|
+
return
|
|
182
|
+
raise ValueError(repr(value) + ' is not in deque')
|
|
183
|
+
|
|
184
|
+
def reverse(self):
|
|
185
|
+
self._data.reverse()
|
|
186
|
+
|
|
187
|
+
def index(self, x, start=0, stop=None):
|
|
188
|
+
if stop is None:
|
|
189
|
+
stop = len(self._data)
|
|
190
|
+
for i in range(start, stop):
|
|
191
|
+
if self._data[i] == x:
|
|
192
|
+
return i
|
|
193
|
+
raise ValueError(repr(x) + ' is not in deque')
|
|
194
|
+
|
|
195
|
+
def insert(self, i, x):
|
|
196
|
+
if self._maxlen is not None and len(self._data) >= self._maxlen:
|
|
197
|
+
raise IndexError('deque already at its maximum size')
|
|
198
|
+
self._data.splice(i, 0, x)
|
|
199
|
+
|
|
200
|
+
def __len__(self):
|
|
201
|
+
return self._data.length
|
|
202
|
+
|
|
203
|
+
def __getitem__(self, i):
|
|
204
|
+
size = len(self._data)
|
|
205
|
+
if i < 0:
|
|
206
|
+
i += size
|
|
207
|
+
if i < 0 or i >= size:
|
|
208
|
+
raise IndexError('deque index out of range')
|
|
209
|
+
return self._data[i]
|
|
210
|
+
|
|
211
|
+
def __setitem__(self, i, value):
|
|
212
|
+
size = len(self._data)
|
|
213
|
+
if i < 0:
|
|
214
|
+
i += size
|
|
215
|
+
if i < 0 or i >= size:
|
|
216
|
+
raise IndexError('deque index out of range')
|
|
217
|
+
self._data[i] = value
|
|
218
|
+
|
|
219
|
+
def __contains__(self, x):
|
|
220
|
+
for item in self._data:
|
|
221
|
+
if item == x:
|
|
222
|
+
return True
|
|
223
|
+
return False
|
|
224
|
+
|
|
225
|
+
def __iter__(self):
|
|
226
|
+
return iter(self._data)
|
|
227
|
+
|
|
228
|
+
def __repr__(self):
|
|
229
|
+
if self._maxlen is not None:
|
|
230
|
+
return 'deque(' + repr(list(self._data)) + ', maxlen=' + str(self._maxlen) + ')'
|
|
231
|
+
return 'deque(' + repr(list(self._data)) + ')'
|
|
232
|
+
|
|
233
|
+
def __eq__(self, other):
|
|
234
|
+
if not isinstance(other, deque):
|
|
235
|
+
return False
|
|
236
|
+
if len(self._data) != len(other._data):
|
|
237
|
+
return False
|
|
238
|
+
for i in range(len(self._data)):
|
|
239
|
+
if self._data[i] != other._data[i]:
|
|
240
|
+
return False
|
|
241
|
+
return True
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class Counter:
|
|
245
|
+
"""Dict subclass for counting hashable objects."""
|
|
246
|
+
|
|
247
|
+
def __init__(self, iterable=None, **kwargs):
|
|
248
|
+
self._data = {}
|
|
249
|
+
if iterable is not None:
|
|
250
|
+
if isinstance(iterable, Counter):
|
|
251
|
+
for k in iterable._data:
|
|
252
|
+
self._data[k] = (self._data[k] or 0) + iterable._data[k]
|
|
253
|
+
elif isinstance(iterable, OrderedDict) or isinstance(iterable, defaultdict):
|
|
254
|
+
src = iterable._data
|
|
255
|
+
for k in src:
|
|
256
|
+
self._data[k] = (self._data[k] or 0) + src[k]
|
|
257
|
+
elif jstype(iterable) is 'object' and not Array.isArray(iterable):
|
|
258
|
+
for k in Object.keys(iterable):
|
|
259
|
+
self._data[k] = (self._data[k] or 0) + iterable[k]
|
|
260
|
+
else:
|
|
261
|
+
for item in iterable:
|
|
262
|
+
key = str(item)
|
|
263
|
+
self._data[key] = (self._data[key] or 0) + 1
|
|
264
|
+
for k in kwargs:
|
|
265
|
+
self._data[k] = (self._data[k] or 0) + kwargs[k]
|
|
266
|
+
|
|
267
|
+
def __getitem__(self, key):
|
|
268
|
+
return self._data[key] or 0
|
|
269
|
+
|
|
270
|
+
def __setitem__(self, key, value):
|
|
271
|
+
self._data[key] = value
|
|
272
|
+
|
|
273
|
+
def __delitem__(self, key):
|
|
274
|
+
v'delete this._data[key]'
|
|
275
|
+
|
|
276
|
+
def __contains__(self, key):
|
|
277
|
+
return key in self._data and self._data[key] != 0
|
|
278
|
+
|
|
279
|
+
def __len__(self):
|
|
280
|
+
return Object.keys(self._data).length
|
|
281
|
+
|
|
282
|
+
def __iter__(self):
|
|
283
|
+
return iter(Object.keys(self._data))
|
|
284
|
+
|
|
285
|
+
def __repr__(self):
|
|
286
|
+
items = [[k, self._data[k]] for k in self._data]
|
|
287
|
+
pairs = [repr(p[0]) + ': ' + repr(p[1]) for p in items]
|
|
288
|
+
return 'Counter({' + pairs.join(', ') + '})'
|
|
289
|
+
|
|
290
|
+
def __eq__(self, other):
|
|
291
|
+
if not isinstance(other, Counter):
|
|
292
|
+
return False
|
|
293
|
+
keys_a = Object.keys(self._data)
|
|
294
|
+
keys_b = Object.keys(other._data)
|
|
295
|
+
if keys_a.length != keys_b.length:
|
|
296
|
+
return False
|
|
297
|
+
for k in keys_a:
|
|
298
|
+
if self._data[k] != other._data[k]:
|
|
299
|
+
return False
|
|
300
|
+
return True
|
|
301
|
+
|
|
302
|
+
def get(self, key, dflt=None):
|
|
303
|
+
if key in self._data:
|
|
304
|
+
return self._data[key]
|
|
305
|
+
return dflt
|
|
306
|
+
|
|
307
|
+
def keys(self):
|
|
308
|
+
return Object.keys(self._data)
|
|
309
|
+
|
|
310
|
+
def values(self):
|
|
311
|
+
return Object.values(self._data)
|
|
312
|
+
|
|
313
|
+
def items(self):
|
|
314
|
+
return [[k, self._data[k]] for k in self._data]
|
|
315
|
+
|
|
316
|
+
def update(self, iterable=None, **kwargs):
|
|
317
|
+
if iterable is not None:
|
|
318
|
+
if isinstance(iterable, Counter):
|
|
319
|
+
for k in iterable._data:
|
|
320
|
+
self._data[k] = (self._data[k] or 0) + iterable._data[k]
|
|
321
|
+
elif isinstance(iterable, OrderedDict) or isinstance(iterable, defaultdict):
|
|
322
|
+
src = iterable._data
|
|
323
|
+
for k in src:
|
|
324
|
+
self._data[k] = (self._data[k] or 0) + src[k]
|
|
325
|
+
elif jstype(iterable) is 'object' and not Array.isArray(iterable):
|
|
326
|
+
for k in Object.keys(iterable):
|
|
327
|
+
self._data[k] = (self._data[k] or 0) + iterable[k]
|
|
328
|
+
else:
|
|
329
|
+
for item in iterable:
|
|
330
|
+
key = str(item)
|
|
331
|
+
self._data[key] = (self._data[key] or 0) + 1
|
|
332
|
+
for k in kwargs:
|
|
333
|
+
self._data[k] = (self._data[k] or 0) + kwargs[k]
|
|
334
|
+
|
|
335
|
+
def subtract(self, iterable=None, **kwargs):
|
|
336
|
+
if iterable is not None:
|
|
337
|
+
if isinstance(iterable, Counter):
|
|
338
|
+
for k in iterable._data:
|
|
339
|
+
self._data[k] = (self._data[k] or 0) - iterable._data[k]
|
|
340
|
+
elif isinstance(iterable, OrderedDict) or isinstance(iterable, defaultdict):
|
|
341
|
+
src = iterable._data
|
|
342
|
+
for k in src:
|
|
343
|
+
self._data[k] = (self._data[k] or 0) - src[k]
|
|
344
|
+
elif jstype(iterable) is 'object' and not Array.isArray(iterable):
|
|
345
|
+
for k in Object.keys(iterable):
|
|
346
|
+
self._data[k] = (self._data[k] or 0) - iterable[k]
|
|
347
|
+
else:
|
|
348
|
+
for item in iterable:
|
|
349
|
+
key = str(item)
|
|
350
|
+
self._data[key] = (self._data[key] or 0) - 1
|
|
351
|
+
for k in kwargs:
|
|
352
|
+
self._data[k] = (self._data[k] or 0) - kwargs[k]
|
|
353
|
+
|
|
354
|
+
def most_common(self, n=None):
|
|
355
|
+
items = [[k, self._data[k]] for k in self._data]
|
|
356
|
+
items.pysort(key=def(pair): return -pair[1];)
|
|
357
|
+
if n is not None:
|
|
358
|
+
return items[:n]
|
|
359
|
+
return items
|
|
360
|
+
|
|
361
|
+
def elements(self):
|
|
362
|
+
result = []
|
|
363
|
+
for k in self._data:
|
|
364
|
+
count = self._data[k]
|
|
365
|
+
for i in range(max(0, count)):
|
|
366
|
+
result.push(k)
|
|
367
|
+
return iter(result)
|
|
368
|
+
|
|
369
|
+
def total(self):
|
|
370
|
+
s = 0
|
|
371
|
+
for k in self._data:
|
|
372
|
+
s += self._data[k]
|
|
373
|
+
return s
|
|
374
|
+
|
|
375
|
+
def copy(self):
|
|
376
|
+
c = Counter()
|
|
377
|
+
for k in self._data:
|
|
378
|
+
c._data[k] = self._data[k]
|
|
379
|
+
return c
|
|
380
|
+
|
|
381
|
+
def clear(self):
|
|
382
|
+
self._data = {}
|
|
383
|
+
|
|
384
|
+
def pop(self, key, *rest):
|
|
385
|
+
if key in self._data:
|
|
386
|
+
val = self._data[key]
|
|
387
|
+
v'delete this._data[key]'
|
|
388
|
+
return val
|
|
389
|
+
if len(rest) > 0:
|
|
390
|
+
return rest[0]
|
|
391
|
+
raise KeyError(repr(key))
|
|
392
|
+
|
|
393
|
+
def __add__(self, other):
|
|
394
|
+
result = Counter()
|
|
395
|
+
all_keys = Object.keys(self._data).concat(Object.keys(other._data))
|
|
396
|
+
for k in all_keys:
|
|
397
|
+
val = (self._data[k] or 0) + (other._data[k] or 0)
|
|
398
|
+
if val > 0:
|
|
399
|
+
result._data[k] = val
|
|
400
|
+
return result
|
|
401
|
+
|
|
402
|
+
def __sub__(self, other):
|
|
403
|
+
result = Counter()
|
|
404
|
+
for k in self._data:
|
|
405
|
+
val = (self._data[k] or 0) - (other._data[k] or 0)
|
|
406
|
+
if val > 0:
|
|
407
|
+
result._data[k] = val
|
|
408
|
+
return result
|
|
409
|
+
|
|
410
|
+
def __or__(self, other):
|
|
411
|
+
result = Counter()
|
|
412
|
+
all_keys = Object.keys(self._data).concat(Object.keys(other._data))
|
|
413
|
+
for k in all_keys:
|
|
414
|
+
val = max(self._data[k] or 0, other._data[k] or 0)
|
|
415
|
+
if val > 0:
|
|
416
|
+
result._data[k] = val
|
|
417
|
+
return result
|
|
418
|
+
|
|
419
|
+
def __and__(self, other):
|
|
420
|
+
result = Counter()
|
|
421
|
+
for k in self._data:
|
|
422
|
+
if k in other._data:
|
|
423
|
+
val = min(self._data[k] or 0, other._data[k] or 0)
|
|
424
|
+
if val > 0:
|
|
425
|
+
result._data[k] = val
|
|
426
|
+
return result
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
class OrderedDict:
|
|
430
|
+
"""Dict that remembers insertion order and supports move_to_end / popitem."""
|
|
431
|
+
|
|
432
|
+
def __init__(self, iterable=None, **kwargs):
|
|
433
|
+
self._keys = []
|
|
434
|
+
self._data = {}
|
|
435
|
+
if iterable is not None:
|
|
436
|
+
if isinstance(iterable, OrderedDict):
|
|
437
|
+
for k in iterable._keys:
|
|
438
|
+
self._set(k, iterable._data[k])
|
|
439
|
+
elif jstype(iterable) is 'object' and not Array.isArray(iterable):
|
|
440
|
+
for k in Object.keys(iterable):
|
|
441
|
+
self._set(k, iterable[k])
|
|
442
|
+
else:
|
|
443
|
+
for pair in iterable:
|
|
444
|
+
self._set(pair[0], pair[1])
|
|
445
|
+
for k in kwargs:
|
|
446
|
+
self._set(k, kwargs[k])
|
|
447
|
+
|
|
448
|
+
def _set(self, key, value):
|
|
449
|
+
if key not in self._data:
|
|
450
|
+
self._keys.push(key)
|
|
451
|
+
self._data[key] = value
|
|
452
|
+
|
|
453
|
+
def __setitem__(self, key, value):
|
|
454
|
+
self._set(key, value)
|
|
455
|
+
|
|
456
|
+
def __getitem__(self, key):
|
|
457
|
+
if key not in self._data:
|
|
458
|
+
raise KeyError(repr(key))
|
|
459
|
+
return self._data[key]
|
|
460
|
+
|
|
461
|
+
def __delitem__(self, key):
|
|
462
|
+
if key not in self._data:
|
|
463
|
+
raise KeyError(repr(key))
|
|
464
|
+
v'delete this._data[key]'
|
|
465
|
+
idx = self._keys.indexOf(key)
|
|
466
|
+
if idx != -1:
|
|
467
|
+
self._keys.splice(idx, 1)
|
|
468
|
+
|
|
469
|
+
def __contains__(self, key):
|
|
470
|
+
return key in self._data
|
|
471
|
+
|
|
472
|
+
def __len__(self):
|
|
473
|
+
return self._keys.length
|
|
474
|
+
|
|
475
|
+
def __iter__(self):
|
|
476
|
+
return iter(list(self._keys))
|
|
477
|
+
|
|
478
|
+
def __repr__(self):
|
|
479
|
+
pairs = ['(' + repr(k) + ', ' + repr(self._data[k]) + ')' for k in self._keys]
|
|
480
|
+
return 'OrderedDict([' + pairs.join(', ') + '])'
|
|
481
|
+
|
|
482
|
+
def __eq__(self, other):
|
|
483
|
+
if isinstance(other, OrderedDict):
|
|
484
|
+
if self._keys.length != other._keys.length:
|
|
485
|
+
return False
|
|
486
|
+
for i in range(len(self._keys)):
|
|
487
|
+
if self._keys[i] != other._keys[i]:
|
|
488
|
+
return False
|
|
489
|
+
k = self._keys[i]
|
|
490
|
+
if self._data[k] != other._data[k]:
|
|
491
|
+
return False
|
|
492
|
+
return True
|
|
493
|
+
if jstype(other) is 'object' and not Array.isArray(other) and not isinstance(other, OrderedDict):
|
|
494
|
+
keys_b = Object.keys(other)
|
|
495
|
+
if self._keys.length != keys_b.length:
|
|
496
|
+
return False
|
|
497
|
+
for k in self._keys:
|
|
498
|
+
if k not in other or self._data[k] != other[k]:
|
|
499
|
+
return False
|
|
500
|
+
return True
|
|
501
|
+
return False
|
|
502
|
+
|
|
503
|
+
def get(self, key, dflt=None):
|
|
504
|
+
if key in self._data:
|
|
505
|
+
return self._data[key]
|
|
506
|
+
return dflt
|
|
507
|
+
|
|
508
|
+
def keys(self):
|
|
509
|
+
return list(self._keys)
|
|
510
|
+
|
|
511
|
+
def values(self):
|
|
512
|
+
return [self._data[k] for k in self._keys]
|
|
513
|
+
|
|
514
|
+
def items(self):
|
|
515
|
+
return [[k, self._data[k]] for k in self._keys]
|
|
516
|
+
|
|
517
|
+
def pop(self, key, *rest):
|
|
518
|
+
if key in self._data:
|
|
519
|
+
val = self._data[key]
|
|
520
|
+
del self[key]
|
|
521
|
+
return val
|
|
522
|
+
if len(rest) > 0:
|
|
523
|
+
return rest[0]
|
|
524
|
+
raise KeyError(repr(key))
|
|
525
|
+
|
|
526
|
+
def popitem(self, last=True):
|
|
527
|
+
if not self._keys.length:
|
|
528
|
+
raise KeyError('dictionary is empty')
|
|
529
|
+
k = self._keys.pop() if last else self._keys.shift()
|
|
530
|
+
val = self._data[k]
|
|
531
|
+
v'delete this._data[k]'
|
|
532
|
+
return [k, val]
|
|
533
|
+
|
|
534
|
+
def move_to_end(self, key, last=True):
|
|
535
|
+
if key not in self._data:
|
|
536
|
+
raise KeyError(repr(key))
|
|
537
|
+
idx = self._keys.indexOf(key)
|
|
538
|
+
self._keys.splice(idx, 1)
|
|
539
|
+
if last:
|
|
540
|
+
self._keys.push(key)
|
|
541
|
+
else:
|
|
542
|
+
self._keys.unshift(key)
|
|
543
|
+
|
|
544
|
+
def update(self, other=None, **kwargs):
|
|
545
|
+
if other is not None:
|
|
546
|
+
if isinstance(other, OrderedDict):
|
|
547
|
+
for k in other._keys:
|
|
548
|
+
self._set(k, other._data[k])
|
|
549
|
+
elif jstype(other) is 'object' and not Array.isArray(other):
|
|
550
|
+
for k in Object.keys(other):
|
|
551
|
+
self._set(k, other[k])
|
|
552
|
+
else:
|
|
553
|
+
for pair in other:
|
|
554
|
+
self._set(pair[0], pair[1])
|
|
555
|
+
for k in kwargs:
|
|
556
|
+
self._set(k, kwargs[k])
|
|
557
|
+
|
|
558
|
+
def setdefault(self, key, dflt=None):
|
|
559
|
+
if key not in self._data:
|
|
560
|
+
self._set(key, dflt)
|
|
561
|
+
return self._data[key]
|
|
562
|
+
|
|
563
|
+
def clear(self):
|
|
564
|
+
self._keys = []
|
|
565
|
+
self._data = {}
|
|
566
|
+
|
|
567
|
+
def copy(self):
|
|
568
|
+
return OrderedDict(self)
|
|
569
|
+
|
|
570
|
+
def fromkeys(self, keys, value=None):
|
|
571
|
+
od = OrderedDict()
|
|
572
|
+
for k in keys:
|
|
573
|
+
od._set(k, value)
|
|
574
|
+
return od
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
class defaultdict:
|
|
578
|
+
"""Dict subclass that calls a factory for missing keys."""
|
|
579
|
+
|
|
580
|
+
def __init__(self, default_factory=None, iterable=None, **kwargs):
|
|
581
|
+
self.default_factory = default_factory
|
|
582
|
+
self._data = {}
|
|
583
|
+
if iterable is not None:
|
|
584
|
+
if isinstance(iterable, defaultdict):
|
|
585
|
+
for k in iterable._data:
|
|
586
|
+
self._data[k] = iterable._data[k]
|
|
587
|
+
elif jstype(iterable) is 'object' and not Array.isArray(iterable):
|
|
588
|
+
for k in Object.keys(iterable):
|
|
589
|
+
self._data[k] = iterable[k]
|
|
590
|
+
else:
|
|
591
|
+
for pair in iterable:
|
|
592
|
+
self._data[pair[0]] = pair[1]
|
|
593
|
+
for k in kwargs:
|
|
594
|
+
self._data[k] = kwargs[k]
|
|
595
|
+
|
|
596
|
+
def __missing__(self, key):
|
|
597
|
+
if self.default_factory is None:
|
|
598
|
+
raise KeyError(repr(key))
|
|
599
|
+
val = self.default_factory()
|
|
600
|
+
self._data[key] = val
|
|
601
|
+
return val
|
|
602
|
+
|
|
603
|
+
def __getitem__(self, key):
|
|
604
|
+
if key not in self._data:
|
|
605
|
+
return self.__missing__(key)
|
|
606
|
+
return self._data[key]
|
|
607
|
+
|
|
608
|
+
def __setitem__(self, key, value):
|
|
609
|
+
self._data[key] = value
|
|
610
|
+
|
|
611
|
+
def __delitem__(self, key):
|
|
612
|
+
if key not in self._data:
|
|
613
|
+
raise KeyError(repr(key))
|
|
614
|
+
v'delete this._data[key]'
|
|
615
|
+
|
|
616
|
+
def __contains__(self, key):
|
|
617
|
+
return key in self._data
|
|
618
|
+
|
|
619
|
+
def __len__(self):
|
|
620
|
+
return Object.keys(self._data).length
|
|
621
|
+
|
|
622
|
+
def __iter__(self):
|
|
623
|
+
return iter(Object.keys(self._data))
|
|
624
|
+
|
|
625
|
+
def __repr__(self):
|
|
626
|
+
parts = [repr(k) + ': ' + repr(self._data[k]) for k in self._data]
|
|
627
|
+
fname = self.default_factory.name if self.default_factory else 'None'
|
|
628
|
+
return 'defaultdict(' + fname + ', {' + parts.join(', ') + '})'
|
|
629
|
+
|
|
630
|
+
def get(self, key, dflt=None):
|
|
631
|
+
if key in self._data:
|
|
632
|
+
return self._data[key]
|
|
633
|
+
return dflt
|
|
634
|
+
|
|
635
|
+
def keys(self):
|
|
636
|
+
return Object.keys(self._data)
|
|
637
|
+
|
|
638
|
+
def values(self):
|
|
639
|
+
return Object.values(self._data)
|
|
640
|
+
|
|
641
|
+
def items(self):
|
|
642
|
+
return [[k, self._data[k]] for k in self._data]
|
|
643
|
+
|
|
644
|
+
def pop(self, key, *rest):
|
|
645
|
+
if key in self._data:
|
|
646
|
+
val = self._data[key]
|
|
647
|
+
v'delete this._data[key]'
|
|
648
|
+
return val
|
|
649
|
+
if len(rest) > 0:
|
|
650
|
+
return rest[0]
|
|
651
|
+
raise KeyError(repr(key))
|
|
652
|
+
|
|
653
|
+
def setdefault(self, key, dflt=None):
|
|
654
|
+
if key not in self._data:
|
|
655
|
+
self._data[key] = dflt
|
|
656
|
+
return self._data[key]
|
|
657
|
+
|
|
658
|
+
def update(self, other=None, **kwargs):
|
|
659
|
+
if other is not None:
|
|
660
|
+
if isinstance(other, defaultdict):
|
|
661
|
+
for k in other._data:
|
|
662
|
+
self._data[k] = other._data[k]
|
|
663
|
+
elif jstype(other) is 'object' and not Array.isArray(other):
|
|
664
|
+
for k in Object.keys(other):
|
|
665
|
+
self._data[k] = other[k]
|
|
666
|
+
else:
|
|
667
|
+
for pair in other:
|
|
668
|
+
self._data[pair[0]] = pair[1]
|
|
669
|
+
for k in kwargs:
|
|
670
|
+
self._data[k] = kwargs[k]
|
|
671
|
+
|
|
672
|
+
def clear(self):
|
|
673
|
+
self._data = {}
|
|
674
|
+
|
|
675
|
+
def copy(self):
|
|
676
|
+
d = defaultdict(self.default_factory)
|
|
677
|
+
for k in self._data:
|
|
678
|
+
d._data[k] = self._data[k]
|
|
679
|
+
return d
|
|
680
|
+
|
|
681
|
+
def __eq__(self, other):
|
|
682
|
+
if isinstance(other, defaultdict):
|
|
683
|
+
src = other._data
|
|
684
|
+
elif jstype(other) is 'object' and not Array.isArray(other) and not isinstance(other, defaultdict):
|
|
685
|
+
src = other
|
|
686
|
+
else:
|
|
687
|
+
return False
|
|
688
|
+
keys_a = Object.keys(self._data)
|
|
689
|
+
keys_b = Object.keys(src)
|
|
690
|
+
if keys_a.length != keys_b.length:
|
|
691
|
+
return False
|
|
692
|
+
for k in keys_a:
|
|
693
|
+
if self._data[k] != src[k]:
|
|
694
|
+
return False
|
|
695
|
+
return True
|