rapydscript-ns 0.9.2 → 0.9.3
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 -1
- package/.github/workflows/ci.yml +38 -38
- package/=template.pyj +5 -5
- package/CHANGELOG.md +19 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/PYTHON_GAPS.md +420 -0
- package/README.md +153 -29
- package/TODO.md +16 -118
- package/add-toc-to-readme +2 -2
- package/bin/export +75 -75
- package/bin/rapydscript +70 -70
- package/bin/web-repl-export +102 -102
- package/build +2 -2
- package/language-service/index.js +237 -8
- package/memory/project_string_impl.md +43 -0
- package/package.json +1 -1
- package/publish.py +37 -37
- package/release/baselib-plain-pretty.js +248 -38
- package/release/baselib-plain-ugly.js +8 -8
- package/release/compiler.js +778 -277
- package/release/signatures.json +30 -30
- package/session.vim +4 -4
- package/setup.cfg +2 -2
- package/src/ast.pyj +4 -1
- package/src/baselib-builtins.pyj +56 -2
- package/src/baselib-containers.pyj +2 -0
- package/src/baselib-errors.pyj +7 -3
- package/src/baselib-internal.pyj +51 -6
- package/src/baselib-str.pyj +5 -3
- package/src/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/aes.pyj +646 -646
- package/src/lib/asyncio.pyj +534 -0
- package/src/lib/base64.pyj +399 -0
- package/src/lib/bisect.pyj +73 -0
- package/src/lib/collections.pyj +1 -1
- package/src/lib/copy.pyj +120 -120
- package/src/lib/csv.pyj +494 -0
- package/src/lib/elementmaker.pyj +83 -83
- package/src/lib/encodings.pyj +126 -126
- package/src/lib/gettext.pyj +569 -569
- package/src/lib/heapq.pyj +98 -0
- package/src/lib/html.pyj +382 -0
- package/src/lib/http/__init__.pyj +98 -0
- package/src/lib/http/client.pyj +304 -0
- package/src/lib/http/cookies.pyj +236 -0
- package/src/lib/itertools.pyj +580 -580
- package/src/lib/logging.pyj +672 -0
- package/src/lib/math.pyj +193 -193
- package/src/lib/operator.pyj +11 -11
- package/src/lib/pythonize.pyj +20 -20
- package/src/lib/random.pyj +118 -118
- package/src/lib/react.pyj +74 -74
- package/src/lib/string.pyj +357 -0
- package/src/lib/textwrap.pyj +329 -0
- package/src/lib/traceback.pyj +63 -63
- package/src/lib/urllib/__init__.pyj +14 -0
- package/src/lib/urllib/error.pyj +66 -0
- package/src/lib/urllib/parse.pyj +475 -0
- package/src/lib/urllib/request.pyj +86 -0
- package/src/lib/uuid.pyj +77 -77
- package/src/monaco-language-service/analyzer.js +5 -2
- package/src/monaco-language-service/completions.js +26 -0
- package/src/monaco-language-service/diagnostics.js +202 -3
- package/src/monaco-language-service/dts.js +550 -550
- package/src/monaco-language-service/scope.js +1 -0
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -201
- package/src/output/functions.pyj +152 -6
- package/src/output/jsx.pyj +164 -164
- package/src/output/loops.pyj +17 -2
- package/src/output/modules.pyj +1 -1
- package/src/output/operators.pyj +15 -0
- package/src/output/stream.pyj +0 -1
- package/src/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/parse.pyj +80 -17
- package/src/string_interpolation.pyj +72 -72
- package/src/tokenizer.pyj +1 -1
- package/src/unicode_aliases.pyj +576 -576
- package/src/utils.pyj +192 -192
- package/test/_import_one.pyj +37 -37
- package/test/_import_two/__init__.pyj +11 -11
- package/test/_import_two/level2/deep.pyj +4 -4
- package/test/_import_two/other.pyj +6 -6
- package/test/_import_two/sub.pyj +13 -13
- package/test/aes_vectors.pyj +421 -421
- package/test/annotations.pyj +80 -80
- package/test/async_generators.pyj +144 -0
- package/test/asyncio.pyj +307 -0
- package/test/base64.pyj +202 -0
- package/test/bisect.pyj +178 -0
- package/test/csv.pyj +405 -0
- package/test/decorators.pyj +77 -77
- package/test/docstrings.pyj +39 -39
- package/test/elementmaker_test.pyj +45 -45
- package/test/float_special.pyj +64 -0
- package/test/functions.pyj +151 -151
- package/test/generators.pyj +41 -41
- package/test/generic.pyj +370 -370
- package/test/heapq.pyj +174 -0
- package/test/html.pyj +212 -0
- package/test/http.pyj +259 -0
- package/test/imports.pyj +79 -72
- package/test/internationalization.pyj +73 -73
- package/test/lint.pyj +164 -164
- package/test/logging.pyj +356 -0
- package/test/long.pyj +130 -0
- package/test/loops.pyj +85 -85
- package/test/numpy.pyj +734 -734
- package/test/parenthesized_with.pyj +141 -0
- package/test/python_compat.pyj +3 -5
- package/test/python_modulo.pyj +76 -0
- package/test/python_modulo_off.pyj +21 -0
- package/test/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- package/test/str.pyj +14 -0
- package/test/string.pyj +245 -0
- package/test/textwrap.pyj +172 -0
- package/test/type_display.pyj +48 -0
- package/test/type_enforcement.pyj +164 -0
- package/test/unit/index.js +14 -6
- package/test/unit/language-service-completions.js +119 -0
- package/test/unit/language-service-dts.js +543 -543
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service-scope.js +32 -0
- package/test/unit/language-service.js +127 -3
- package/test/unit/run-language-service.js +17 -3
- package/test/unit/web-repl.js +2094 -29
- package/test/urllib.pyj +193 -0
- package/tools/compile.js +1 -1
- package/tools/compiler.d.ts +367 -367
- package/tools/completer.js +131 -131
- package/tools/embedded_compiler.js +7 -7
- package/tools/gettext.js +185 -185
- package/tools/ini.js +65 -65
- package/tools/msgfmt.js +187 -187
- package/tools/repl.js +223 -223
- package/tools/test.js +118 -118
- package/tools/utils.js +128 -128
- package/tools/web_repl.js +95 -95
- package/try +41 -41
- package/web-repl/env.js +196 -196
- package/web-repl/index.html +163 -163
- package/web-repl/main.js +1 -1
- package/web-repl/prism.css +139 -139
- package/web-repl/prism.js +113 -113
- package/web-repl/rapydscript.js +224 -224
- package/web-repl/sha1.js +25 -25
- package/test/omit_function_metadata.pyj +0 -20
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
###########################################################
|
|
2
|
+
# RapydScript Standard Library
|
|
3
|
+
# Author: RapydScript-NS Contributors
|
|
4
|
+
# Copyright 2024 RapydScript-NS Contributors
|
|
5
|
+
# License: Apache License 2.0
|
|
6
|
+
# This library is covered under Apache license, so that
|
|
7
|
+
# you can distribute it with your RapydScript applications.
|
|
8
|
+
###########################################################
|
|
9
|
+
|
|
10
|
+
# Python-compatible base64 module.
|
|
11
|
+
#
|
|
12
|
+
# All encode functions accept bytes/bytearray/list-of-ints and return bytes.
|
|
13
|
+
# All decode functions return bytes.
|
|
14
|
+
#
|
|
15
|
+
# Functions available:
|
|
16
|
+
# b64encode(s, altchars=None)
|
|
17
|
+
# b64decode(s, altchars=None, validate=False)
|
|
18
|
+
# standard_b64encode(s)
|
|
19
|
+
# standard_b64decode(s)
|
|
20
|
+
# urlsafe_b64encode(s)
|
|
21
|
+
# urlsafe_b64decode(s)
|
|
22
|
+
# b32encode(s)
|
|
23
|
+
# b32decode(s, casefold=False, map01=None)
|
|
24
|
+
# b16encode(s)
|
|
25
|
+
# b16decode(s, casefold=False)
|
|
26
|
+
# encodebytes(s)
|
|
27
|
+
# decodebytes(s)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Error(ValueError):
|
|
31
|
+
"""Raised when invalid base64/base32/base16 data is encountered."""
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
v"""
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Internal helpers
|
|
38
|
+
// Note: backslash sequences must be doubled inside triple-quote verbatim
|
|
39
|
+
// blocks since Python processes them before passing to JS.
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
// Convert a bytes-like value to a plain JS Array of integers 0-255.
|
|
43
|
+
function _b64_to_arr(b) {
|
|
44
|
+
if (b === null || b === undefined) return [];
|
|
45
|
+
if (b._data !== undefined && b._data !== null) return b._data;
|
|
46
|
+
if (Array.isArray(b)) return b;
|
|
47
|
+
if (b instanceof Uint8Array || b instanceof Int8Array) {
|
|
48
|
+
var r = [];
|
|
49
|
+
for (var i = 0; i < b.length; i++) r.push(b[i] & 0xFF);
|
|
50
|
+
return r;
|
|
51
|
+
}
|
|
52
|
+
if (typeof b === 'string') {
|
|
53
|
+
var r2 = [];
|
|
54
|
+
for (var j = 0; j < b.length; j++) r2.push(b.charCodeAt(j) & 0xFF);
|
|
55
|
+
return r2;
|
|
56
|
+
}
|
|
57
|
+
var r3 = [];
|
|
58
|
+
for (var k = 0; k < (b.length || 0); k++) r3.push((b[k] | 0) & 0xFF);
|
|
59
|
+
return r3;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Convert a bytes-like value or string to an ASCII string.
|
|
63
|
+
function _b64_to_str(b) {
|
|
64
|
+
if (typeof b === 'string') return b;
|
|
65
|
+
var arr = _b64_to_arr(b);
|
|
66
|
+
var parts = [];
|
|
67
|
+
for (var i = 0; i < arr.length; i++) parts.push(String.fromCharCode(arr[i]));
|
|
68
|
+
return parts.join('');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Convert a plain JS integer array to a ρσ_bytes object.
|
|
72
|
+
function _b64_arr_to_bytes(arr) {
|
|
73
|
+
return ρσ_bytes(arr);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Base64 internals
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
var _B64_STD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
81
|
+
var _B64_SAFE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
82
|
+
|
|
83
|
+
function _b64_make_table(alpha) {
|
|
84
|
+
var t = new Uint8Array(128);
|
|
85
|
+
for (var fi = 0; fi < 128; fi++) t[fi] = 255; // 255 = invalid
|
|
86
|
+
for (var gi = 0; gi < alpha.length; gi++) t[alpha.charCodeAt(gi)] = gi;
|
|
87
|
+
t['='.charCodeAt(0)] = 64; // 64 = padding sentinel
|
|
88
|
+
return t;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
var _B64_STD_TABLE = _b64_make_table(_B64_STD);
|
|
92
|
+
var _B64_SAFE_TABLE = _b64_make_table(_B64_SAFE);
|
|
93
|
+
|
|
94
|
+
// Encode a plain int array to a base64 string using the given 64-char alphabet.
|
|
95
|
+
function _b64_encode_impl(data, alpha) {
|
|
96
|
+
var out = [];
|
|
97
|
+
var len = data.length;
|
|
98
|
+
for (var i = 0; i < len; i += 3) {
|
|
99
|
+
var b0 = data[i];
|
|
100
|
+
var b1 = (i + 1 < len) ? data[i + 1] : 0;
|
|
101
|
+
var b2 = (i + 2 < len) ? data[i + 2] : 0;
|
|
102
|
+
out.push(alpha.charAt((b0 >> 2) & 0x3F));
|
|
103
|
+
out.push(alpha.charAt(((b0 & 0x3) << 4) | ((b1 >> 4) & 0xF)));
|
|
104
|
+
out.push((i + 1 < len) ? alpha.charAt(((b1 & 0xF) << 2) | ((b2 >> 6) & 0x3)) : '=');
|
|
105
|
+
out.push((i + 2 < len) ? alpha.charAt(b2 & 0x3F) : '=');
|
|
106
|
+
}
|
|
107
|
+
return out.join('');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Strip ASCII whitespace from a base64 string using split/join.
|
|
111
|
+
function _b64_strip_ws(s) {
|
|
112
|
+
return s.split(' ').join('').split('\\t').join('').split('\\n').join('').split('\\r').join('').split('\\f').join('').split('\\v').join('');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Decode a base64 string to a plain int array.
|
|
116
|
+
// table — 128-entry Uint8Array (255=invalid, 64=padding '=')
|
|
117
|
+
// validate — if true, raise on non-alphabet characters
|
|
118
|
+
// Error_cls — RapydScript Error class to instantiate on bad input
|
|
119
|
+
function _b64_decode_impl(s, table, validate, Error_cls) {
|
|
120
|
+
if (!validate) {
|
|
121
|
+
s = _b64_strip_ws(s);
|
|
122
|
+
}
|
|
123
|
+
var len = s.length;
|
|
124
|
+
if (len === 0) return [];
|
|
125
|
+
|
|
126
|
+
if (validate && len % 4 !== 0) {
|
|
127
|
+
throw new Error_cls('Incorrect padding');
|
|
128
|
+
}
|
|
129
|
+
// Pad to multiple of 4 (Python is lenient about missing padding).
|
|
130
|
+
// pad === 3 means 1 leftover base64 char, which can't encode any bytes.
|
|
131
|
+
var pad = (4 - (len % 4)) % 4;
|
|
132
|
+
if (pad === 3) throw new Error_cls('Incorrect padding');
|
|
133
|
+
if (pad > 0) {
|
|
134
|
+
s = s + '===='.slice(0, pad);
|
|
135
|
+
len = s.length;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
var out = [];
|
|
139
|
+
for (var i = 0; i < len; i += 4) {
|
|
140
|
+
var c0 = s.charCodeAt(i), c1 = s.charCodeAt(i + 1);
|
|
141
|
+
var c2 = s.charCodeAt(i + 2), c3 = s.charCodeAt(i + 3);
|
|
142
|
+
var v0 = c0 < 128 ? table[c0] : 255;
|
|
143
|
+
var v1 = c1 < 128 ? table[c1] : 255;
|
|
144
|
+
var v2 = c2 < 128 ? table[c2] : 255;
|
|
145
|
+
var v3 = c3 < 128 ? table[c3] : 255;
|
|
146
|
+
|
|
147
|
+
if (v0 === 255 || v1 === 255 || v2 === 255 || v3 === 255) {
|
|
148
|
+
if (validate) throw new Error_cls('Non-base64 digit found');
|
|
149
|
+
continue; // skip bad block when not validating
|
|
150
|
+
}
|
|
151
|
+
if (v0 === 64 || v1 === 64) {
|
|
152
|
+
throw new Error_cls('Incorrect padding');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
out.push(((v0 << 2) | (v1 >> 4)) & 0xFF);
|
|
156
|
+
if (v2 !== 64) {
|
|
157
|
+
out.push(((v1 << 4) | (v2 >> 2)) & 0xFF);
|
|
158
|
+
if (v3 !== 64) {
|
|
159
|
+
out.push(((v2 << 6) | v3) & 0xFF);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
// Base32 internals
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
|
|
170
|
+
var _B32_ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
|
171
|
+
var _B32_TABLE = (function() {
|
|
172
|
+
var t = new Uint8Array(128);
|
|
173
|
+
for (var fi = 0; fi < 128; fi++) t[fi] = 255;
|
|
174
|
+
for (var gi = 0; gi < _B32_ALPHA.length; gi++) t[_B32_ALPHA.charCodeAt(gi)] = gi;
|
|
175
|
+
t['='.charCodeAt(0)] = 32; // 32 = padding sentinel
|
|
176
|
+
return t;
|
|
177
|
+
})();
|
|
178
|
+
|
|
179
|
+
// Encode a plain int array to base32.
|
|
180
|
+
function _b32_encode_impl(data) {
|
|
181
|
+
var out = [];
|
|
182
|
+
var len = data.length;
|
|
183
|
+
for (var i = 0; i < len; i += 5) {
|
|
184
|
+
var take = Math.min(5, len - i);
|
|
185
|
+
var b = [0, 0, 0, 0, 0];
|
|
186
|
+
for (var j = 0; j < take; j++) b[j] = data[i + j];
|
|
187
|
+
|
|
188
|
+
out.push(_B32_ALPHA.charAt((b[0] >> 3) & 0x1F));
|
|
189
|
+
out.push(_B32_ALPHA.charAt(((b[0] & 0x7) << 2) | ((b[1] >> 6) & 0x3)));
|
|
190
|
+
out.push(take >= 2 ? _B32_ALPHA.charAt((b[1] >> 1) & 0x1F) : '=');
|
|
191
|
+
out.push(take >= 2 ? _B32_ALPHA.charAt(((b[1] & 0x1) << 4) | ((b[2] >> 4) & 0xF)) : '=');
|
|
192
|
+
out.push(take >= 3 ? _B32_ALPHA.charAt(((b[2] & 0xF) << 1) | ((b[3] >> 7) & 0x1)) : '=');
|
|
193
|
+
out.push(take >= 4 ? _B32_ALPHA.charAt((b[3] >> 2) & 0x1F) : '=');
|
|
194
|
+
out.push(take >= 4 ? _B32_ALPHA.charAt(((b[3] & 0x3) << 3) | ((b[4] >> 5) & 0x7)) : '=');
|
|
195
|
+
out.push(take >= 5 ? _B32_ALPHA.charAt(b[4] & 0x1F) : '=');
|
|
196
|
+
}
|
|
197
|
+
return out.join('');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Decode a base32 string to a plain int array.
|
|
201
|
+
function _b32_decode_impl(s, Error_cls) {
|
|
202
|
+
// Strip padding chars and whitespace using split/join.
|
|
203
|
+
s = s.split('=').join('');
|
|
204
|
+
s = s.split(' ').join('');
|
|
205
|
+
s = s.split('\\t').join('');
|
|
206
|
+
s = s.split('\\n').join('');
|
|
207
|
+
s = s.split('\\r').join('');
|
|
208
|
+
|
|
209
|
+
var out = [];
|
|
210
|
+
var len = s.length;
|
|
211
|
+
for (var i = 0; i < len; i += 8) {
|
|
212
|
+
var v = [0, 0, 0, 0, 0, 0, 0, 0];
|
|
213
|
+
var take = Math.min(8, len - i);
|
|
214
|
+
for (var j = 0; j < take; j++) {
|
|
215
|
+
var cc = s.charCodeAt(i + j);
|
|
216
|
+
var vv = cc < 128 ? _B32_TABLE[cc] : 255;
|
|
217
|
+
if (vv >= 32) throw new Error_cls('Non-base32 digit found');
|
|
218
|
+
v[j] = vv;
|
|
219
|
+
}
|
|
220
|
+
if (take >= 2) out.push(((v[0] << 3) | (v[1] >> 2)) & 0xFF);
|
|
221
|
+
if (take >= 4) out.push(((v[1] << 6) | (v[2] << 1) | (v[3] >> 4)) & 0xFF);
|
|
222
|
+
if (take >= 5) out.push(((v[3] << 4) | (v[4] >> 1)) & 0xFF);
|
|
223
|
+
if (take >= 7) out.push(((v[4] << 7) | (v[5] << 2) | (v[6] >> 3)) & 0xFF);
|
|
224
|
+
if (take >= 8) out.push(((v[6] << 5) | v[7]) & 0xFF);
|
|
225
|
+
}
|
|
226
|
+
return out;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ---------------------------------------------------------------------------
|
|
230
|
+
// Base16 (hex) internals
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
|
|
233
|
+
function _b16_encode_impl(data) {
|
|
234
|
+
var out = [];
|
|
235
|
+
for (var i = 0; i < data.length; i++) {
|
|
236
|
+
var h = data[i].toString(16).toUpperCase();
|
|
237
|
+
out.push(h.length === 1 ? '0' + h : h);
|
|
238
|
+
}
|
|
239
|
+
return out.join('');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function _b16_decode_impl(s, Error_cls) {
|
|
243
|
+
if (s.length % 2 !== 0) throw new Error_cls('Odd-length string');
|
|
244
|
+
var out = [];
|
|
245
|
+
for (var i = 0; i < s.length; i += 2) {
|
|
246
|
+
var v = parseInt(s.slice(i, i + 2), 16);
|
|
247
|
+
if (isNaN(v)) throw new Error_cls('Non-hexadecimal digit found');
|
|
248
|
+
out.push(v);
|
|
249
|
+
}
|
|
250
|
+
return out;
|
|
251
|
+
}
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
# ---------------------------------------------------------------------------
|
|
256
|
+
# Public API — Base64
|
|
257
|
+
# ---------------------------------------------------------------------------
|
|
258
|
+
|
|
259
|
+
def b64encode(s, altchars=None):
|
|
260
|
+
"""Encode bytes *s* using Base64, returning a bytes object.
|
|
261
|
+
|
|
262
|
+
*altchars* is an optional 2-byte bytes-like whose two characters replace
|
|
263
|
+
``+`` and ``/`` in the output (e.g. ``b'-_'`` for URL-safe encoding).
|
|
264
|
+
"""
|
|
265
|
+
data = v'_b64_to_arr(s)'
|
|
266
|
+
if altchars is not None:
|
|
267
|
+
alt = v'_b64_to_arr(altchars)'
|
|
268
|
+
if v'alt.length' != 2:
|
|
269
|
+
raise ValueError('altchars must be a bytes-like of length 2')
|
|
270
|
+
# Build custom alphabet by replacing + and / with the altchars
|
|
271
|
+
alpha = v'_B64_STD.split("+").join(String.fromCharCode(alt[0])).split("/").join(String.fromCharCode(alt[1]))'
|
|
272
|
+
else:
|
|
273
|
+
alpha = v'_B64_STD'
|
|
274
|
+
result = v'_b64_encode_impl(data, alpha)'
|
|
275
|
+
return v'_b64_arr_to_bytes(_b64_to_arr(result))'
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def b64decode(s, altchars=None, validate=False):
|
|
279
|
+
"""Decode Base64-encoded *s*, returning a bytes object.
|
|
280
|
+
|
|
281
|
+
*altchars* is an optional 2-byte bytes-like whose characters are the
|
|
282
|
+
alternatives used for ``+`` and ``/`` in the encoded data.
|
|
283
|
+
If *validate* is ``True``, characters outside the alphabet raise ``Error``.
|
|
284
|
+
Whitespace is stripped unless *validate* is ``True``.
|
|
285
|
+
"""
|
|
286
|
+
s_str = v'_b64_to_str(s)'
|
|
287
|
+
if altchars is not None:
|
|
288
|
+
alt = v'_b64_to_arr(altchars)'
|
|
289
|
+
if v'alt.length' != 2:
|
|
290
|
+
raise ValueError('altchars must be a bytes-like of length 2')
|
|
291
|
+
# Replace altchars back to standard + and / before decoding
|
|
292
|
+
s_str = v's_str.split(String.fromCharCode(alt[0])).join("+").split(String.fromCharCode(alt[1])).join("/")'
|
|
293
|
+
arr = v'_b64_decode_impl(s_str, _B64_STD_TABLE, validate, Error)'
|
|
294
|
+
return bytes(arr)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def standard_b64encode(s):
|
|
298
|
+
"""Encode *s* using the standard Base64 alphabet. Alias for b64encode."""
|
|
299
|
+
return b64encode(s)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def standard_b64decode(s):
|
|
303
|
+
"""Decode standard Base64-encoded *s*. Alias for b64decode."""
|
|
304
|
+
return b64decode(s)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def urlsafe_b64encode(s):
|
|
308
|
+
"""Encode *s* using the URL-safe Base64 alphabet (- and _ instead of + and /)."""
|
|
309
|
+
data = v'_b64_to_arr(s)'
|
|
310
|
+
result = v'_b64_encode_impl(data, _B64_SAFE)'
|
|
311
|
+
return v'_b64_arr_to_bytes(_b64_to_arr(result))'
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def urlsafe_b64decode(s):
|
|
315
|
+
"""Decode URL-safe Base64-encoded *s*, returning bytes."""
|
|
316
|
+
s_str = v'_b64_to_str(s)'
|
|
317
|
+
arr = v'_b64_decode_impl(s_str, _B64_SAFE_TABLE, false, Error)'
|
|
318
|
+
return bytes(arr)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def encodebytes(s):
|
|
322
|
+
"""Encode bytes *s* as Base64, inserting a newline after every 76 characters.
|
|
323
|
+
|
|
324
|
+
Matches Python's ``base64.encodebytes``. The returned bytes always ends
|
|
325
|
+
with a newline.
|
|
326
|
+
"""
|
|
327
|
+
data = v'_b64_to_arr(s)'
|
|
328
|
+
encoded = v'_b64_encode_impl(data, _B64_STD)'
|
|
329
|
+
lines = []
|
|
330
|
+
i = 0
|
|
331
|
+
while i < v'encoded.length':
|
|
332
|
+
chunk = v'encoded.slice(i, i + 76)'
|
|
333
|
+
lines.append(chunk + '\n')
|
|
334
|
+
i += 76
|
|
335
|
+
if v'encoded.length' == 0:
|
|
336
|
+
lines.append('\n')
|
|
337
|
+
result_str = v'lines.join("")'
|
|
338
|
+
return v'_b64_arr_to_bytes(_b64_to_arr(result_str))'
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def decodebytes(s):
|
|
342
|
+
"""Decode Base64 data from *s*, ignoring newline characters."""
|
|
343
|
+
s_str = v'_b64_to_str(s)'
|
|
344
|
+
# Strip newlines via split/join (avoids backslash-in-regex issues)
|
|
345
|
+
s_str = v's_str.split("\n").join("").split("\r").join("")'
|
|
346
|
+
arr = v'_b64_decode_impl(s_str, _B64_STD_TABLE, false, Error)'
|
|
347
|
+
return bytes(arr)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
# ---------------------------------------------------------------------------
|
|
351
|
+
# Public API — Base32
|
|
352
|
+
# ---------------------------------------------------------------------------
|
|
353
|
+
|
|
354
|
+
def b32encode(s):
|
|
355
|
+
"""Encode bytes *s* using Base32, returning a bytes object."""
|
|
356
|
+
data = v'_b64_to_arr(s)'
|
|
357
|
+
result = v'_b32_encode_impl(data)'
|
|
358
|
+
return v'_b64_arr_to_bytes(_b64_to_arr(result))'
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def b32decode(s, casefold=False, map01=None):
|
|
362
|
+
"""Decode Base32-encoded *s*, returning a bytes object.
|
|
363
|
+
|
|
364
|
+
If *casefold* is ``True``, lowercase letters are accepted.
|
|
365
|
+
*map01* is an optional byte (e.g. ``b'I'``) to map the digit ``1`` to.
|
|
366
|
+
"""
|
|
367
|
+
s_str = v'_b64_to_str(s)'
|
|
368
|
+
if casefold:
|
|
369
|
+
s_str = v's_str.toUpperCase()'
|
|
370
|
+
if map01 is not None:
|
|
371
|
+
target_char = v'String.fromCharCode(_b64_to_arr(map01)[0]).toUpperCase()'
|
|
372
|
+
# Replace '0' with 'O' and '1' with the target character
|
|
373
|
+
s_str = v's_str.split("0").join("O").split("1").join(target_char)'
|
|
374
|
+
arr = v'_b32_decode_impl(s_str, Error)'
|
|
375
|
+
return bytes(arr)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
# ---------------------------------------------------------------------------
|
|
379
|
+
# Public API — Base16 (hex)
|
|
380
|
+
# ---------------------------------------------------------------------------
|
|
381
|
+
|
|
382
|
+
def b16encode(s):
|
|
383
|
+
"""Encode bytes *s* as uppercase hexadecimal, returning a bytes object."""
|
|
384
|
+
data = v'_b64_to_arr(s)'
|
|
385
|
+
result = v'_b16_encode_impl(data)'
|
|
386
|
+
return v'_b64_arr_to_bytes(_b64_to_arr(result))'
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def b16decode(s, casefold=False):
|
|
390
|
+
"""Decode hexadecimal-encoded *s*, returning a bytes object.
|
|
391
|
+
|
|
392
|
+
If *casefold* is ``True``, lowercase hex digits are accepted.
|
|
393
|
+
Raises ``Error`` on invalid input.
|
|
394
|
+
"""
|
|
395
|
+
s_str = v'_b64_to_str(s)'
|
|
396
|
+
if casefold:
|
|
397
|
+
s_str = v's_str.toUpperCase()'
|
|
398
|
+
arr = v'_b16_decode_impl(s_str, Error)'
|
|
399
|
+
return bytes(arr)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
###########################################################
|
|
2
|
+
# RapydScript Standard Library
|
|
3
|
+
# License: Apache License 2.0
|
|
4
|
+
# This library is covered under Apache license, so that
|
|
5
|
+
# you can distribute it with your RapydScript applications.
|
|
6
|
+
###########################################################
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Implementation of Python's 'bisect' module.
|
|
10
|
+
# Binary search and sorted list insertion for maintaining sorted lists.
|
|
11
|
+
#
|
|
12
|
+
# key parameter (Python 3.10+): applied to each array element but NOT to x;
|
|
13
|
+
# pass the desired comparison value as x directly when using key.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def bisect_left(a, x, lo=0, hi=None, key=None):
|
|
17
|
+
if lo < 0:
|
|
18
|
+
raise ValueError('lo must be non-negative')
|
|
19
|
+
if hi is None:
|
|
20
|
+
hi = a.length
|
|
21
|
+
if key is None:
|
|
22
|
+
while lo < hi:
|
|
23
|
+
mid = Math.floor((lo + hi) / 2)
|
|
24
|
+
if a[mid] < x:
|
|
25
|
+
lo = mid + 1
|
|
26
|
+
else:
|
|
27
|
+
hi = mid
|
|
28
|
+
else:
|
|
29
|
+
while lo < hi:
|
|
30
|
+
mid = Math.floor((lo + hi) / 2)
|
|
31
|
+
if key(a[mid]) < x:
|
|
32
|
+
lo = mid + 1
|
|
33
|
+
else:
|
|
34
|
+
hi = mid
|
|
35
|
+
return lo
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def bisect_right(a, x, lo=0, hi=None, key=None):
|
|
39
|
+
if lo < 0:
|
|
40
|
+
raise ValueError('lo must be non-negative')
|
|
41
|
+
if hi is None:
|
|
42
|
+
hi = a.length
|
|
43
|
+
if key is None:
|
|
44
|
+
while lo < hi:
|
|
45
|
+
mid = Math.floor((lo + hi) / 2)
|
|
46
|
+
if x < a[mid]:
|
|
47
|
+
hi = mid
|
|
48
|
+
else:
|
|
49
|
+
lo = mid + 1
|
|
50
|
+
else:
|
|
51
|
+
while lo < hi:
|
|
52
|
+
mid = Math.floor((lo + hi) / 2)
|
|
53
|
+
if x < key(a[mid]):
|
|
54
|
+
hi = mid
|
|
55
|
+
else:
|
|
56
|
+
lo = mid + 1
|
|
57
|
+
return lo
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
bisect = bisect_right
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def insort_left(a, x, lo=0, hi=None, key=None):
|
|
64
|
+
idx = bisect_left(a, x, lo, hi, key)
|
|
65
|
+
a.splice(idx, 0, x)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def insort_right(a, x, lo=0, hi=None, key=None):
|
|
69
|
+
idx = bisect_right(a, x, lo, hi, key)
|
|
70
|
+
a.splice(idx, 0, x)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
insort = insort_right
|
package/src/lib/collections.pyj
CHANGED
|
@@ -13,7 +13,7 @@ def namedtuple(typename, field_names):
|
|
|
13
13
|
"""Return a new class with named fields, like Python's collections.namedtuple."""
|
|
14
14
|
if isinstance(field_names, str):
|
|
15
15
|
# Use explicit JS regex split for cross-environment safety
|
|
16
|
-
fields = v"field_names.replace(/,/g, ' ').trim().split(
|
|
16
|
+
fields = v"field_names.replace(/,/g, ' ').trim().split(/\s+/).filter(function(s){return s.length>0;})"
|
|
17
17
|
else:
|
|
18
18
|
fields = list(field_names)
|
|
19
19
|
n = fields.length
|