rapydscript-ns 0.8.2 → 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 +39 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/PYTHON_DIFFERENCES_REPORT.md +291 -0
- package/PYTHON_FEATURE_COVERAGE.md +106 -15
- package/README.md +831 -52
- package/TODO.md +4 -286
- 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 +4623 -0
- package/language-service/language-service.d.ts +40 -0
- package/package.json +9 -7
- 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 +99 -2
- package/src/baselib-containers.pyj +107 -4
- package/src/baselib-errors.pyj +44 -0
- package/src/baselib-internal.pyj +124 -5
- package/src/baselib-itertools.pyj +97 -97
- package/src/baselib-str.pyj +32 -1
- package/src/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/aes.pyj +646 -646
- package/src/lib/collections.pyj +1 -1
- 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/numpy.pyj +10 -10
- 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/analyzer.js +131 -9
- package/src/monaco-language-service/builtins.js +17 -2
- package/src/monaco-language-service/completions.js +170 -1
- package/src/monaco-language-service/diagnostics.js +25 -3
- package/src/monaco-language-service/dts.js +550 -550
- package/src/monaco-language-service/index.js +17 -0
- package/src/monaco-language-service/scope.js +3 -0
- package/src/output/classes.pyj +128 -11
- package/src/output/codegen.pyj +17 -3
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -105
- package/src/output/functions.pyj +13 -16
- package/src/output/jsx.pyj +164 -0
- package/src/output/literals.pyj +28 -2
- package/src/output/loops.pyj +0 -9
- package/src/output/modules.pyj +2 -5
- package/src/output/operators.pyj +22 -2
- package/src/output/statements.pyj +2 -2
- package/src/output/stream.pyj +1 -13
- package/src/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/parse.pyj +434 -114
- 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/baselib.pyj +4 -4
- package/test/classes.pyj +56 -17
- package/test/collections.pyj +5 -5
- 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_compat.pyj +326 -0
- package/test/python_features.pyj +129 -29
- package/test/regexp.pyj +55 -55
- package/test/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- package/test/slice.pyj +105 -0
- package/test/str.pyj +25 -0
- package/test/unit/fixtures/fibonacci_expected.js +1 -1
- package/test/unit/index.js +2296 -71
- package/test/unit/language-service-builtins.js +70 -0
- package/test/unit/language-service-bundle.js +5 -5
- package/test/unit/language-service-completions.js +180 -0
- package/test/unit/language-service-dts.js +543 -543
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service-index.js +350 -0
- package/test/unit/language-service-scope.js +255 -0
- package/test/unit/language-service.js +625 -4
- package/test/unit/run-language-service.js +1 -0
- package/test/unit/web-repl.js +437 -0
- package/tools/build-language-service.js +2 -2
- package/tools/cli.js +547 -547
- package/tools/compile.js +219 -219
- package/tools/compiler.js +0 -24
- package/tools/completer.js +131 -131
- package/tools/embedded_compiler.js +251 -251
- package/tools/export.js +3 -37
- 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 +227 -139
- package/web-repl/sha1.js +25 -25
- package/hack_demo.pyj +0 -112
- package/web-repl/language-service.js +0 -4187
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(' ')
|
|
@@ -164,7 +167,22 @@ def ρσ_reversed(iterable):
|
|
|
164
167
|
return ans
|
|
165
168
|
raise TypeError('reversed() can only be called on arrays or strings')
|
|
166
169
|
|
|
167
|
-
def ρσ_iter(iterable):
|
|
170
|
+
def ρσ_iter(iterable, sentinel):
|
|
171
|
+
# Two-argument form: iter(callable, sentinel) — call repeatedly until sentinel is returned
|
|
172
|
+
if arguments.length >= 2:
|
|
173
|
+
callable_ = iterable
|
|
174
|
+
ans = v'{"_callable":callable_,"_sentinel":sentinel,"_done":false}'
|
|
175
|
+
ans[ρσ_iterator_symbol] = def():
|
|
176
|
+
return this
|
|
177
|
+
ans['next'] = def():
|
|
178
|
+
if this._done:
|
|
179
|
+
return v"{'done':true}"
|
|
180
|
+
val = ρσ_callable_call(this._callable)
|
|
181
|
+
if v'val === this._sentinel':
|
|
182
|
+
this._done = True
|
|
183
|
+
return v"{'done':true}"
|
|
184
|
+
return v"{'done':false,'value':val}"
|
|
185
|
+
return ans
|
|
168
186
|
# Generate a JavaScript iterator object from iterable
|
|
169
187
|
if jstype(iterable[ρσ_iterator_symbol]) is 'function':
|
|
170
188
|
return iterable.keys() if jstype(Map) is 'function' and v'iterable instanceof Map' else iterable[ρσ_iterator_symbol]()
|
|
@@ -267,6 +285,23 @@ def ρσ_hasattr(obj, name):
|
|
|
267
285
|
def ρσ_get_module(name):
|
|
268
286
|
return ρσ_modules[name]
|
|
269
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
|
+
|
|
270
305
|
def ρσ_pow(x, y, z):
|
|
271
306
|
ans = Math.pow(x, y)
|
|
272
307
|
if z is not undefined:
|
|
@@ -307,6 +342,7 @@ def ρσ_hash(obj):
|
|
|
307
342
|
}
|
|
308
343
|
return ρσ_h;
|
|
309
344
|
}'''
|
|
345
|
+
v'if (obj.__hash__ === null) throw new TypeError("unhashable type: \'" + (obj.constructor && obj.constructor.name ? obj.constructor.name : "object") + "\'")'
|
|
310
346
|
v'if (typeof obj.__hash__ === "function") return obj.__hash__()'
|
|
311
347
|
v'if (Array.isArray(obj)) throw new TypeError("unhashable type: \'list\'")'
|
|
312
348
|
v'if (typeof ρσ_set === "function" && obj instanceof ρσ_set) throw new TypeError("unhashable type: \'set\'")'
|
|
@@ -363,11 +399,72 @@ def ρσ_max(*args, **kwargs):
|
|
|
363
399
|
raise TypeError('expected at least one argument')
|
|
364
400
|
|
|
365
401
|
|
|
402
|
+
class ρσ_slice:
|
|
403
|
+
def __init__(self, start_or_stop, stop, step):
|
|
404
|
+
if arguments.length is 1:
|
|
405
|
+
self.start = None
|
|
406
|
+
self.stop = start_or_stop
|
|
407
|
+
self.step = None
|
|
408
|
+
elif arguments.length is 2:
|
|
409
|
+
self.start = start_or_stop
|
|
410
|
+
self.stop = stop
|
|
411
|
+
self.step = None
|
|
412
|
+
else:
|
|
413
|
+
self.start = start_or_stop
|
|
414
|
+
self.stop = stop
|
|
415
|
+
self.step = step
|
|
416
|
+
|
|
417
|
+
def indices(self, length):
|
|
418
|
+
step = 1 if self.step is None else self.step
|
|
419
|
+
if step is 0:
|
|
420
|
+
raise ValueError('slice step cannot be zero')
|
|
421
|
+
if step > 0:
|
|
422
|
+
lower = 0
|
|
423
|
+
upper = length
|
|
424
|
+
start = lower if self.start is None else self.start
|
|
425
|
+
stop = upper if self.stop is None else self.stop
|
|
426
|
+
else:
|
|
427
|
+
lower = -1
|
|
428
|
+
upper = length - 1
|
|
429
|
+
start = upper if self.start is None else self.start
|
|
430
|
+
stop = lower if self.stop is None else self.stop
|
|
431
|
+
# Only clamp values that were explicitly provided (None defaults are already correct).
|
|
432
|
+
if self.start is not None:
|
|
433
|
+
if start < 0:
|
|
434
|
+
start = max(start + length, lower)
|
|
435
|
+
if start > upper:
|
|
436
|
+
start = upper
|
|
437
|
+
if self.stop is not None:
|
|
438
|
+
if stop < 0:
|
|
439
|
+
stop = max(stop + length, lower)
|
|
440
|
+
if stop > upper:
|
|
441
|
+
stop = upper
|
|
442
|
+
return start, stop, step
|
|
443
|
+
|
|
444
|
+
def __repr__(self):
|
|
445
|
+
s = 'None' if self.start is None else String(self.start)
|
|
446
|
+
stop = 'None' if self.stop is None else String(self.stop)
|
|
447
|
+
step = 'None' if self.step is None else String(self.step)
|
|
448
|
+
return 'slice(' + s + ', ' + stop + ', ' + step + ')'
|
|
449
|
+
|
|
450
|
+
def __str__(self):
|
|
451
|
+
return self.__repr__()
|
|
452
|
+
|
|
453
|
+
def __eq__(self, other):
|
|
454
|
+
if not v'other instanceof ρσ_slice':
|
|
455
|
+
return False
|
|
456
|
+
return self.start is other.start and self.stop is other.stop and self.step is other.step
|
|
457
|
+
|
|
458
|
+
def __hash__(self):
|
|
459
|
+
raise TypeError("unhashable type: 'slice'")
|
|
460
|
+
|
|
461
|
+
|
|
366
462
|
v'var abs = Math.abs, max = ρσ_max.bind(Math.max), min = ρσ_max.bind(Math.min), bool = ρσ_bool, type = ρσ_type'
|
|
367
463
|
v'var float = ρσ_float, int = ρσ_int, arraylike = ρσ_arraylike_creator(), ρσ_arraylike = arraylike'
|
|
368
|
-
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__'
|
|
369
465
|
v'var dir = ρσ_dir, ord = ρσ_ord, chr = ρσ_chr, bin = ρσ_bin, hex = ρσ_hex, callable = ρσ_callable, round = ρσ_round'
|
|
370
466
|
v'var enumerate = ρσ_enumerate, iter = ρσ_iter, reversed = ρσ_reversed, len = ρσ_len'
|
|
371
467
|
v'var range = ρσ_range, getattr = ρσ_getattr, setattr = ρσ_setattr, hasattr = ρσ_hasattr, issubclass = ρσ_issubclass, hash = ρσ_hash, next = ρσ_next'
|
|
372
468
|
v'var ρσ_Ellipsis = Object.freeze({toString: function(){return "Ellipsis";}, __repr__: function(){return "Ellipsis";}})'
|
|
373
469
|
v'var Ellipsis = ρσ_Ellipsis'
|
|
470
|
+
v'var slice = ρσ_slice'
|
|
@@ -140,7 +140,7 @@ def ρσ_list_sort(key=None, reverse=False):
|
|
|
140
140
|
k = this[i] # noqa:undef
|
|
141
141
|
keymap.set(k, key(k))
|
|
142
142
|
posmap.set(k, i)
|
|
143
|
-
|
|
143
|
+
Array.prototype.sort.call(this, def (a, b): return mult * ρσ_list_sort_cmp(keymap.get(a), keymap.get(b), posmap.get(a), posmap.get(b));)
|
|
144
144
|
|
|
145
145
|
def ρσ_list_concat(): # ensure concat() returns an object of type list
|
|
146
146
|
ans = Array.prototype.concat.apply(this, arguments)
|
|
@@ -190,14 +190,18 @@ def ρσ_list_decorate(ans):
|
|
|
190
190
|
ans.inspect = ρσ_list_to_string
|
|
191
191
|
ans.extend = ρσ_list_extend
|
|
192
192
|
ans.index = ρσ_list_index
|
|
193
|
-
ans.
|
|
193
|
+
ans.jspop = Array.prototype.pop # native JS pop (no bounds check, ignores args)
|
|
194
|
+
ans.pop = ρσ_list_pop # Python pop (bounds-checked, supports negative index)
|
|
195
|
+
ans.pypop = ρσ_list_pop # backward-compat alias for pop
|
|
194
196
|
ans.remove = ρσ_list_remove
|
|
195
197
|
ans.insert = ρσ_list_insert
|
|
196
198
|
ans.copy = ρσ_list_copy
|
|
197
199
|
ans.clear = ρσ_list_clear
|
|
198
200
|
ans.count = ρσ_list_count
|
|
199
201
|
ans.concat = ρσ_list_concat
|
|
200
|
-
ans.
|
|
202
|
+
ans.jssort = Array.prototype.sort # native JS sort (lexicographic by default)
|
|
203
|
+
ans.sort = ρσ_list_sort # Python sort (numeric by default)
|
|
204
|
+
ans.pysort = ρσ_list_sort # backward-compat alias for sort
|
|
201
205
|
ans.slice = ρσ_list_slice
|
|
202
206
|
ans.as_array = ρσ_list_as_array
|
|
203
207
|
ans.__len__ = ρσ_list_len
|
|
@@ -235,10 +239,30 @@ v'var list = ρσ_list_constructor, list_wrap = ρσ_list_decorate'
|
|
|
235
239
|
|
|
236
240
|
def sorted(iterable, key=None, reverse=False):
|
|
237
241
|
ans = ρσ_list_constructor(iterable)
|
|
238
|
-
ans.
|
|
242
|
+
ans.sort(key, reverse)
|
|
239
243
|
return ans
|
|
240
244
|
# }}}
|
|
241
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
|
+
|
|
242
266
|
# set {{{
|
|
243
267
|
v'var ρσ_global_object_id = 0, ρσ_set_implementation'
|
|
244
268
|
|
|
@@ -694,6 +718,12 @@ def ρσ_dict_polyfill():
|
|
|
694
718
|
return v"{'done':false, 'value':this._s[this._keys[this._i]]}"
|
|
695
719
|
return ans
|
|
696
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
|
+
|
|
697
727
|
if jstype(Map) is not 'function' or jstype(Map.prototype.delete) is not 'function':
|
|
698
728
|
v'ρσ_dict_implementation = ρσ_dict_polyfill'
|
|
699
729
|
else:
|
|
@@ -858,6 +888,15 @@ Object.defineProperties(ρσ_dict.prototype, {
|
|
|
858
888
|
r = iterator.next()
|
|
859
889
|
return ans
|
|
860
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
|
+
|
|
861
900
|
def ρσ_dict_wrap(x):
|
|
862
901
|
ans = new ρσ_dict()
|
|
863
902
|
ans.jsmap = x
|
|
@@ -865,4 +904,68 @@ def ρσ_dict_wrap(x):
|
|
|
865
904
|
|
|
866
905
|
v'var dict = ρσ_dict, dict_wrap = ρσ_dict_wrap'
|
|
867
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
|
+
|
|
868
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) + ')'
|