rapydscript-ns 0.8.3 → 0.9.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/CHANGELOG.md +26 -0
- package/README.md +1351 -141
- package/TODO.md +12 -6
- package/language-service/index.js +184 -26
- package/package.json +1 -1
- package/release/baselib-plain-pretty.js +5895 -1928
- package/release/baselib-plain-ugly.js +140 -3
- package/release/compiler.js +16282 -5408
- package/release/signatures.json +25 -22
- package/src/ast.pyj +94 -1
- package/src/baselib-builtins.pyj +362 -3
- package/src/baselib-bytes.pyj +664 -0
- package/src/baselib-containers.pyj +99 -0
- package/src/baselib-errors.pyj +45 -1
- package/src/baselib-internal.pyj +346 -49
- package/src/baselib-itertools.pyj +17 -4
- package/src/baselib-str.pyj +46 -4
- package/src/lib/abc.pyj +317 -0
- package/src/lib/copy.pyj +120 -0
- package/src/lib/dataclasses.pyj +532 -0
- package/src/lib/enum.pyj +125 -0
- package/src/lib/pythonize.pyj +1 -1
- package/src/lib/re.pyj +35 -1
- package/src/lib/react.pyj +74 -0
- package/src/lib/typing.pyj +577 -0
- package/src/monaco-language-service/builtins.js +19 -4
- package/src/monaco-language-service/diagnostics.js +40 -19
- package/src/output/classes.pyj +161 -25
- package/src/output/codegen.pyj +16 -2
- package/src/output/exceptions.pyj +97 -1
- package/src/output/functions.pyj +87 -5
- package/src/output/jsx.pyj +164 -0
- package/src/output/literals.pyj +28 -2
- package/src/output/loops.pyj +5 -2
- package/src/output/modules.pyj +1 -1
- package/src/output/operators.pyj +108 -36
- package/src/output/statements.pyj +2 -2
- package/src/output/stream.pyj +1 -0
- package/src/parse.pyj +496 -128
- package/src/tokenizer.pyj +38 -4
- package/test/abc.pyj +291 -0
- package/test/arithmetic_nostrict.pyj +88 -0
- package/test/arithmetic_types.pyj +169 -0
- package/test/baselib.pyj +91 -0
- package/test/bytes.pyj +467 -0
- package/test/classes.pyj +1 -0
- package/test/comparison_ops.pyj +173 -0
- package/test/dataclasses.pyj +253 -0
- package/test/enum.pyj +134 -0
- package/test/eval_exec.pyj +56 -0
- package/test/format.pyj +148 -0
- package/test/object.pyj +64 -0
- package/test/python_compat.pyj +17 -15
- package/test/python_features.pyj +89 -21
- package/test/regexp.pyj +29 -1
- package/test/tuples.pyj +96 -0
- package/test/typing.pyj +469 -0
- package/test/unit/index.js +2292 -70
- package/test/unit/language-service.js +674 -4
- package/test/unit/web-repl.js +1106 -0
- package/test/vars_locals_globals.pyj +94 -0
- package/tools/cli.js +11 -0
- package/tools/compile.js +5 -0
- package/tools/embedded_compiler.js +15 -4
- package/tools/lint.js +16 -19
- package/tools/repl.js +1 -1
- package/web-repl/env.js +122 -0
- package/web-repl/main.js +1 -3
- package/web-repl/rapydscript.js +125 -3
- package/PYTHON_DIFFERENCES_REPORT.md +0 -291
- package/PYTHON_FEATURE_COVERAGE.md +0 -200
- package/hack_demo.pyj +0 -112
|
@@ -0,0 +1,664 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD
|
|
3
|
+
|
|
4
|
+
# globals: exports, console, ρσ_iterator_symbol, ρσ_arraylike, ρσ_str, ρσ_slice
|
|
5
|
+
|
|
6
|
+
# ---------------------------------------------------------------------------
|
|
7
|
+
# Encoding helpers
|
|
8
|
+
# ---------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
def ρσ_bytes_utf8_encode(s):
|
|
11
|
+
if v'typeof TextEncoder !== "undefined"':
|
|
12
|
+
return v'Array.from(new TextEncoder().encode(s))'
|
|
13
|
+
out = []
|
|
14
|
+
for v'var i = 0; i < s.length; i++':
|
|
15
|
+
c = s.charCodeAt(i)
|
|
16
|
+
if c < 0x80:
|
|
17
|
+
out.push(c)
|
|
18
|
+
elif c < 0x800:
|
|
19
|
+
out.push(0xC0 | (c >> 6))
|
|
20
|
+
out.push(0x80 | (c & 0x3F))
|
|
21
|
+
elif c >= 0xD800 and c <= 0xDBFF:
|
|
22
|
+
i += 1
|
|
23
|
+
c2 = s.charCodeAt(i)
|
|
24
|
+
cp = 0x10000 + ((c - 0xD800) << 10) + (c2 - 0xDC00)
|
|
25
|
+
out.push(0xF0 | (cp >> 18))
|
|
26
|
+
out.push(0x80 | ((cp >> 12) & 0x3F))
|
|
27
|
+
out.push(0x80 | ((cp >> 6) & 0x3F))
|
|
28
|
+
out.push(0x80 | (cp & 0x3F))
|
|
29
|
+
else:
|
|
30
|
+
out.push(0xE0 | (c >> 12))
|
|
31
|
+
out.push(0x80 | ((c >> 6) & 0x3F))
|
|
32
|
+
out.push(0x80 | (c & 0x3F))
|
|
33
|
+
return out
|
|
34
|
+
|
|
35
|
+
def ρσ_bytes_utf8_decode(data):
|
|
36
|
+
if v'typeof TextDecoder !== "undefined"':
|
|
37
|
+
return v'new TextDecoder("utf-8").decode(new Uint8Array(data))'
|
|
38
|
+
out = []
|
|
39
|
+
i = 0
|
|
40
|
+
while i < data.length:
|
|
41
|
+
b = data[i]
|
|
42
|
+
if b < 0x80:
|
|
43
|
+
out.push(String.fromCharCode(b))
|
|
44
|
+
i += 1
|
|
45
|
+
elif b < 0xE0:
|
|
46
|
+
cp = ((b & 0x1F) << 6) | (data[i + 1] & 0x3F)
|
|
47
|
+
out.push(String.fromCharCode(cp))
|
|
48
|
+
i += 2
|
|
49
|
+
elif b < 0xF0:
|
|
50
|
+
cp = ((b & 0x0F) << 12) | ((data[i + 1] & 0x3F) << 6) | (data[i + 2] & 0x3F)
|
|
51
|
+
out.push(String.fromCharCode(cp))
|
|
52
|
+
i += 3
|
|
53
|
+
else:
|
|
54
|
+
cp = ((b & 0x07) << 18) | ((data[i + 1] & 0x3F) << 12) | ((data[i + 2] & 0x3F) << 6) | (data[i + 3] & 0x3F)
|
|
55
|
+
cp -= 0x10000
|
|
56
|
+
out.push(String.fromCharCode(0xD800 + (cp >> 10)))
|
|
57
|
+
out.push(String.fromCharCode(0xDC00 + (cp & 0x3FF)))
|
|
58
|
+
i += 4
|
|
59
|
+
return out.join('')
|
|
60
|
+
|
|
61
|
+
def ρσ_bytes_latin1_encode(s):
|
|
62
|
+
out = []
|
|
63
|
+
for v'var i = 0; i < s.length; i++':
|
|
64
|
+
c = s.charCodeAt(i)
|
|
65
|
+
if c > 255:
|
|
66
|
+
raise UnicodeEncodeError('latin-1', s, i, i + 1, 'ordinal not in range(256)')
|
|
67
|
+
out.push(c)
|
|
68
|
+
return out
|
|
69
|
+
|
|
70
|
+
def ρσ_bytes_latin1_decode(data):
|
|
71
|
+
chars = []
|
|
72
|
+
for v'var i = 0; i < data.length; i++':
|
|
73
|
+
chars.push(String.fromCharCode(data[i]))
|
|
74
|
+
return chars.join('')
|
|
75
|
+
|
|
76
|
+
def ρσ_bytes_from_source(source, encoding, errors):
|
|
77
|
+
data = []
|
|
78
|
+
if arguments.length is 0 or source is None or source is undefined:
|
|
79
|
+
pass # empty bytes
|
|
80
|
+
elif jstype(source) is 'number':
|
|
81
|
+
n = source | 0
|
|
82
|
+
if n < 0:
|
|
83
|
+
raise ValueError('negative count')
|
|
84
|
+
for v'var i = 0; i < n; i++':
|
|
85
|
+
data.push(0)
|
|
86
|
+
elif jstype(source) is 'string':
|
|
87
|
+
enc = (encoding or 'utf-8').toLowerCase().replace(/-|_/g, '')
|
|
88
|
+
if enc is 'utf8':
|
|
89
|
+
data = ρσ_bytes_utf8_encode(source)
|
|
90
|
+
elif enc is 'latin1' or enc is 'iso88591' or enc is 'ascii':
|
|
91
|
+
data = ρσ_bytes_latin1_encode(source)
|
|
92
|
+
else:
|
|
93
|
+
raise LookupError('unknown encoding: ' + (encoding or 'utf-8'))
|
|
94
|
+
elif v'source instanceof ρσ_bytes' or v'source instanceof ρσ_bytearray':
|
|
95
|
+
data = source._data.slice()
|
|
96
|
+
elif v'source instanceof Uint8Array' or v'source instanceof Int8Array':
|
|
97
|
+
for v'var i = 0; i < source.length; i++':
|
|
98
|
+
data.push(source[i] & 0xFF)
|
|
99
|
+
elif ρσ_arraylike(source) or Array.isArray(source):
|
|
100
|
+
for x in source:
|
|
101
|
+
b = x | 0
|
|
102
|
+
if b < 0 or b > 255:
|
|
103
|
+
raise ValueError('bytes must be in range(0, 256)')
|
|
104
|
+
data.push(b)
|
|
105
|
+
elif jstype(source[ρσ_iterator_symbol]) is 'function':
|
|
106
|
+
iterator = source[ρσ_iterator_symbol]()
|
|
107
|
+
result = iterator.next()
|
|
108
|
+
while not result.done:
|
|
109
|
+
b = result.value | 0
|
|
110
|
+
if b < 0 or b > 255:
|
|
111
|
+
raise ValueError('bytes must be in range(0, 256)')
|
|
112
|
+
data.push(b)
|
|
113
|
+
result = iterator.next()
|
|
114
|
+
else:
|
|
115
|
+
raise TypeError("cannot convert '" + jstype(source) + "' object to bytes-like object")
|
|
116
|
+
return data
|
|
117
|
+
|
|
118
|
+
# ---------------------------------------------------------------------------
|
|
119
|
+
# Index sync helper — sets numeric properties on the object so that
|
|
120
|
+
# plain JS `obj[i]` access (used when the subscript is a literal number in
|
|
121
|
+
# the compiler output) returns the correct byte value. Also sets .length so
|
|
122
|
+
# that the negative-index arithmetic in print_getitem works correctly.
|
|
123
|
+
# ---------------------------------------------------------------------------
|
|
124
|
+
|
|
125
|
+
def ρσ_bytes_sync(obj):
|
|
126
|
+
data = obj._data
|
|
127
|
+
old_len = obj.length | 0
|
|
128
|
+
new_len = data.length
|
|
129
|
+
# Remove stale numeric properties beyond the new length
|
|
130
|
+
for v'var i = new_len; i < old_len; i++':
|
|
131
|
+
v'delete obj[i]'
|
|
132
|
+
# Set all current indices
|
|
133
|
+
for v'var i = 0; i < new_len; i++':
|
|
134
|
+
obj[i] = data[i]
|
|
135
|
+
obj.length = new_len
|
|
136
|
+
|
|
137
|
+
# ---------------------------------------------------------------------------
|
|
138
|
+
# Shared helper — search for needle (plain array) in haystack (plain array)
|
|
139
|
+
# starting at offset `start`. Returns index or -1.
|
|
140
|
+
# ---------------------------------------------------------------------------
|
|
141
|
+
|
|
142
|
+
def ρσ_bytes_find(haystack, needle, start):
|
|
143
|
+
hl = haystack.length
|
|
144
|
+
nl = needle.length
|
|
145
|
+
if nl is 0:
|
|
146
|
+
return start
|
|
147
|
+
for v'var i = start; i <= hl - nl; i++':
|
|
148
|
+
ok = True
|
|
149
|
+
for v'var j = 0; j < nl; j++':
|
|
150
|
+
if haystack[i + j] is not needle[j]:
|
|
151
|
+
ok = False
|
|
152
|
+
break
|
|
153
|
+
if ok:
|
|
154
|
+
return i
|
|
155
|
+
return -1
|
|
156
|
+
|
|
157
|
+
# ---------------------------------------------------------------------------
|
|
158
|
+
# bytes — immutable sequence of integers in 0..255
|
|
159
|
+
# ---------------------------------------------------------------------------
|
|
160
|
+
|
|
161
|
+
class ρσ_bytes:
|
|
162
|
+
def __init__(self, source, encoding, errors):
|
|
163
|
+
self._data = ρσ_bytes_from_source.apply(None, arguments)
|
|
164
|
+
ρσ_bytes_sync(self)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def __len__(self):
|
|
168
|
+
return self._data.length
|
|
169
|
+
|
|
170
|
+
def __getitem__(self, key):
|
|
171
|
+
if v'key instanceof ρσ_slice':
|
|
172
|
+
indices = key.indices(self._data.length)
|
|
173
|
+
start = indices[0]
|
|
174
|
+
stop = indices[1]
|
|
175
|
+
step = indices[2]
|
|
176
|
+
result = []
|
|
177
|
+
if step > 0:
|
|
178
|
+
for v'var i = start; i < stop; i += step':
|
|
179
|
+
result.push(self._data[i])
|
|
180
|
+
else:
|
|
181
|
+
for v'var i = start; i > stop; i += step':
|
|
182
|
+
result.push(self._data[i])
|
|
183
|
+
return ρσ_bytes(result)
|
|
184
|
+
n = key | 0
|
|
185
|
+
if n < 0:
|
|
186
|
+
n += self._data.length
|
|
187
|
+
if n < 0 or n >= self._data.length:
|
|
188
|
+
raise IndexError('index out of range')
|
|
189
|
+
return self._data[n]
|
|
190
|
+
|
|
191
|
+
def __contains__(self, item):
|
|
192
|
+
if v'item instanceof ρσ_bytes' or v'item instanceof ρσ_bytearray':
|
|
193
|
+
return ρσ_bytes_find(self._data, item._data, 0) >= 0
|
|
194
|
+
b = item | 0
|
|
195
|
+
for v'var i = 0; i < this._data.length; i++':
|
|
196
|
+
if self._data[i] is b:
|
|
197
|
+
return True
|
|
198
|
+
return False
|
|
199
|
+
|
|
200
|
+
def __add__(self, other):
|
|
201
|
+
if not (v'other instanceof ρσ_bytes' or v'other instanceof ρσ_bytearray'):
|
|
202
|
+
raise TypeError("can't concat bytes-like objects of different types")
|
|
203
|
+
return ρσ_bytes(self._data.concat(other._data))
|
|
204
|
+
|
|
205
|
+
def __mul__(self, n):
|
|
206
|
+
result = []
|
|
207
|
+
for v'var k = 0; k < n; k++':
|
|
208
|
+
for v'var j = 0; j < this._data.length; j++':
|
|
209
|
+
result.push(self._data[j])
|
|
210
|
+
return ρσ_bytes(result)
|
|
211
|
+
|
|
212
|
+
def __rmul__(self, n):
|
|
213
|
+
return self.__mul__(n)
|
|
214
|
+
|
|
215
|
+
def __eq__(self, other):
|
|
216
|
+
if not (v'other instanceof ρσ_bytes' or v'other instanceof ρσ_bytearray'):
|
|
217
|
+
return False
|
|
218
|
+
if self._data.length is not other._data.length:
|
|
219
|
+
return False
|
|
220
|
+
for v'var i = 0; i < this._data.length; i++':
|
|
221
|
+
if self._data[i] is not other._data[i]:
|
|
222
|
+
return False
|
|
223
|
+
return True
|
|
224
|
+
|
|
225
|
+
def __iter__(self):
|
|
226
|
+
return iter(self._data)
|
|
227
|
+
|
|
228
|
+
def __bool__(self):
|
|
229
|
+
return self._data.length > 0
|
|
230
|
+
|
|
231
|
+
def __repr__(self):
|
|
232
|
+
parts = ["b'"]
|
|
233
|
+
for v'var i = 0; i < this._data.length; i++':
|
|
234
|
+
b = self._data[i]
|
|
235
|
+
if b is 9:
|
|
236
|
+
parts.push('\\t')
|
|
237
|
+
elif b is 10:
|
|
238
|
+
parts.push('\\n')
|
|
239
|
+
elif b is 13:
|
|
240
|
+
parts.push('\\r')
|
|
241
|
+
elif b is 39:
|
|
242
|
+
parts.push("\\'")
|
|
243
|
+
elif b is 92:
|
|
244
|
+
parts.push('\\\\')
|
|
245
|
+
elif b >= 32 and b < 127:
|
|
246
|
+
parts.push(String.fromCharCode(b))
|
|
247
|
+
else:
|
|
248
|
+
h = b.toString(16)
|
|
249
|
+
parts.push('\\x' + ('0' if h.length < 2 else '') + h)
|
|
250
|
+
parts.push("'")
|
|
251
|
+
return parts.join('')
|
|
252
|
+
|
|
253
|
+
def __str__(self):
|
|
254
|
+
return self.__repr__()
|
|
255
|
+
|
|
256
|
+
def __hash__(self):
|
|
257
|
+
h = 5381
|
|
258
|
+
for v'var i = 0; i < this._data.length; i++':
|
|
259
|
+
h = ((h << 5) + h) ^ self._data[i]
|
|
260
|
+
h = h | 0
|
|
261
|
+
return h
|
|
262
|
+
|
|
263
|
+
def hex(self, sep, bytes_per_sep):
|
|
264
|
+
parts = []
|
|
265
|
+
for v'var i = 0; i < this._data.length; i++':
|
|
266
|
+
h = self._data[i].toString(16)
|
|
267
|
+
parts.push(('0' if h.length < 2 else '') + h)
|
|
268
|
+
if sep is not undefined and sep is not None and parts.length > 0:
|
|
269
|
+
n = 1 if (bytes_per_sep is undefined or bytes_per_sep is None) else (bytes_per_sep | 0)
|
|
270
|
+
if n < 0:
|
|
271
|
+
n = -n
|
|
272
|
+
grouped = []
|
|
273
|
+
i = parts.length
|
|
274
|
+
while i > 0:
|
|
275
|
+
grouped.unshift(parts.slice(max(0, i - n), i).join(''))
|
|
276
|
+
i -= n
|
|
277
|
+
return grouped.join(sep)
|
|
278
|
+
else:
|
|
279
|
+
grouped = []
|
|
280
|
+
for v'var i = 0; i < parts.length; i += n':
|
|
281
|
+
grouped.push(parts.slice(i, i + n).join(''))
|
|
282
|
+
return grouped.join(sep)
|
|
283
|
+
return parts.join('')
|
|
284
|
+
|
|
285
|
+
def decode(self, encoding, errors):
|
|
286
|
+
enc = (encoding or 'utf-8').toLowerCase().replace(/-|_/g, '')
|
|
287
|
+
if enc is 'utf8':
|
|
288
|
+
return ρσ_bytes_utf8_decode(self._data)
|
|
289
|
+
elif enc is 'latin1' or enc is 'iso88591' or enc is 'ascii':
|
|
290
|
+
return ρσ_bytes_latin1_decode(self._data)
|
|
291
|
+
else:
|
|
292
|
+
raise LookupError('unknown encoding: ' + (encoding or 'utf-8'))
|
|
293
|
+
|
|
294
|
+
@staticmethod
|
|
295
|
+
def fromhex(s):
|
|
296
|
+
s = s.replace(/ /g, '')
|
|
297
|
+
if s.length % 2 is not 0:
|
|
298
|
+
raise ValueError('non-hexadecimal number found in fromhex() arg')
|
|
299
|
+
data = []
|
|
300
|
+
for v'var i = 0; i < s.length; i += 2':
|
|
301
|
+
val = parseInt(s.slice(i, i + 2), 16)
|
|
302
|
+
if isNaN(val):
|
|
303
|
+
raise ValueError('non-hexadecimal number found in fromhex() arg at position ' + str(i))
|
|
304
|
+
data.push(val)
|
|
305
|
+
return ρσ_bytes(data)
|
|
306
|
+
|
|
307
|
+
def count(self, sub, start, end):
|
|
308
|
+
needle = [sub | 0] if jstype(sub) is 'number' else sub._data
|
|
309
|
+
s = 0 if start is undefined else (start | 0)
|
|
310
|
+
e = self._data.length if end is undefined else (end | 0)
|
|
311
|
+
n = 0
|
|
312
|
+
pos = s
|
|
313
|
+
while pos <= e - needle.length:
|
|
314
|
+
found = ρσ_bytes_find(self._data, needle, pos)
|
|
315
|
+
if found < 0 or found + needle.length > e:
|
|
316
|
+
break
|
|
317
|
+
n += 1
|
|
318
|
+
pos = found + max(1, needle.length)
|
|
319
|
+
return n
|
|
320
|
+
|
|
321
|
+
def find(self, sub, start, end):
|
|
322
|
+
needle = [sub | 0] if jstype(sub) is 'number' else sub._data
|
|
323
|
+
s = 0 if start is undefined else (start | 0)
|
|
324
|
+
e = self._data.length if end is undefined else (end | 0)
|
|
325
|
+
pos = ρσ_bytes_find(self._data, needle, s)
|
|
326
|
+
if pos >= 0 and pos + needle.length <= e:
|
|
327
|
+
return pos
|
|
328
|
+
return -1
|
|
329
|
+
|
|
330
|
+
def index(self, sub, start, end):
|
|
331
|
+
pos = self.find(sub, start, end)
|
|
332
|
+
if pos < 0:
|
|
333
|
+
raise ValueError('subsequence not found')
|
|
334
|
+
return pos
|
|
335
|
+
|
|
336
|
+
def rfind(self, sub, start, end):
|
|
337
|
+
needle = [sub | 0] if jstype(sub) is 'number' else sub._data
|
|
338
|
+
s = 0 if start is undefined else (start | 0)
|
|
339
|
+
e = self._data.length if end is undefined else (end | 0)
|
|
340
|
+
last = -1
|
|
341
|
+
pos = s
|
|
342
|
+
while pos <= e - needle.length:
|
|
343
|
+
found = ρσ_bytes_find(self._data, needle, pos)
|
|
344
|
+
if found < 0 or found + needle.length > e:
|
|
345
|
+
break
|
|
346
|
+
last = found
|
|
347
|
+
pos = found + max(1, needle.length)
|
|
348
|
+
return last
|
|
349
|
+
|
|
350
|
+
def rindex(self, sub, start, end):
|
|
351
|
+
pos = self.rfind(sub, start, end)
|
|
352
|
+
if pos < 0:
|
|
353
|
+
raise ValueError('subsequence not found')
|
|
354
|
+
return pos
|
|
355
|
+
|
|
356
|
+
def startswith(self, prefix, start, end):
|
|
357
|
+
s = 0 if start is undefined else (start | 0)
|
|
358
|
+
e = self._data.length if end is undefined else (end | 0)
|
|
359
|
+
pdata = [prefix | 0] if jstype(prefix) is 'number' else prefix._data
|
|
360
|
+
if pdata.length > e - s:
|
|
361
|
+
return False
|
|
362
|
+
for v'var i = 0; i < pdata.length; i++':
|
|
363
|
+
if self._data[s + i] is not pdata[i]:
|
|
364
|
+
return False
|
|
365
|
+
return True
|
|
366
|
+
|
|
367
|
+
def endswith(self, suffix, start, end):
|
|
368
|
+
s = 0 if start is undefined else (start | 0)
|
|
369
|
+
e = self._data.length if end is undefined else (end | 0)
|
|
370
|
+
sdata = [suffix | 0] if jstype(suffix) is 'number' else suffix._data
|
|
371
|
+
if sdata.length > e - s:
|
|
372
|
+
return False
|
|
373
|
+
offset = e - sdata.length
|
|
374
|
+
for v'var i = 0; i < sdata.length; i++':
|
|
375
|
+
if self._data[offset + i] is not sdata[i]:
|
|
376
|
+
return False
|
|
377
|
+
return True
|
|
378
|
+
|
|
379
|
+
def join(self, iterable):
|
|
380
|
+
parts = []
|
|
381
|
+
for item in iterable:
|
|
382
|
+
if not (v'item instanceof ρσ_bytes' or v'item instanceof ρσ_bytearray'):
|
|
383
|
+
raise TypeError('sequence item must be a bytes-like object')
|
|
384
|
+
parts.push(item._data)
|
|
385
|
+
result = []
|
|
386
|
+
for v'var i = 0; i < parts.length; i++':
|
|
387
|
+
if i > 0:
|
|
388
|
+
for v'var j = 0; j < this._data.length; j++':
|
|
389
|
+
result.push(self._data[j])
|
|
390
|
+
for v'var j = 0; j < parts[i].length; j++':
|
|
391
|
+
result.push(parts[i][j])
|
|
392
|
+
return ρσ_bytes(result)
|
|
393
|
+
|
|
394
|
+
def split(self, sep, maxsplit):
|
|
395
|
+
if maxsplit is undefined:
|
|
396
|
+
maxsplit = -1
|
|
397
|
+
if sep is None or sep is undefined or jstype(sep) is 'string':
|
|
398
|
+
# Split on whitespace
|
|
399
|
+
result = []
|
|
400
|
+
i = 0
|
|
401
|
+
n = self._data.length
|
|
402
|
+
while i < n:
|
|
403
|
+
while i < n and self._data[i] <= 32:
|
|
404
|
+
i += 1
|
|
405
|
+
if i >= n:
|
|
406
|
+
break
|
|
407
|
+
j = i
|
|
408
|
+
while j < n and self._data[j] > 32:
|
|
409
|
+
j += 1
|
|
410
|
+
result.push(ρσ_bytes(self._data.slice(i, j)))
|
|
411
|
+
i = j
|
|
412
|
+
if maxsplit >= 0 and result.length >= maxsplit:
|
|
413
|
+
while i < n and self._data[i] <= 32:
|
|
414
|
+
i += 1
|
|
415
|
+
if i < n:
|
|
416
|
+
result.push(ρσ_bytes(self._data.slice(i)))
|
|
417
|
+
break
|
|
418
|
+
return result
|
|
419
|
+
needle = sep._data
|
|
420
|
+
result = []
|
|
421
|
+
pos = 0
|
|
422
|
+
splits = 0
|
|
423
|
+
while True:
|
|
424
|
+
found = ρσ_bytes_find(self._data, needle, pos)
|
|
425
|
+
if found < 0 or (maxsplit >= 0 and splits >= maxsplit):
|
|
426
|
+
result.push(ρσ_bytes(self._data.slice(pos)))
|
|
427
|
+
break
|
|
428
|
+
result.push(ρσ_bytes(self._data.slice(pos, found)))
|
|
429
|
+
pos = found + needle.length
|
|
430
|
+
splits += 1
|
|
431
|
+
return result
|
|
432
|
+
|
|
433
|
+
def replace(self, old, replacement, count):
|
|
434
|
+
odata = old._data
|
|
435
|
+
ndata = replacement._data
|
|
436
|
+
result = []
|
|
437
|
+
pos = 0
|
|
438
|
+
n = 0
|
|
439
|
+
limit = count if (count is not undefined and count is not None) else -1
|
|
440
|
+
while pos <= self._data.length:
|
|
441
|
+
found = ρσ_bytes_find(self._data, odata, pos)
|
|
442
|
+
if found < 0 or (limit >= 0 and n >= limit):
|
|
443
|
+
for v'var i = pos; i < this._data.length; i++':
|
|
444
|
+
result.push(self._data[i])
|
|
445
|
+
break
|
|
446
|
+
for v'var i = pos; i < found; i++':
|
|
447
|
+
result.push(self._data[i])
|
|
448
|
+
for v'var i = 0; i < ndata.length; i++':
|
|
449
|
+
result.push(ndata[i])
|
|
450
|
+
pos = found + odata.length
|
|
451
|
+
n += 1
|
|
452
|
+
if odata.length is 0:
|
|
453
|
+
if pos < self._data.length:
|
|
454
|
+
result.push(self._data[pos])
|
|
455
|
+
pos += 1
|
|
456
|
+
else:
|
|
457
|
+
break
|
|
458
|
+
return ρσ_bytes(result)
|
|
459
|
+
|
|
460
|
+
def strip(self, chars):
|
|
461
|
+
return self.lstrip(chars).rstrip(chars)
|
|
462
|
+
|
|
463
|
+
def lstrip(self, chars):
|
|
464
|
+
is_ws = chars is None or chars is undefined
|
|
465
|
+
cdata = [] if is_ws else chars._data
|
|
466
|
+
i = 0
|
|
467
|
+
while i < self._data.length:
|
|
468
|
+
b = self._data[i]
|
|
469
|
+
if is_ws:
|
|
470
|
+
if b > 32:
|
|
471
|
+
break
|
|
472
|
+
else:
|
|
473
|
+
if cdata.indexOf(b) < 0:
|
|
474
|
+
break
|
|
475
|
+
i += 1
|
|
476
|
+
return ρσ_bytes(self._data.slice(i))
|
|
477
|
+
|
|
478
|
+
def rstrip(self, chars):
|
|
479
|
+
is_ws = chars is None or chars is undefined
|
|
480
|
+
cdata = [] if is_ws else chars._data
|
|
481
|
+
i = self._data.length - 1
|
|
482
|
+
while i >= 0:
|
|
483
|
+
b = self._data[i]
|
|
484
|
+
if is_ws:
|
|
485
|
+
if b > 32:
|
|
486
|
+
break
|
|
487
|
+
else:
|
|
488
|
+
if cdata.indexOf(b) < 0:
|
|
489
|
+
break
|
|
490
|
+
i -= 1
|
|
491
|
+
return ρσ_bytes(self._data.slice(0, i + 1))
|
|
492
|
+
|
|
493
|
+
def upper(self):
|
|
494
|
+
data = self._data.slice()
|
|
495
|
+
for v'var i = 0; i < data.length; i++':
|
|
496
|
+
b = data[i]
|
|
497
|
+
if b >= 97 and b <= 122:
|
|
498
|
+
data[i] = b - 32
|
|
499
|
+
return ρσ_bytes(data)
|
|
500
|
+
|
|
501
|
+
def lower(self):
|
|
502
|
+
data = self._data.slice()
|
|
503
|
+
for v'var i = 0; i < data.length; i++':
|
|
504
|
+
b = data[i]
|
|
505
|
+
if b >= 65 and b <= 90:
|
|
506
|
+
data[i] = b + 32
|
|
507
|
+
return ρσ_bytes(data)
|
|
508
|
+
|
|
509
|
+
def copy(self):
|
|
510
|
+
return ρσ_bytes(self._data.slice())
|
|
511
|
+
|
|
512
|
+
# .slice() and .filter() are called by the RapydScript compiler output for
|
|
513
|
+
# b[start:end] and b[start:end:step] subscript expressions respectively.
|
|
514
|
+
# They must return a new bytes object (not a plain array) so that sliced
|
|
515
|
+
# bytes values continue to behave as bytes.
|
|
516
|
+
|
|
517
|
+
def slice(self, start, end):
|
|
518
|
+
return ρσ_bytes(self._data.slice(start, end))
|
|
519
|
+
|
|
520
|
+
def filter(self, fn):
|
|
521
|
+
return ρσ_bytes(self._data.filter(fn))
|
|
522
|
+
|
|
523
|
+
ρσ_bytes.__name__ = 'bytes'
|
|
524
|
+
|
|
525
|
+
# ---------------------------------------------------------------------------
|
|
526
|
+
# bytearray — mutable version of bytes
|
|
527
|
+
# ---------------------------------------------------------------------------
|
|
528
|
+
|
|
529
|
+
class ρσ_bytearray(ρσ_bytes):
|
|
530
|
+
def __init__(self, source, encoding, errors):
|
|
531
|
+
self._data = ρσ_bytes_from_source.apply(None, arguments)
|
|
532
|
+
ρσ_bytes_sync(self)
|
|
533
|
+
|
|
534
|
+
def __setitem__(self, key, val):
|
|
535
|
+
if v'key instanceof ρσ_slice':
|
|
536
|
+
indices = key.indices(self._data.length)
|
|
537
|
+
start = indices[0]
|
|
538
|
+
stop = indices[1]
|
|
539
|
+
step = indices[2]
|
|
540
|
+
if v'val instanceof ρσ_bytes' or v'val instanceof ρσ_bytearray':
|
|
541
|
+
src = val._data
|
|
542
|
+
else:
|
|
543
|
+
src = ρσ_bytes_from_source(val)
|
|
544
|
+
if step is 1:
|
|
545
|
+
self._data.splice.apply(self._data, [start, stop - start].concat(src))
|
|
546
|
+
else:
|
|
547
|
+
positions = []
|
|
548
|
+
if step > 0:
|
|
549
|
+
for v'var i = start; i < stop; i += step':
|
|
550
|
+
positions.push(i)
|
|
551
|
+
else:
|
|
552
|
+
for v'var i = start; i > stop; i += step':
|
|
553
|
+
positions.push(i)
|
|
554
|
+
if src.length is not positions.length:
|
|
555
|
+
raise ValueError('attempt to assign bytes of size ' + str(src.length) + ' to extended slice of size ' + str(positions.length))
|
|
556
|
+
for v'var i = 0; i < positions.length; i++':
|
|
557
|
+
self._data[positions[i]] = src[i]
|
|
558
|
+
ρσ_bytes_sync(self)
|
|
559
|
+
else:
|
|
560
|
+
n = key | 0
|
|
561
|
+
if n < 0:
|
|
562
|
+
n += self._data.length
|
|
563
|
+
if n < 0 or n >= self._data.length:
|
|
564
|
+
raise IndexError('index out of range')
|
|
565
|
+
b = val | 0
|
|
566
|
+
if b < 0 or b > 255:
|
|
567
|
+
raise ValueError('byte must be in range(0, 256)')
|
|
568
|
+
self._data[n] = b
|
|
569
|
+
self[n] = b
|
|
570
|
+
|
|
571
|
+
def __add__(self, other):
|
|
572
|
+
if not (v'other instanceof ρσ_bytes' or v'other instanceof ρσ_bytearray'):
|
|
573
|
+
raise TypeError("can't concat bytes-like objects of different types")
|
|
574
|
+
return ρσ_bytearray(self._data.concat(other._data))
|
|
575
|
+
|
|
576
|
+
def __iadd__(self, other):
|
|
577
|
+
if not (v'other instanceof ρσ_bytes' or v'other instanceof ρσ_bytearray'):
|
|
578
|
+
raise TypeError("can't concat bytes-like objects of different types")
|
|
579
|
+
for v'var i = 0; i < other._data.length; i++':
|
|
580
|
+
self._data.push(other._data[i])
|
|
581
|
+
ρσ_bytes_sync(self)
|
|
582
|
+
return self
|
|
583
|
+
|
|
584
|
+
def __mul__(self, n):
|
|
585
|
+
result = []
|
|
586
|
+
for v'var k = 0; k < n; k++':
|
|
587
|
+
for v'var j = 0; j < this._data.length; j++':
|
|
588
|
+
result.push(self._data[j])
|
|
589
|
+
return ρσ_bytearray(result)
|
|
590
|
+
|
|
591
|
+
def __repr__(self):
|
|
592
|
+
b = ρσ_bytes.prototype.__repr__.call(self)
|
|
593
|
+
return 'bytearray(' + b + ')'
|
|
594
|
+
|
|
595
|
+
def append(self, item):
|
|
596
|
+
b = item | 0
|
|
597
|
+
if b < 0 or b > 255:
|
|
598
|
+
raise ValueError('byte must be in range(0, 256)')
|
|
599
|
+
idx = self._data.length
|
|
600
|
+
self._data.push(b)
|
|
601
|
+
self[idx] = b
|
|
602
|
+
self.length = self._data.length
|
|
603
|
+
|
|
604
|
+
def extend(self, iterable):
|
|
605
|
+
if v'iterable instanceof ρσ_bytes' or v'iterable instanceof ρσ_bytearray':
|
|
606
|
+
for v'var i = 0; i < iterable._data.length; i++':
|
|
607
|
+
self._data.push(iterable._data[i])
|
|
608
|
+
else:
|
|
609
|
+
for x in iterable:
|
|
610
|
+
b = x | 0
|
|
611
|
+
if b < 0 or b > 255:
|
|
612
|
+
raise ValueError('byte must be in range(0, 256)')
|
|
613
|
+
self._data.push(b)
|
|
614
|
+
ρσ_bytes_sync(self)
|
|
615
|
+
|
|
616
|
+
def insert(self, idx, item):
|
|
617
|
+
n = idx | 0
|
|
618
|
+
if n < 0:
|
|
619
|
+
n = max(0, self._data.length + n)
|
|
620
|
+
b = item | 0
|
|
621
|
+
if b < 0 or b > 255:
|
|
622
|
+
raise ValueError('byte must be in range(0, 256)')
|
|
623
|
+
self._data.splice(n, 0, b)
|
|
624
|
+
ρσ_bytes_sync(self)
|
|
625
|
+
|
|
626
|
+
def pop(self, idx):
|
|
627
|
+
n = self._data.length - 1 if idx is undefined else (idx | 0)
|
|
628
|
+
if n < 0:
|
|
629
|
+
n += self._data.length
|
|
630
|
+
if n < 0 or n >= self._data.length:
|
|
631
|
+
raise IndexError('pop index out of range')
|
|
632
|
+
val = self._data.splice(n, 1)[0]
|
|
633
|
+
ρσ_bytes_sync(self)
|
|
634
|
+
return val
|
|
635
|
+
|
|
636
|
+
def remove(self, item):
|
|
637
|
+
b = item | 0
|
|
638
|
+
for v'var i = 0; i < this._data.length; i++':
|
|
639
|
+
if self._data[i] is b:
|
|
640
|
+
self._data.splice(i, 1)
|
|
641
|
+
ρσ_bytes_sync(self)
|
|
642
|
+
return
|
|
643
|
+
raise ValueError(str(item) + ' is not in bytearray')
|
|
644
|
+
|
|
645
|
+
def reverse(self):
|
|
646
|
+
self._data.reverse()
|
|
647
|
+
ρσ_bytes_sync(self)
|
|
648
|
+
|
|
649
|
+
def clear(self):
|
|
650
|
+
self._data.length = 0
|
|
651
|
+
ρσ_bytes_sync(self)
|
|
652
|
+
|
|
653
|
+
def copy(self):
|
|
654
|
+
return ρσ_bytearray(self._data.slice())
|
|
655
|
+
|
|
656
|
+
def slice(self, start, end):
|
|
657
|
+
return ρσ_bytearray(self._data.slice(start, end))
|
|
658
|
+
|
|
659
|
+
def filter(self, fn):
|
|
660
|
+
return ρσ_bytearray(self._data.filter(fn))
|
|
661
|
+
|
|
662
|
+
ρσ_bytearray.__name__ = 'bytearray'
|
|
663
|
+
|
|
664
|
+
v'var bytes = ρσ_bytes, bytearray = ρσ_bytearray'
|