rapydscript-ns 0.8.3 → 0.8.4
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 +8 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/PYTHON_DIFFERENCES_REPORT.md +2 -2
- package/PYTHON_FEATURE_COVERAGE.md +13 -13
- package/README.md +670 -6
- package/TODO.md +5 -6
- 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 +155 -6
- package/package.json +1 -1
- package/publish.py +37 -37
- package/release/baselib-plain-pretty.js +2006 -229
- package/release/baselib-plain-ugly.js +70 -3
- package/release/compiler.js +11554 -3870
- package/release/signatures.json +31 -29
- package/session.vim +4 -4
- package/setup.cfg +2 -2
- package/src/ast.pyj +93 -1
- package/src/baselib-builtins.pyj +22 -1
- package/src/baselib-containers.pyj +99 -0
- package/src/baselib-errors.pyj +44 -0
- package/src/baselib-internal.pyj +94 -4
- package/src/baselib-itertools.pyj +97 -97
- package/src/baselib-str.pyj +24 -0
- package/src/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/aes.pyj +646 -646
- package/src/lib/copy.pyj +120 -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/itertools.pyj +580 -580
- 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/re.pyj +470 -470
- package/src/lib/react.pyj +74 -0
- package/src/lib/traceback.pyj +63 -63
- package/src/lib/uuid.pyj +77 -77
- package/src/monaco-language-service/builtins.js +5 -0
- package/src/monaco-language-service/diagnostics.js +25 -3
- package/src/monaco-language-service/dts.js +550 -550
- package/src/output/classes.pyj +108 -8
- package/src/output/codegen.pyj +16 -2
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -105
- package/src/output/functions.pyj +9 -0
- package/src/output/jsx.pyj +164 -0
- package/src/output/literals.pyj +28 -2
- package/src/output/modules.pyj +1 -1
- package/src/output/operators.pyj +8 -2
- package/src/output/statements.pyj +2 -2
- package/src/output/stream.pyj +1 -0
- package/src/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/parse.pyj +417 -113
- package/src/string_interpolation.pyj +72 -72
- package/src/tokenizer.pyj +29 -0
- 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/decorators.pyj +77 -77
- package/test/docstrings.pyj +39 -39
- package/test/elementmaker_test.pyj +45 -45
- package/test/functions.pyj +151 -151
- package/test/generators.pyj +41 -41
- package/test/generic.pyj +370 -370
- package/test/imports.pyj +72 -72
- package/test/internationalization.pyj +73 -73
- package/test/lint.pyj +164 -164
- package/test/loops.pyj +85 -85
- package/test/numpy.pyj +734 -734
- package/test/omit_function_metadata.pyj +20 -20
- package/test/python_features.pyj +19 -6
- package/test/regexp.pyj +55 -55
- package/test/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- package/test/unit/index.js +2177 -64
- package/test/unit/language-service-dts.js +543 -543
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service.js +590 -4
- package/test/unit/web-repl.js +303 -0
- package/tools/cli.js +547 -547
- package/tools/compile.js +219 -219
- package/tools/completer.js +131 -131
- package/tools/embedded_compiler.js +251 -251
- 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 -74
- package/web-repl/index.html +163 -163
- package/web-repl/main.js +252 -254
- package/web-repl/prism.css +139 -139
- package/web-repl/prism.js +113 -113
- package/web-repl/rapydscript.js +224 -102
- package/web-repl/sha1.js +25 -25
- package/hack_demo.pyj +0 -112
package/release/signatures.json
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
{
|
|
2
|
-
"ast": "
|
|
3
|
-
"baselib-builtins": "
|
|
4
|
-
"baselib-containers": "
|
|
5
|
-
"baselib-errors": "
|
|
6
|
-
"baselib-internal": "
|
|
7
|
-
"baselib-itertools": "
|
|
8
|
-
"baselib-str": "
|
|
9
|
-
"compiler": "
|
|
10
|
-
"errors": "
|
|
11
|
-
"output
|
|
12
|
-
"output
|
|
13
|
-
"output
|
|
14
|
-
"output
|
|
15
|
-
"output
|
|
16
|
-
"output
|
|
17
|
-
"output
|
|
18
|
-
"output
|
|
19
|
-
"output
|
|
20
|
-
"output
|
|
21
|
-
"output
|
|
22
|
-
"output
|
|
23
|
-
"output
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
2
|
+
"ast": "c8f6f1be6f7f73b1b9e2bbf470f5e2e5fff879df",
|
|
3
|
+
"baselib-builtins": "ced189b19392b1f425a1a180b90bc61e5e1b022f",
|
|
4
|
+
"baselib-containers": "d2f534e6530dfb309b074bf7fac082c65779e778",
|
|
5
|
+
"baselib-errors": "a9e8c63e450360fd0bd70642d4c107672d395ccf",
|
|
6
|
+
"baselib-internal": "b020b5154a7ee023ceb5852bf35eeee31e285d87",
|
|
7
|
+
"baselib-itertools": "425f5c45bbd5de894cae891e71ba1a9e9e2063d5",
|
|
8
|
+
"baselib-str": "a00bdd267521d31d97cdc76581f955b6fafb4bae",
|
|
9
|
+
"compiler": "bb16e915c60dc4ffb5bfe98bef411736d19fa297",
|
|
10
|
+
"errors": "257eca38b6de987e5fd80672bec9b9981847e1bd",
|
|
11
|
+
"output\\classes": "a88c3c84ded9049d7a5052fb151d51bdbb600dcd",
|
|
12
|
+
"output\\codegen": "69151b2cd53ff8b3270a122c65e1a0f56735150e",
|
|
13
|
+
"output\\comments": "63b39620f9d6f407aa2d4ddb557d1c60ef296b05",
|
|
14
|
+
"output\\exceptions": "e7d9119550403e6c5730d40b9bc9c923a23d6eb7",
|
|
15
|
+
"output\\functions": "58972ccc4562ab3422317f79f68ea3e00b765279",
|
|
16
|
+
"output\\jsx": "14f32c048301965de7764c5b74b651bc279de937",
|
|
17
|
+
"output\\literals": "287ec4222c79f1ebfa2c6efae925e794cbb931ab",
|
|
18
|
+
"output\\loops": "93afeea09e81382edf1c2f6009f4811430d0ebb8",
|
|
19
|
+
"output\\modules": "15735b9b07260d11ba231fc3439818bd1a54947e",
|
|
20
|
+
"output\\operators": "d9ebb70a00cfe6be60c5d75596edf7986f619644",
|
|
21
|
+
"output\\statements": "94ee0cd084f22aea451b96eb1a9a831084cc4267",
|
|
22
|
+
"output\\stream": "2723d80bc398468e0828f50fb0837095c52f45dc",
|
|
23
|
+
"output\\treeshake": "4a490ba097739d924db9e3cd9eb7718db5e24cae",
|
|
24
|
+
"output\\utils": "e957919bfccb9a3ab510d824a8f2ee3fc2689795",
|
|
25
|
+
"output\\__init__": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
|
|
26
|
+
"parse": "1815f278b2b974ed79973f792a4dbcccfb35c2b8",
|
|
27
|
+
"string_interpolation": "88dce6c2c5ee75126a6838a1506841c6531a0d15",
|
|
28
|
+
"tokenizer": "6c06a87951cc4cfe6256dfa4f22ab3533967e856",
|
|
29
|
+
"unicode_aliases": "7fbcbc9c24adcb2e33fac8d69aaafe5047fcc2c2",
|
|
30
|
+
"utils": "35a2a707c841da851e18c64edac54e7c20b7dfc9",
|
|
31
|
+
"#compiler#": "724970153770773cd9e1ff1e588f17df9c607ee9",
|
|
32
|
+
"#compiled_with#": "724970153770773cd9e1ff1e588f17df9c607ee9"
|
|
31
33
|
}
|
package/session.vim
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
set wildignore+=*.pyj-cached
|
|
2
|
-
set wildignore+=node_modules
|
|
3
|
-
imap <F4> ρσ_
|
|
4
|
-
cmap <F4> ρσ_
|
|
1
|
+
set wildignore+=*.pyj-cached
|
|
2
|
+
set wildignore+=node_modules
|
|
3
|
+
imap <F4> ρσ_
|
|
4
|
+
cmap <F4> ρσ_
|
package/setup.cfg
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
[rapydscript]
|
|
2
|
-
globals=assert,RapydScript
|
|
1
|
+
[rapydscript]
|
|
2
|
+
globals=assert,RapydScript
|
package/src/ast.pyj
CHANGED
|
@@ -600,6 +600,9 @@ class AST_Class(AST_Scope):
|
|
|
600
600
|
'statements': "[AST_Node*] list of statements in the class scope (excluding method definitions)",
|
|
601
601
|
'dynamic_properties': '[dict] map of dynamic property names to property descriptors of the form {getter:AST_Method, setter:AST_Method',
|
|
602
602
|
'classvars': '[dict] map containing all class variables as keys, to be used to easily test for existence of a class variable',
|
|
603
|
+
'has_new': "[boolean] true if the class defines a __new__ method",
|
|
604
|
+
'has_attr_dunders': "[boolean] true if the class defines any of __getattr__/__setattr__/__delattr__/__getattribute__",
|
|
605
|
+
'class_kwargs': "[array] keyword arguments from class header (e.g. class C(Base, key=val):) as [[key_node, value_node], ...]",
|
|
603
606
|
}
|
|
604
607
|
|
|
605
608
|
def _walk(self, visitor):
|
|
@@ -610,6 +613,9 @@ class AST_Class(AST_Scope):
|
|
|
610
613
|
self.name._walk(visitor)
|
|
611
614
|
walk_body(self, visitor)
|
|
612
615
|
if (self.parent) self.parent._walk(visitor)
|
|
616
|
+
if self.class_kwargs:
|
|
617
|
+
for kw in self.class_kwargs:
|
|
618
|
+
kw[1]._walk(visitor)
|
|
613
619
|
)
|
|
614
620
|
|
|
615
621
|
class AST_Method(AST_Lambda):
|
|
@@ -725,7 +731,8 @@ class AST_Except(AST_Block):
|
|
|
725
731
|
"An `except` node for RapydScript, which resides inside the catch block"
|
|
726
732
|
properties = {
|
|
727
733
|
'argname': "[AST_SymbolCatch] symbol for the exception",
|
|
728
|
-
'errors': "[AST_SymbolVar*] error classes to catch in this block"
|
|
734
|
+
'errors': "[AST_SymbolVar*] error classes to catch in this block",
|
|
735
|
+
'is_star': '[bool] True for except* (exception group) clauses',
|
|
729
736
|
}
|
|
730
737
|
|
|
731
738
|
def _walk(self, visitor):
|
|
@@ -1161,6 +1168,17 @@ class AST_ObjectSpread(AST_Node):
|
|
|
1161
1168
|
self.value._walk(visitor)
|
|
1162
1169
|
)
|
|
1163
1170
|
|
|
1171
|
+
class AST_Spread(AST_Node):
|
|
1172
|
+
"A *expr spread item inside a list or set literal: [1, *a, 2]"
|
|
1173
|
+
properties = {
|
|
1174
|
+
'expression': "[AST_Node] the expression being spread",
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
def _walk(self, visitor):
|
|
1178
|
+
return visitor._visit(self, def():
|
|
1179
|
+
self.expression._walk(visitor)
|
|
1180
|
+
)
|
|
1181
|
+
|
|
1164
1182
|
class AST_Set(AST_Node):
|
|
1165
1183
|
"A set literal"
|
|
1166
1184
|
properties = {
|
|
@@ -1360,6 +1378,80 @@ class TreeWalker:
|
|
|
1360
1378
|
self = p
|
|
1361
1379
|
# }}}
|
|
1362
1380
|
|
|
1381
|
+
# JSX nodes {{{
|
|
1382
|
+
|
|
1383
|
+
class AST_JSXElement(AST_Node):
|
|
1384
|
+
"A JSX element like <div>...</div> or <Component />"
|
|
1385
|
+
properties = {
|
|
1386
|
+
'tag': "[string] The tag name (e.g. 'div', 'MyComponent')",
|
|
1387
|
+
'props': "[AST_JSXAttribute[]] The props/attributes",
|
|
1388
|
+
'children': "[AST_Node[]] The children",
|
|
1389
|
+
'self_closing': "[bool] Whether self-closing (no children)"
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
def _walk(self, visitor):
|
|
1393
|
+
return visitor._visit(self, def():
|
|
1394
|
+
for prop in self.props:
|
|
1395
|
+
prop._walk(visitor)
|
|
1396
|
+
for child in self.children:
|
|
1397
|
+
child._walk(visitor)
|
|
1398
|
+
)
|
|
1399
|
+
|
|
1400
|
+
class AST_JSXFragment(AST_Node):
|
|
1401
|
+
"A JSX fragment <>...</>"
|
|
1402
|
+
properties = {
|
|
1403
|
+
'children': "[AST_Node[]] The children"
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
def _walk(self, visitor):
|
|
1407
|
+
return visitor._visit(self, def():
|
|
1408
|
+
for child in self.children:
|
|
1409
|
+
child._walk(visitor)
|
|
1410
|
+
)
|
|
1411
|
+
|
|
1412
|
+
class AST_JSXAttribute(AST_Node):
|
|
1413
|
+
"A JSX attribute like prop='val', prop={expr}, or just prop (boolean)"
|
|
1414
|
+
properties = {
|
|
1415
|
+
'name': "[string] The attribute name",
|
|
1416
|
+
'value': "[AST_Node|null] The value (null for boolean attrs)"
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
def _walk(self, visitor):
|
|
1420
|
+
return visitor._visit(self, def():
|
|
1421
|
+
if self.value:
|
|
1422
|
+
self.value._walk(visitor)
|
|
1423
|
+
)
|
|
1424
|
+
|
|
1425
|
+
class AST_JSXSpread(AST_Node):
|
|
1426
|
+
"A JSX spread attribute {...expr}"
|
|
1427
|
+
properties = {
|
|
1428
|
+
'expression': "[AST_Node] The spread expression"
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
def _walk(self, visitor):
|
|
1432
|
+
return visitor._visit(self, def():
|
|
1433
|
+
self.expression._walk(visitor)
|
|
1434
|
+
)
|
|
1435
|
+
|
|
1436
|
+
class AST_JSXText(AST_Node):
|
|
1437
|
+
"Text content inside a JSX element"
|
|
1438
|
+
properties = {
|
|
1439
|
+
'value': "[string] The text content"
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
class AST_JSXExprContainer(AST_Node):
|
|
1443
|
+
"A JSX expression container {expr}"
|
|
1444
|
+
properties = {
|
|
1445
|
+
'expression': "[AST_Node] The expression"
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
def _walk(self, visitor):
|
|
1449
|
+
return visitor._visit(self, def():
|
|
1450
|
+
self.expression._walk(visitor)
|
|
1451
|
+
)
|
|
1452
|
+
|
|
1453
|
+
# }}}
|
|
1454
|
+
|
|
1363
1455
|
class Found(Exception):
|
|
1364
1456
|
pass
|
|
1365
1457
|
|
package/src/baselib-builtins.pyj
CHANGED
|
@@ -20,6 +20,7 @@ def ρσ_bool(val):
|
|
|
20
20
|
v'if ((typeof Set === "function" && val instanceof Set) || (typeof Map === "function" && val instanceof Map)) return val.size > 0'
|
|
21
21
|
v'if (!val.constructor || val.constructor === Object) return Object.keys(val).length > 0'
|
|
22
22
|
return True
|
|
23
|
+
ρσ_bool.__name__ = 'bool'
|
|
23
24
|
|
|
24
25
|
def ρσ_print(*args, **kwargs):
|
|
25
26
|
if v'typeof console' is 'object':
|
|
@@ -35,6 +36,7 @@ def ρσ_int(val, base):
|
|
|
35
36
|
if isNaN(ans):
|
|
36
37
|
raise ValueError('Invalid literal for int with base ' + (base or 10) + ': ' + val)
|
|
37
38
|
return ans
|
|
39
|
+
ρσ_int.__name__ = 'int'
|
|
38
40
|
|
|
39
41
|
def ρσ_float(val):
|
|
40
42
|
if jstype(val) is "number":
|
|
@@ -44,6 +46,7 @@ def ρσ_float(val):
|
|
|
44
46
|
if isNaN(ans):
|
|
45
47
|
raise ValueError('Could not convert string to float: ' + arguments[0])
|
|
46
48
|
return ans
|
|
49
|
+
ρσ_float.__name__ = 'float'
|
|
47
50
|
|
|
48
51
|
def ρσ_arraylike_creator():
|
|
49
52
|
names = 'Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' ')
|
|
@@ -282,6 +285,23 @@ def ρσ_hasattr(obj, name):
|
|
|
282
285
|
def ρσ_get_module(name):
|
|
283
286
|
return ρσ_modules[name]
|
|
284
287
|
|
|
288
|
+
def ρσ__import__(name, globals, locals, fromlist, level):
|
|
289
|
+
# Return the module from the already-compiled ρσ_modules registry.
|
|
290
|
+
# Like Python: without fromlist (or empty fromlist) returns the top-level
|
|
291
|
+
# package; with a non-empty fromlist returns the named (possibly dotted) module.
|
|
292
|
+
# NOTE: the module must have been statically imported elsewhere in the source;
|
|
293
|
+
# __import__ only provides a runtime reference to an already-compiled module.
|
|
294
|
+
if v'typeof ρσ_modules' is 'undefined':
|
|
295
|
+
raise ImportError('No module named \'' + name + '\'')
|
|
296
|
+
if fromlist is not undefined and fromlist is not None and fromlist.length:
|
|
297
|
+
lookup = name
|
|
298
|
+
else:
|
|
299
|
+
lookup = name.split('.')[0]
|
|
300
|
+
module = ρσ_modules[lookup]
|
|
301
|
+
if module is undefined:
|
|
302
|
+
raise ModuleNotFoundError('No module named \'' + lookup + '\'')
|
|
303
|
+
return module
|
|
304
|
+
|
|
285
305
|
def ρσ_pow(x, y, z):
|
|
286
306
|
ans = Math.pow(x, y)
|
|
287
307
|
if z is not undefined:
|
|
@@ -322,6 +342,7 @@ def ρσ_hash(obj):
|
|
|
322
342
|
}
|
|
323
343
|
return ρσ_h;
|
|
324
344
|
}'''
|
|
345
|
+
v'if (obj.__hash__ === null) throw new TypeError("unhashable type: \'" + (obj.constructor && obj.constructor.name ? obj.constructor.name : "object") + "\'")'
|
|
325
346
|
v'if (typeof obj.__hash__ === "function") return obj.__hash__()'
|
|
326
347
|
v'if (Array.isArray(obj)) throw new TypeError("unhashable type: \'list\'")'
|
|
327
348
|
v'if (typeof ρσ_set === "function" && obj instanceof ρσ_set) throw new TypeError("unhashable type: \'set\'")'
|
|
@@ -440,7 +461,7 @@ class ρσ_slice:
|
|
|
440
461
|
|
|
441
462
|
v'var abs = Math.abs, max = ρσ_max.bind(Math.max), min = ρσ_max.bind(Math.min), bool = ρσ_bool, type = ρσ_type'
|
|
442
463
|
v'var float = ρσ_float, int = ρσ_int, arraylike = ρσ_arraylike_creator(), ρσ_arraylike = arraylike'
|
|
443
|
-
v'var id = ρσ_id, get_module = ρσ_get_module, pow = ρσ_pow, divmod = ρσ_divmod'
|
|
464
|
+
v'var id = ρσ_id, get_module = ρσ_get_module, pow = ρσ_pow, divmod = ρσ_divmod, __import__ = ρσ__import__'
|
|
444
465
|
v'var dir = ρσ_dir, ord = ρσ_ord, chr = ρσ_chr, bin = ρσ_bin, hex = ρσ_hex, callable = ρσ_callable, round = ρσ_round'
|
|
445
466
|
v'var enumerate = ρσ_enumerate, iter = ρσ_iter, reversed = ρσ_reversed, len = ρσ_len'
|
|
446
467
|
v'var range = ρσ_range, getattr = ρσ_getattr, setattr = ρσ_setattr, hasattr = ρσ_hasattr, issubclass = ρσ_issubclass, hash = ρσ_hash, next = ρσ_next'
|
|
@@ -243,6 +243,26 @@ def sorted(iterable, key=None, reverse=False):
|
|
|
243
243
|
return ans
|
|
244
244
|
# }}}
|
|
245
245
|
|
|
246
|
+
# tuple {{{
|
|
247
|
+
def ρσ_tuple_constructor(iterable):
|
|
248
|
+
if iterable is undefined:
|
|
249
|
+
return v'[]'
|
|
250
|
+
if ρσ_arraylike(iterable):
|
|
251
|
+
return Array.prototype.slice.call(iterable)
|
|
252
|
+
if jstype(iterable[ρσ_iterator_symbol]) is 'function':
|
|
253
|
+
iterator = iterable.keys() if jstype(Map) is 'function' and v'iterable instanceof Map' else iterable[ρσ_iterator_symbol]()
|
|
254
|
+
ans = []
|
|
255
|
+
result = iterator.next()
|
|
256
|
+
while not result.done:
|
|
257
|
+
ans.push(result.value)
|
|
258
|
+
result = iterator.next()
|
|
259
|
+
return ans
|
|
260
|
+
return Object.keys(iterable)
|
|
261
|
+
|
|
262
|
+
ρσ_tuple_constructor.__name__ = 'tuple'
|
|
263
|
+
v'var tuple = ρσ_tuple_constructor'
|
|
264
|
+
# }}}
|
|
265
|
+
|
|
246
266
|
# set {{{
|
|
247
267
|
v'var ρσ_global_object_id = 0, ρσ_set_implementation'
|
|
248
268
|
|
|
@@ -698,6 +718,12 @@ def ρσ_dict_polyfill():
|
|
|
698
718
|
return v"{'done':false, 'value':this._s[this._keys[this._i]]}"
|
|
699
719
|
return ans
|
|
700
720
|
|
|
721
|
+
ρσ_dict_polyfill.prototype.forEach = def(callback):
|
|
722
|
+
keys = Object.keys(this._store)
|
|
723
|
+
for v'var ρσ_fi = 0; ρσ_fi < keys.length; ρσ_fi++':
|
|
724
|
+
entry = this._store[keys[v'ρσ_fi']]
|
|
725
|
+
callback(entry[1], entry[0], this)
|
|
726
|
+
|
|
701
727
|
if jstype(Map) is not 'function' or jstype(Map.prototype.delete) is not 'function':
|
|
702
728
|
v'ρσ_dict_implementation = ρσ_dict_polyfill'
|
|
703
729
|
else:
|
|
@@ -862,6 +888,15 @@ Object.defineProperties(ρσ_dict.prototype, {
|
|
|
862
888
|
r = iterator.next()
|
|
863
889
|
return ans
|
|
864
890
|
|
|
891
|
+
ρσ_dict.prototype.toJSON = def():
|
|
892
|
+
ans = {}
|
|
893
|
+
iterator = this.jsmap.entries()
|
|
894
|
+
r = iterator.next()
|
|
895
|
+
while not r.done:
|
|
896
|
+
ans[r.value[0]] = r.value[1]
|
|
897
|
+
r = iterator.next()
|
|
898
|
+
return ans
|
|
899
|
+
|
|
865
900
|
def ρσ_dict_wrap(x):
|
|
866
901
|
ans = new ρσ_dict()
|
|
867
902
|
ans.jsmap = x
|
|
@@ -869,4 +904,68 @@ def ρσ_dict_wrap(x):
|
|
|
869
904
|
|
|
870
905
|
v'var dict = ρσ_dict, dict_wrap = ρσ_dict_wrap'
|
|
871
906
|
|
|
907
|
+
v'''
|
|
908
|
+
function ρσ_kwargs_to_dict(kw) {
|
|
909
|
+
// Augment the plain kwargs object with non-enumerable Python dict methods so
|
|
910
|
+
// that kw.items(), kw.keys(), kw.values() work in user code, while plain
|
|
911
|
+
// property access (kw.propname) and Object.keys(kw) are unaffected.
|
|
912
|
+
//
|
|
913
|
+
// items/keys/values return dual-mode arrays: they support both Array indexing
|
|
914
|
+
// (for ρσ_dict.prototype.update which does pairs[i]) and iterator protocol
|
|
915
|
+
// (for `for k, v in kw.items():` which calls .next()).
|
|
916
|
+
function _make_seq(arr) {
|
|
917
|
+
arr._ρσ_i = 0;
|
|
918
|
+
arr.next = function() {
|
|
919
|
+
return this._ρσ_i < this.length
|
|
920
|
+
? {done: false, value: this[this._ρσ_i++]}
|
|
921
|
+
: {done: true, value: undefined};
|
|
922
|
+
};
|
|
923
|
+
arr[ρσ_iterator_symbol] = function() { this._ρσ_i = 0; return this; };
|
|
924
|
+
return arr;
|
|
925
|
+
}
|
|
926
|
+
function _def(name, fn) {
|
|
927
|
+
if (!Object.prototype.hasOwnProperty.call(kw, name)) {
|
|
928
|
+
Object.defineProperty(kw, name, {value: fn, configurable: true, writable: true, enumerable: false});
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
_def("items", function() {
|
|
932
|
+
var ks = Object.keys(kw), arr = [], i;
|
|
933
|
+
for (i = 0; i < ks.length; i++) arr.push([ks[i], kw[ks[i]]]);
|
|
934
|
+
return _make_seq(arr);
|
|
935
|
+
});
|
|
936
|
+
_def("entries", kw.items);
|
|
937
|
+
_def("keys", function() {
|
|
938
|
+
return _make_seq(Object.keys(kw).slice());
|
|
939
|
+
});
|
|
940
|
+
_def("values", function() {
|
|
941
|
+
var ks = Object.keys(kw), arr = [], i;
|
|
942
|
+
for (i = 0; i < ks.length; i++) arr.push(kw[ks[i]]);
|
|
943
|
+
return _make_seq(arr);
|
|
944
|
+
});
|
|
945
|
+
_def("get", function(k, d) {
|
|
946
|
+
return Object.prototype.hasOwnProperty.call(kw, k) ? kw[k] : (d !== undefined ? d : null);
|
|
947
|
+
});
|
|
948
|
+
_def("__contains__", function(k) { return Object.prototype.hasOwnProperty.call(kw, k); });
|
|
949
|
+
_def("has", function(k) { return Object.prototype.hasOwnProperty.call(kw, k); });
|
|
950
|
+
_def("__len__", function() { return Object.keys(kw).length; });
|
|
951
|
+
kw[ρσ_iterator_symbol] = function() {
|
|
952
|
+
var ks = Object.keys(kw), i = 0;
|
|
953
|
+
return {next: function() {
|
|
954
|
+
return i < ks.length ? {done: false, value: ks[i++]} : {done: true, value: undefined};
|
|
955
|
+
}};
|
|
956
|
+
};
|
|
957
|
+
return kw;
|
|
958
|
+
}
|
|
959
|
+
'''
|
|
960
|
+
|
|
961
|
+
v"""var ρσ_json_parse = function(text, reviver) {
|
|
962
|
+
function dict_reviver(key, value) {
|
|
963
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof ρσ_dict)) {
|
|
964
|
+
value = ρσ_dict(value);
|
|
965
|
+
}
|
|
966
|
+
return reviver ? reviver.call(this, key, value) : value;
|
|
967
|
+
}
|
|
968
|
+
return JSON.parse(text, dict_reviver);
|
|
969
|
+
};"""
|
|
970
|
+
|
|
872
971
|
# }}}
|
package/src/baselib-errors.pyj
CHANGED
|
@@ -38,3 +38,47 @@ class ZeroDivisionError(Exception):
|
|
|
38
38
|
|
|
39
39
|
class StopIteration(Exception):
|
|
40
40
|
pass
|
|
41
|
+
|
|
42
|
+
class ImportError(Exception):
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
class ModuleNotFoundError(ImportError):
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
def _is_exc_class(obj):
|
|
49
|
+
# True when obj is an Error subclass (or Error itself), not a plain predicate function
|
|
50
|
+
return jstype(obj) is 'function' and (obj is Error or (obj.prototype and isinstance(obj.prototype, Error)))
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ExceptionGroup(Exception):
|
|
54
|
+
|
|
55
|
+
def __init__(self, message, exceptions):
|
|
56
|
+
Exception.__init__(self, message)
|
|
57
|
+
self.exceptions = exceptions if exceptions else []
|
|
58
|
+
|
|
59
|
+
def subgroup(self, condition):
|
|
60
|
+
if _is_exc_class(condition):
|
|
61
|
+
matched = [e for e in self.exceptions if isinstance(e, condition)]
|
|
62
|
+
elif callable(condition):
|
|
63
|
+
matched = [e for e in self.exceptions if condition(e)]
|
|
64
|
+
else:
|
|
65
|
+
matched = [e for e in self.exceptions if isinstance(e, condition)]
|
|
66
|
+
return ExceptionGroup(self.message, matched) if matched else None
|
|
67
|
+
|
|
68
|
+
def split(self, condition):
|
|
69
|
+
if _is_exc_class(condition):
|
|
70
|
+
matched = [e for e in self.exceptions if isinstance(e, condition)]
|
|
71
|
+
rest = [e for e in self.exceptions if not isinstance(e, condition)]
|
|
72
|
+
elif callable(condition):
|
|
73
|
+
matched = [e for e in self.exceptions if condition(e)]
|
|
74
|
+
rest = [e for e in self.exceptions if not condition(e)]
|
|
75
|
+
else:
|
|
76
|
+
matched = [e for e in self.exceptions if isinstance(e, condition)]
|
|
77
|
+
rest = [e for e in self.exceptions if not isinstance(e, condition)]
|
|
78
|
+
return [
|
|
79
|
+
ExceptionGroup(self.message, matched) if matched else None,
|
|
80
|
+
ExceptionGroup(self.message, rest) if rest else None
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
def __repr__(self):
|
|
84
|
+
return 'ExceptionGroup(' + repr(self.message) + ', ' + repr(self.exceptions) + ')'
|
package/src/baselib-internal.pyj
CHANGED
|
@@ -87,6 +87,14 @@ def ρσ_extends(child, parent):
|
|
|
87
87
|
child.prototype.constructor = child
|
|
88
88
|
Object.setPrototypeOf(child, parent)
|
|
89
89
|
|
|
90
|
+
def ρσ_object_new(cls):
|
|
91
|
+
return v'Object.create(cls.prototype)'
|
|
92
|
+
|
|
93
|
+
def ρσ_new(parent, cls):
|
|
94
|
+
if parent and jstype(parent.__new__) is 'function':
|
|
95
|
+
return parent.__new__.apply(parent, v'Array.prototype.slice.call(arguments, 1)')
|
|
96
|
+
return v'Object.create(cls.prototype)'
|
|
97
|
+
|
|
90
98
|
ρσ_in = (def ():
|
|
91
99
|
if jstype(Map) is 'function' and jstype(Set) is 'function':
|
|
92
100
|
return def(val, arr):
|
|
@@ -131,15 +139,23 @@ def ρσ_Iterable(iterable):
|
|
|
131
139
|
ans = Object.create(None)
|
|
132
140
|
ans[ρσ_kwargs_symbol] = True
|
|
133
141
|
for v'var i = 0; i < arguments.length; i++':
|
|
134
|
-
|
|
142
|
+
arg = arguments[i]
|
|
143
|
+
if v'arg && arg.jsmap && typeof arg.jsmap.forEach === "function"':
|
|
144
|
+
v'arg.jsmap.forEach(function(v, k) { ans[k] = v; })'
|
|
145
|
+
else:
|
|
146
|
+
Object.assign(ans, arg)
|
|
135
147
|
return ans
|
|
136
148
|
return def():
|
|
137
149
|
ans = Object.create(None)
|
|
138
150
|
ans[ρσ_kwargs_symbol] = True
|
|
139
151
|
for v'var i = 0; i < arguments.length; i++':
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
ans[
|
|
152
|
+
arg = arguments[i]
|
|
153
|
+
if v'arg && arg.jsmap && typeof arg.jsmap.forEach === "function"':
|
|
154
|
+
v'arg.jsmap.forEach(function(v, k) { ans[k] = v; })'
|
|
155
|
+
else:
|
|
156
|
+
keys = Object.keys(arg)
|
|
157
|
+
for v'var j = 0; j < keys.length; j++':
|
|
158
|
+
ans[keys[j]] = arg[keys[j]]
|
|
143
159
|
return ans
|
|
144
160
|
)()
|
|
145
161
|
|
|
@@ -177,6 +193,8 @@ def ρσ_interpolate_kwargs_constructor(apply, f, supplied_args):
|
|
|
177
193
|
return this
|
|
178
194
|
|
|
179
195
|
def ρσ_getitem(obj, key):
|
|
196
|
+
if v'typeof obj === "function"' and obj.__class_getitem__:
|
|
197
|
+
return obj.__class_getitem__(key)
|
|
180
198
|
if obj.__getitem__:
|
|
181
199
|
return obj.__getitem__(key)
|
|
182
200
|
if v'typeof ρσ_slice !== "undefined" && key instanceof ρσ_slice':
|
|
@@ -458,3 +476,75 @@ def ρσ_instanceof():
|
|
|
458
476
|
break
|
|
459
477
|
cls = p.constructor
|
|
460
478
|
return False
|
|
479
|
+
|
|
480
|
+
# ── Attribute-dunder support (__getattr__ / __setattr__ / __delattr__ / __getattribute__) ──
|
|
481
|
+
# We use a JavaScript Proxy to intercept attribute access/assignment/deletion on class instances
|
|
482
|
+
# that define any of the four attribute dunders.
|
|
483
|
+
|
|
484
|
+
# Cache the JS Proxy constructor with a ρσ_ name to avoid collisions with user-defined 'Proxy' classes.
|
|
485
|
+
ρσ_JS_Proxy = v'typeof Proxy === "function" ? Proxy : null'
|
|
486
|
+
|
|
487
|
+
# Symbol (or fallback string key) used to retrieve the raw underlying target from a wrapped proxy.
|
|
488
|
+
ρσ_proxy_target_symbol = v'typeof Symbol === "function" ? Symbol("ρσ_proxy_target") : "__ρσ_proxy_target__"'
|
|
489
|
+
|
|
490
|
+
ρσ_attr_proxy_handler = {
|
|
491
|
+
'get': def(target, prop, receiver):
|
|
492
|
+
# Always expose the raw target via the sentinel key (used by ρσ_object_* helpers).
|
|
493
|
+
if prop is ρσ_proxy_target_symbol:
|
|
494
|
+
return target
|
|
495
|
+
# Pass through JS symbols (Symbol.iterator, Symbol.toPrimitive, etc.) unchanged.
|
|
496
|
+
if jstype(prop) is 'symbol':
|
|
497
|
+
return v'Reflect.get(target, prop, receiver)'
|
|
498
|
+
# __getattribute__ overrides every attribute lookup (except itself, to avoid infinite recursion).
|
|
499
|
+
if jstype(target.__getattribute__) is 'function' and prop is not '__getattribute__':
|
|
500
|
+
try:
|
|
501
|
+
return target.__getattribute__.call(receiver, prop)
|
|
502
|
+
except AttributeError:
|
|
503
|
+
# AttributeError from __getattribute__ → try __getattr__ fallback.
|
|
504
|
+
if jstype(target.__getattr__) is 'function':
|
|
505
|
+
return target.__getattr__.call(receiver, prop)
|
|
506
|
+
raise
|
|
507
|
+
# Normal property lookup via prototype chain.
|
|
508
|
+
val = v'Reflect.get(target, prop, receiver)'
|
|
509
|
+
# __getattr__ is only called when the attribute is genuinely missing.
|
|
510
|
+
if val is undefined and jstype(target.__getattr__) is 'function' and not v'(prop in target)':
|
|
511
|
+
return target.__getattr__.call(receiver, prop)
|
|
512
|
+
return val
|
|
513
|
+
,
|
|
514
|
+
'set': def(target, prop, value, receiver):
|
|
515
|
+
if jstype(target.__setattr__) is 'function':
|
|
516
|
+
target.__setattr__.call(receiver, prop, value)
|
|
517
|
+
return True
|
|
518
|
+
# Pass 'target' as receiver (not proxy) to avoid infinite recursion through the Proxy set trap.
|
|
519
|
+
return v'Reflect.set(target, prop, value, target)'
|
|
520
|
+
,
|
|
521
|
+
'deleteProperty': def(target, prop):
|
|
522
|
+
if jstype(target.__delattr__) is 'function':
|
|
523
|
+
# deleteProperty has no receiver; pass target as 'this'.
|
|
524
|
+
# Inside __delattr__, use ρσ_object_delattr(self, name) for a direct delete.
|
|
525
|
+
target.__delattr__.call(target, prop)
|
|
526
|
+
return True
|
|
527
|
+
return v'Reflect.deleteProperty(target, prop)'
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
def ρσ_object_setattr(obj, name, value):
|
|
531
|
+
# Bypass __setattr__ and set directly on the underlying object.
|
|
532
|
+
# Use this inside __setattr__ to avoid infinite recursion (like object.__setattr__ in Python).
|
|
533
|
+
target = obj[ρσ_proxy_target_symbol]
|
|
534
|
+
if target is undefined:
|
|
535
|
+
target = obj
|
|
536
|
+
v'target[name] = value'
|
|
537
|
+
|
|
538
|
+
def ρσ_object_getattr(obj, name):
|
|
539
|
+
# Bypass __getattribute__ and read directly from the underlying object.
|
|
540
|
+
target = obj[ρσ_proxy_target_symbol]
|
|
541
|
+
if target is undefined:
|
|
542
|
+
target = obj
|
|
543
|
+
return target[name]
|
|
544
|
+
|
|
545
|
+
def ρσ_object_delattr(obj, name):
|
|
546
|
+
# Bypass __delattr__ and delete directly from the underlying object.
|
|
547
|
+
target = obj[ρσ_proxy_target_symbol]
|
|
548
|
+
if target is undefined:
|
|
549
|
+
target = obj
|
|
550
|
+
v'delete target[name]'
|