rapydscript-ns 0.8.4 → 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/.agignore +1 -1
- package/.github/workflows/ci.yml +38 -38
- package/=template.pyj +5 -5
- package/CHANGELOG.md +18 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/README.md +715 -169
- package/TODO.md +9 -2
- 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 +36 -27
- package/package.json +1 -1
- package/publish.py +37 -37
- package/release/baselib-plain-pretty.js +2358 -168
- package/release/baselib-plain-ugly.js +73 -3
- package/release/compiler.js +6282 -3092
- package/release/signatures.json +31 -30
- package/session.vim +4 -4
- package/setup.cfg +2 -2
- package/src/ast.pyj +1 -0
- package/src/baselib-builtins.pyj +340 -2
- package/src/baselib-bytes.pyj +664 -0
- package/src/baselib-errors.pyj +1 -1
- package/src/baselib-internal.pyj +267 -60
- package/src/baselib-itertools.pyj +110 -97
- package/src/baselib-str.pyj +22 -4
- package/src/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/abc.pyj +317 -0
- package/src/lib/aes.pyj +646 -646
- package/src/lib/copy.pyj +120 -120
- package/src/lib/dataclasses.pyj +532 -0
- package/src/lib/elementmaker.pyj +83 -83
- package/src/lib/encodings.pyj +126 -126
- package/src/lib/enum.pyj +125 -0
- 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 +504 -470
- package/src/lib/react.pyj +74 -74
- package/src/lib/traceback.pyj +63 -63
- package/src/lib/typing.pyj +577 -0
- package/src/lib/uuid.pyj +77 -77
- package/src/monaco-language-service/builtins.js +14 -4
- package/src/monaco-language-service/diagnostics.js +19 -20
- package/src/monaco-language-service/dts.js +550 -550
- package/src/output/classes.pyj +62 -26
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -201
- package/src/output/functions.pyj +78 -5
- package/src/output/jsx.pyj +164 -164
- package/src/output/loops.pyj +5 -2
- package/src/output/operators.pyj +100 -34
- package/src/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/parse.pyj +80 -16
- package/src/string_interpolation.pyj +72 -72
- package/src/tokenizer.pyj +9 -4
- 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/abc.pyj +291 -0
- package/test/aes_vectors.pyj +421 -421
- package/test/annotations.pyj +80 -80
- 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/decorators.pyj +77 -77
- package/test/docstrings.pyj +39 -39
- package/test/elementmaker_test.pyj +45 -45
- package/test/enum.pyj +134 -0
- package/test/eval_exec.pyj +56 -0
- package/test/format.pyj +148 -0
- 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/object.pyj +64 -0
- package/test/omit_function_metadata.pyj +20 -20
- package/test/python_compat.pyj +17 -15
- package/test/python_features.pyj +70 -15
- package/test/regexp.pyj +83 -55
- package/test/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- package/test/tuples.pyj +96 -0
- package/test/typing.pyj +469 -0
- package/test/unit/index.js +116 -7
- package/test/unit/language-service-dts.js +543 -543
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service.js +84 -0
- package/test/unit/web-repl.js +804 -1
- package/test/vars_locals_globals.pyj +94 -0
- package/tools/cli.js +558 -547
- package/tools/compile.js +224 -219
- package/tools/completer.js +131 -131
- package/tools/embedded_compiler.js +262 -251
- package/tools/gettext.js +185 -185
- package/tools/ini.js +65 -65
- package/tools/lint.js +16 -19
- 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 +252 -252
- 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/PYTHON_DIFFERENCES_REPORT.md +0 -291
- package/PYTHON_FEATURE_COVERAGE.md +0 -200
package/test/enum.pyj
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# globals: assrt
|
|
2
|
+
# vim:fileencoding=utf-8
|
|
3
|
+
#
|
|
4
|
+
# enum.pyj
|
|
5
|
+
# Tests for the enum standard library (from enum import Enum).
|
|
6
|
+
|
|
7
|
+
ae = assrt.equal
|
|
8
|
+
ade = assrt.deepEqual
|
|
9
|
+
ok = assrt.ok
|
|
10
|
+
|
|
11
|
+
from enum import Enum
|
|
12
|
+
|
|
13
|
+
# ── 1. Basic member access: .name and .value ─────────────────────────────────
|
|
14
|
+
# STATUS: ✓ WORKS
|
|
15
|
+
|
|
16
|
+
class _Color(Enum):
|
|
17
|
+
RED = 1
|
|
18
|
+
GREEN = 2
|
|
19
|
+
BLUE = 3
|
|
20
|
+
|
|
21
|
+
ae(_Color.RED.name, 'RED')
|
|
22
|
+
ae(_Color.RED.value, 1)
|
|
23
|
+
ae(_Color.GREEN.name, 'GREEN')
|
|
24
|
+
ae(_Color.GREEN.value, 2)
|
|
25
|
+
ae(_Color.BLUE.name, 'BLUE')
|
|
26
|
+
ae(_Color.BLUE.value, 3)
|
|
27
|
+
|
|
28
|
+
# ── 2. Member singletons (identity) ──────────────────────────────────────────
|
|
29
|
+
# STATUS: ✓ WORKS
|
|
30
|
+
|
|
31
|
+
ok(_Color.RED is _Color.RED)
|
|
32
|
+
ok(_Color.RED is not _Color.GREEN)
|
|
33
|
+
ok(_Color.GREEN is not _Color.BLUE)
|
|
34
|
+
|
|
35
|
+
# ── 3. repr and str ──────────────────────────────────────────────────────────
|
|
36
|
+
# STATUS: ✓ WORKS
|
|
37
|
+
# Note: repr() for integer values uses the numeric representation.
|
|
38
|
+
# The class name in repr/str reflects the actual JS constructor name.
|
|
39
|
+
|
|
40
|
+
ae(repr(_Color.RED), '<_Color.RED: 1>')
|
|
41
|
+
ae(repr(_Color.GREEN), '<_Color.GREEN: 2>')
|
|
42
|
+
ae(str(_Color.RED), '_Color.RED')
|
|
43
|
+
ae(str(_Color.BLUE), '_Color.BLUE')
|
|
44
|
+
|
|
45
|
+
# ── 4. isinstance checks ─────────────────────────────────────────────────────
|
|
46
|
+
# STATUS: ✓ WORKS
|
|
47
|
+
|
|
48
|
+
ok(isinstance(_Color.RED, _Color))
|
|
49
|
+
ok(isinstance(_Color.RED, Enum))
|
|
50
|
+
ok(isinstance(_Color.GREEN, _Color))
|
|
51
|
+
ok(not isinstance(1, _Color))
|
|
52
|
+
ok(not isinstance(1, Enum))
|
|
53
|
+
|
|
54
|
+
# ── 5. Iteration via list() ───────────────────────────────────────────────────
|
|
55
|
+
# STATUS: ✓ WORKS
|
|
56
|
+
|
|
57
|
+
members = list(_Color)
|
|
58
|
+
ae(len(members), 3)
|
|
59
|
+
ae(members[0].name, 'RED')
|
|
60
|
+
ae(members[1].name, 'GREEN')
|
|
61
|
+
ae(members[2].name, 'BLUE')
|
|
62
|
+
ae(members[0].value, 1)
|
|
63
|
+
ae(members[1].value, 2)
|
|
64
|
+
ae(members[2].value, 3)
|
|
65
|
+
|
|
66
|
+
# ── 6. for loop iteration ─────────────────────────────────────────────────────
|
|
67
|
+
# STATUS: ✓ WORKS
|
|
68
|
+
|
|
69
|
+
_found_names = []
|
|
70
|
+
for _m in _Color:
|
|
71
|
+
_found_names.push(_m.name)
|
|
72
|
+
ade(_found_names, ['RED', 'GREEN', 'BLUE'])
|
|
73
|
+
|
|
74
|
+
_found_values = []
|
|
75
|
+
for _m in _Color:
|
|
76
|
+
_found_values.push(_m.value)
|
|
77
|
+
ade(_found_values, [1, 2, 3])
|
|
78
|
+
|
|
79
|
+
# ── 7. _member_names_ registry ───────────────────────────────────────────────
|
|
80
|
+
# STATUS: ✓ WORKS
|
|
81
|
+
|
|
82
|
+
ade(_Color._member_names_, ['RED', 'GREEN', 'BLUE'])
|
|
83
|
+
|
|
84
|
+
# ── 8. String-valued enum ─────────────────────────────────────────────────────
|
|
85
|
+
# STATUS: ✓ WORKS
|
|
86
|
+
|
|
87
|
+
class _Direction(Enum):
|
|
88
|
+
NORTH = 'north'
|
|
89
|
+
SOUTH = 'south'
|
|
90
|
+
EAST = 'east'
|
|
91
|
+
WEST = 'west'
|
|
92
|
+
|
|
93
|
+
ae(_Direction.NORTH.name, 'NORTH')
|
|
94
|
+
ae(_Direction.NORTH.value, 'north')
|
|
95
|
+
ae(_Direction.SOUTH.value, 'south')
|
|
96
|
+
# RapydScript repr() wraps strings in double quotes (JS convention)
|
|
97
|
+
ae(repr(_Direction.NORTH), '<_Direction.NORTH: "north">')
|
|
98
|
+
ae(str(_Direction.EAST), '_Direction.EAST')
|
|
99
|
+
ae(len(list(_Direction)), 4)
|
|
100
|
+
|
|
101
|
+
# ── 9. Enum subclass with extra methods ───────────────────────────────────────
|
|
102
|
+
# STATUS: ✓ WORKS
|
|
103
|
+
|
|
104
|
+
class _Status(Enum):
|
|
105
|
+
ACTIVE = 1
|
|
106
|
+
INACTIVE = 0
|
|
107
|
+
|
|
108
|
+
def is_active(self):
|
|
109
|
+
return this is _Status.ACTIVE
|
|
110
|
+
|
|
111
|
+
ok(_Status.ACTIVE.is_active())
|
|
112
|
+
ok(not _Status.INACTIVE.is_active())
|
|
113
|
+
|
|
114
|
+
# ── 10. Multiple Enum subclasses are independent ──────────────────────────────
|
|
115
|
+
# STATUS: ✓ WORKS
|
|
116
|
+
|
|
117
|
+
ae(len(list(_Color)), 3)
|
|
118
|
+
ae(len(list(_Direction)), 4)
|
|
119
|
+
ae(len(list(_Status)), 2)
|
|
120
|
+
ok(_Color._member_names_ is not _Direction._member_names_)
|
|
121
|
+
ok(_Color.RED is not _Status.ACTIVE) # different classes, different members
|
|
122
|
+
|
|
123
|
+
# ── 11. Members are not confused with plain class instances ───────────────────
|
|
124
|
+
# STATUS: ✓ WORKS
|
|
125
|
+
|
|
126
|
+
ok(isinstance(_Color.RED, _Color))
|
|
127
|
+
ok(_Color.RED is _Color.RED) # same object every time
|
|
128
|
+
|
|
129
|
+
# ── 12. Values from _members_by_value_ lookup ────────────────────────────────
|
|
130
|
+
# STATUS: ✓ WORKS
|
|
131
|
+
|
|
132
|
+
ae(_Color._members_by_value_[1].name, 'RED')
|
|
133
|
+
ae(_Color._members_by_value_[2].name, 'GREEN')
|
|
134
|
+
ae(_Color._members_by_value_[3].name, 'BLUE')
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# globals: assrt
|
|
3
|
+
|
|
4
|
+
ae = assrt.equal
|
|
5
|
+
ade = assrt.deepEqual
|
|
6
|
+
ok = assrt.ok
|
|
7
|
+
|
|
8
|
+
# ── eval — basic expression evaluation ────────────────────────────────────────
|
|
9
|
+
|
|
10
|
+
ae(eval("1 + 2"), 3)
|
|
11
|
+
ae(eval("10 * 5"), 50)
|
|
12
|
+
ae(eval("100 - 37"), 63)
|
|
13
|
+
ae(eval('"hello" + " world"'), "hello world")
|
|
14
|
+
ae(eval("Math.pow(2, 8)"), 256)
|
|
15
|
+
ae(eval("True"), True)
|
|
16
|
+
ae(eval("None"), None)
|
|
17
|
+
|
|
18
|
+
# ── eval — with explicit globals dict ─────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
ae(eval("x + y", {"x": 10, "y": 5}), 15)
|
|
21
|
+
ae(eval("a * b", {"a": 3, "b": 4}), 12)
|
|
22
|
+
ae(eval("n * n", {"n": 7}), 49)
|
|
23
|
+
|
|
24
|
+
# ── eval — locals override globals ────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
ae(eval("x", {"x": 1}, {"x": 99}), 99)
|
|
27
|
+
ae(eval("x + y", {"x": 10, "y": 20}, {"y": 1}), 11)
|
|
28
|
+
|
|
29
|
+
# ── exec — always returns None ────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
ae(exec("1 + 2"), None)
|
|
32
|
+
ae(exec("_ignored = 42"), None)
|
|
33
|
+
|
|
34
|
+
# ── exec — side effects via mutable objects in globals ────────────────────────
|
|
35
|
+
|
|
36
|
+
log = []
|
|
37
|
+
exec("log.push('hello')", {"log": log})
|
|
38
|
+
ae(log[0], "hello")
|
|
39
|
+
|
|
40
|
+
exec("log.push(1 + 2)", {"log": log})
|
|
41
|
+
ae(log[1], 3)
|
|
42
|
+
|
|
43
|
+
# exec with a function in globals
|
|
44
|
+
out = []
|
|
45
|
+
def _adder(a, b): out.push(a + b);
|
|
46
|
+
exec("fn(10, 7)", {"fn": _adder, "out": out})
|
|
47
|
+
ae(out[0], 17)
|
|
48
|
+
|
|
49
|
+
# exec returns None even when globals/locals provided
|
|
50
|
+
ae(exec("1 + 1", {"x": 5}), None)
|
|
51
|
+
|
|
52
|
+
# ── exec — JS loop, mutation visible in caller ────────────────────────────────
|
|
53
|
+
|
|
54
|
+
nums = []
|
|
55
|
+
exec("for _i in range(4):\n nums.append(_i * _i)", {"nums": nums})
|
|
56
|
+
ade(nums, [0, 1, 4, 9])
|
package/test/format.pyj
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD
|
|
3
|
+
# Tests for __format__ dunder dispatch in format(), str.format(), and f-strings
|
|
4
|
+
# globals: assrt
|
|
5
|
+
|
|
6
|
+
ae = assrt.equal
|
|
7
|
+
|
|
8
|
+
# ── Basic custom __format__ ───────────────────────────────────────────────────
|
|
9
|
+
|
|
10
|
+
class Currency:
|
|
11
|
+
def __init__(self, amount):
|
|
12
|
+
self.amount = amount
|
|
13
|
+
def __str__(self):
|
|
14
|
+
return str(self.amount)
|
|
15
|
+
def __format__(self, spec):
|
|
16
|
+
if spec == 'usd':
|
|
17
|
+
return '$' + str(self.amount)
|
|
18
|
+
if spec == 'eur':
|
|
19
|
+
return '€' + str(self.amount)
|
|
20
|
+
return format(self.amount, spec)
|
|
21
|
+
|
|
22
|
+
c = Currency(42)
|
|
23
|
+
|
|
24
|
+
# format() builtin dispatches to __format__
|
|
25
|
+
ae(format(c, 'usd'), '$42')
|
|
26
|
+
ae(format(c, 'eur'), '€42')
|
|
27
|
+
ae(format(c, '.2f'), '42.00')
|
|
28
|
+
|
|
29
|
+
# str.format() dispatches to __format__
|
|
30
|
+
ae(str.format('{:usd}', c), '$42')
|
|
31
|
+
ae(str.format('{:eur}', c), '€42')
|
|
32
|
+
ae(str.format('{:.2f}', c), '42.00')
|
|
33
|
+
|
|
34
|
+
# f-strings dispatch to __format__
|
|
35
|
+
ae(f'{c:usd}', '$42')
|
|
36
|
+
ae(f'{c:eur}', '€42')
|
|
37
|
+
ae(f'{c:.2f}', '42.00')
|
|
38
|
+
|
|
39
|
+
# ── format() with empty spec calls __format__('') ────────────────────────────
|
|
40
|
+
|
|
41
|
+
class Tagged:
|
|
42
|
+
def __init__(self, v):
|
|
43
|
+
self.v = v
|
|
44
|
+
def __str__(self):
|
|
45
|
+
return 'str:' + str(self.v)
|
|
46
|
+
def __format__(self, spec):
|
|
47
|
+
if not spec:
|
|
48
|
+
return 'fmt:' + str(self.v)
|
|
49
|
+
return 'fmt:' + format(self.v, spec)
|
|
50
|
+
|
|
51
|
+
t = Tagged(7)
|
|
52
|
+
ae(format(t), 'fmt:7')
|
|
53
|
+
ae(format(t, ''), 'fmt:7')
|
|
54
|
+
ae(str.format('{}', t), 'fmt:7')
|
|
55
|
+
ae(f'{t}', 'fmt:7')
|
|
56
|
+
|
|
57
|
+
# ── Default __format__ delegates to __str__ when spec is empty ────────────────
|
|
58
|
+
|
|
59
|
+
class Simple:
|
|
60
|
+
def __str__(self):
|
|
61
|
+
return 'simple!'
|
|
62
|
+
|
|
63
|
+
s = Simple()
|
|
64
|
+
ae(format(s), 'simple!')
|
|
65
|
+
ae(format(s, ''), 'simple!')
|
|
66
|
+
ae(str.format('{}', s), 'simple!')
|
|
67
|
+
ae(f'{s}', 'simple!')
|
|
68
|
+
|
|
69
|
+
# ── Default __format__ raises TypeError for non-empty spec ───────────────────
|
|
70
|
+
|
|
71
|
+
class Plain:
|
|
72
|
+
def __str__(self):
|
|
73
|
+
return 'plain'
|
|
74
|
+
|
|
75
|
+
p = Plain()
|
|
76
|
+
raised = False
|
|
77
|
+
try:
|
|
78
|
+
format(p, 'd')
|
|
79
|
+
except TypeError:
|
|
80
|
+
raised = True
|
|
81
|
+
ae(raised, True)
|
|
82
|
+
|
|
83
|
+
raised = False
|
|
84
|
+
try:
|
|
85
|
+
str.format('{:d}', p)
|
|
86
|
+
except TypeError:
|
|
87
|
+
raised = True
|
|
88
|
+
ae(raised, True)
|
|
89
|
+
|
|
90
|
+
# ── Inheritance: subclass inherits parent __format__ ─────────────────────────
|
|
91
|
+
|
|
92
|
+
class Base:
|
|
93
|
+
def __format__(self, spec):
|
|
94
|
+
return 'base:' + spec
|
|
95
|
+
|
|
96
|
+
class Child(Base):
|
|
97
|
+
pass
|
|
98
|
+
|
|
99
|
+
child = Child()
|
|
100
|
+
ae(format(child, 'x'), 'base:x')
|
|
101
|
+
ae(str.format('{:x}', child), 'base:x')
|
|
102
|
+
ae(f'{child:x}', 'base:x')
|
|
103
|
+
|
|
104
|
+
# ── Subclass can override __format__ ─────────────────────────────────────────
|
|
105
|
+
|
|
106
|
+
class Override(Base):
|
|
107
|
+
def __format__(self, spec):
|
|
108
|
+
return 'override:' + spec
|
|
109
|
+
|
|
110
|
+
o = Override()
|
|
111
|
+
ae(format(o, 'y'), 'override:y')
|
|
112
|
+
ae(str.format('{:y}', o), 'override:y')
|
|
113
|
+
|
|
114
|
+
# ── !r and !s transformers bypass __format__ ─────────────────────────────────
|
|
115
|
+
|
|
116
|
+
class WithRepr:
|
|
117
|
+
def __repr__(self):
|
|
118
|
+
return 'MyRepr'
|
|
119
|
+
def __str__(self):
|
|
120
|
+
return 'MyStr'
|
|
121
|
+
def __format__(self, spec):
|
|
122
|
+
return 'MyFmt'
|
|
123
|
+
|
|
124
|
+
wr = WithRepr()
|
|
125
|
+
# With no transformer, __format__ is called
|
|
126
|
+
ae(str.format('{}', wr), 'MyFmt')
|
|
127
|
+
# !s applies str(), result is a string (no __format__)
|
|
128
|
+
ae(str.format('{!s}', wr), 'MyStr')
|
|
129
|
+
# !r applies repr()
|
|
130
|
+
ae(str.format('{!r}', wr), 'MyRepr')
|
|
131
|
+
|
|
132
|
+
# ── Multiple fields with __format__ ──────────────────────────────────────────
|
|
133
|
+
|
|
134
|
+
class Qty:
|
|
135
|
+
def __init__(self, n):
|
|
136
|
+
self.n = n
|
|
137
|
+
def __str__(self):
|
|
138
|
+
return str(self.n)
|
|
139
|
+
def __format__(self, spec):
|
|
140
|
+
if spec == 'w':
|
|
141
|
+
words = ['zero', 'one', 'two', 'three', 'four', 'five']
|
|
142
|
+
return words[self.n] if self.n < len(words) else str(self.n)
|
|
143
|
+
return format(self.n, spec)
|
|
144
|
+
|
|
145
|
+
a, b = Qty(1), Qty(2)
|
|
146
|
+
ae(str.format('{:w} and {:w}', a, b), 'one and two')
|
|
147
|
+
ae(f'{a:w} + {b:w}', 'one + two')
|
|
148
|
+
ae(str.format('{0:d} + {1:d}', a, b), '1 + 2')
|
package/test/functions.pyj
CHANGED
|
@@ -1,151 +1,151 @@
|
|
|
1
|
-
# globals: assrt
|
|
2
|
-
|
|
3
|
-
def nothing():
|
|
4
|
-
pass
|
|
5
|
-
assrt.equal(nothing(), undefined)
|
|
6
|
-
|
|
7
|
-
add = def(a, b):
|
|
8
|
-
return a+b
|
|
9
|
-
def sub(a, b):
|
|
10
|
-
return a-b
|
|
11
|
-
|
|
12
|
-
mul = None
|
|
13
|
-
(def():
|
|
14
|
-
nonlocal mul
|
|
15
|
-
mul = def(a, b):
|
|
16
|
-
return a*b
|
|
17
|
-
|
|
18
|
-
div = def(a, b): # noqa:unused-local
|
|
19
|
-
return a/b
|
|
20
|
-
)()
|
|
21
|
-
|
|
22
|
-
assrt.equal(add(1,2), 3)
|
|
23
|
-
assrt.equal(sub(1,2), -1)
|
|
24
|
-
assrt.equal(mul(2,2), 4)
|
|
25
|
-
# for some reason input to throws must be of type block, hence the 'def' wrapper
|
|
26
|
-
assrt.throws(
|
|
27
|
-
def():
|
|
28
|
-
div(6,3) # noqa: undef
|
|
29
|
-
,
|
|
30
|
-
/div is not defined/
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
arr = [8,4]
|
|
34
|
-
assrt.equal(add(*arr), 12)
|
|
35
|
-
assrt.ok(Array.isArray(arr))
|
|
36
|
-
|
|
37
|
-
def sum(*args):
|
|
38
|
-
ttl = 0
|
|
39
|
-
for i in args:
|
|
40
|
-
ttl += i
|
|
41
|
-
return ttl
|
|
42
|
-
assrt.equal(sum(1,2,3), 6)
|
|
43
|
-
assrt.equal(sum(1,*[2,3]), 6)
|
|
44
|
-
|
|
45
|
-
num = 4
|
|
46
|
-
def():
|
|
47
|
-
nonlocal num
|
|
48
|
-
num = 5
|
|
49
|
-
.call(this)
|
|
50
|
-
|
|
51
|
-
assrt.equal(num, 5)
|
|
52
|
-
|
|
53
|
-
x = "foo"
|
|
54
|
-
y = 5
|
|
55
|
-
def swap(x, y):
|
|
56
|
-
return y, x
|
|
57
|
-
x, y = swap(x, y)
|
|
58
|
-
assrt.equal(x, 5)
|
|
59
|
-
assrt.equal(y, "foo")
|
|
60
|
-
|
|
61
|
-
count = 0
|
|
62
|
-
f, r = (def():
|
|
63
|
-
def fake_increment():
|
|
64
|
-
count += 1
|
|
65
|
-
def real_increment():
|
|
66
|
-
nonlocal count
|
|
67
|
-
count += 1
|
|
68
|
-
return fake_increment, real_increment
|
|
69
|
-
).call(this)
|
|
70
|
-
|
|
71
|
-
f()
|
|
72
|
-
assrt.equal(count, 0)
|
|
73
|
-
r()
|
|
74
|
-
assrt.equal(count, 1)
|
|
75
|
-
|
|
76
|
-
st = "this is a string"
|
|
77
|
-
assrt.equal(jstype(st), v"typeof st")
|
|
78
|
-
|
|
79
|
-
# testing inlined functions
|
|
80
|
-
inlined = [
|
|
81
|
-
def(x): return x+1;, def(x): return x+2;,
|
|
82
|
-
def(x): return x+3
|
|
83
|
-
,
|
|
84
|
-
def(x): return x+4
|
|
85
|
-
]
|
|
86
|
-
assrt.equal(inlined[0](1), 2)
|
|
87
|
-
assrt.equal(inlined[1](1), 3)
|
|
88
|
-
assrt.equal(inlined[2](1), 4)
|
|
89
|
-
assrt.equal(inlined[3](1), 5)
|
|
90
|
-
|
|
91
|
-
# decorators
|
|
92
|
-
def makebold(fn):
|
|
93
|
-
def wrapped(arg):
|
|
94
|
-
return "<b>" + fn(arg) + "</b>"
|
|
95
|
-
return wrapped
|
|
96
|
-
|
|
97
|
-
def makeitalic(fn):
|
|
98
|
-
def wrapped(arg):
|
|
99
|
-
return "<i>" + fn(arg) + "</i>"
|
|
100
|
-
return wrapped
|
|
101
|
-
|
|
102
|
-
@makebold
|
|
103
|
-
@makeitalic
|
|
104
|
-
def hello(something):
|
|
105
|
-
return "hello " + something
|
|
106
|
-
|
|
107
|
-
assrt.equal(hello("world"), "<b><i>hello world</i></b>")
|
|
108
|
-
assrt.equal(hello.__module__, '__main__')
|
|
109
|
-
assrt.equal(hello.__argnames__.length, 1)
|
|
110
|
-
assrt.equal(hello.__argnames__[0], 'arg')
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def simple_wrapper(f):
|
|
114
|
-
f.test_attr = 'test'
|
|
115
|
-
return f
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
@simple_wrapper
|
|
119
|
-
def fw(x):
|
|
120
|
-
pass
|
|
121
|
-
|
|
122
|
-
assrt.equal(fw.__module__, '__main__')
|
|
123
|
-
assrt.equal(fw.__argnames__.length, 1)
|
|
124
|
-
assrt.equal(fw.__argnames__[0], 'x')
|
|
125
|
-
# just because something is a reserved keyword in RapydScript, doesn't mean other libraries won't attempt to use it
|
|
126
|
-
# let's make sure we parse that correctly
|
|
127
|
-
five = {}
|
|
128
|
-
v"five.is = function(n) { return 5 == n };"
|
|
129
|
-
assrt.ok(five.is(5))
|
|
130
|
-
|
|
131
|
-
# function assignment via conditional
|
|
132
|
-
foo = (def(): return 5;) if 0 else (def(): return 6;)
|
|
133
|
-
bar = (def(): return 5;) if 0 < 1 else (def(): return 6;)
|
|
134
|
-
baz = (def():
|
|
135
|
-
return 5
|
|
136
|
-
) if 1 else (def():
|
|
137
|
-
return 6
|
|
138
|
-
)
|
|
139
|
-
assrt.equal(foo(), 6)
|
|
140
|
-
assrt.equal(bar(), 5)
|
|
141
|
-
assrt.equal(baz(), 5)
|
|
142
|
-
|
|
143
|
-
def trailing_comma(a, b,):
|
|
144
|
-
return a + b
|
|
145
|
-
assrt.equal(trailing_comma(1, 2), 3)
|
|
146
|
-
assrt.equal(trailing_comma(1, 2,), 3)
|
|
147
|
-
|
|
148
|
-
def return_string_with_newline():
|
|
149
|
-
return '''a
|
|
150
|
-
b'''
|
|
151
|
-
assrt.equal(return_string_with_newline(), 'a\nb')
|
|
1
|
+
# globals: assrt
|
|
2
|
+
|
|
3
|
+
def nothing():
|
|
4
|
+
pass
|
|
5
|
+
assrt.equal(nothing(), undefined)
|
|
6
|
+
|
|
7
|
+
add = def(a, b):
|
|
8
|
+
return a+b
|
|
9
|
+
def sub(a, b):
|
|
10
|
+
return a-b
|
|
11
|
+
|
|
12
|
+
mul = None
|
|
13
|
+
(def():
|
|
14
|
+
nonlocal mul
|
|
15
|
+
mul = def(a, b):
|
|
16
|
+
return a*b
|
|
17
|
+
|
|
18
|
+
div = def(a, b): # noqa:unused-local
|
|
19
|
+
return a/b
|
|
20
|
+
)()
|
|
21
|
+
|
|
22
|
+
assrt.equal(add(1,2), 3)
|
|
23
|
+
assrt.equal(sub(1,2), -1)
|
|
24
|
+
assrt.equal(mul(2,2), 4)
|
|
25
|
+
# for some reason input to throws must be of type block, hence the 'def' wrapper
|
|
26
|
+
assrt.throws(
|
|
27
|
+
def():
|
|
28
|
+
div(6,3) # noqa: undef
|
|
29
|
+
,
|
|
30
|
+
/div is not defined/
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
arr = [8,4]
|
|
34
|
+
assrt.equal(add(*arr), 12)
|
|
35
|
+
assrt.ok(Array.isArray(arr))
|
|
36
|
+
|
|
37
|
+
def sum(*args):
|
|
38
|
+
ttl = 0
|
|
39
|
+
for i in args:
|
|
40
|
+
ttl += i
|
|
41
|
+
return ttl
|
|
42
|
+
assrt.equal(sum(1,2,3), 6)
|
|
43
|
+
assrt.equal(sum(1,*[2,3]), 6)
|
|
44
|
+
|
|
45
|
+
num = 4
|
|
46
|
+
def():
|
|
47
|
+
nonlocal num
|
|
48
|
+
num = 5
|
|
49
|
+
.call(this)
|
|
50
|
+
|
|
51
|
+
assrt.equal(num, 5)
|
|
52
|
+
|
|
53
|
+
x = "foo"
|
|
54
|
+
y = 5
|
|
55
|
+
def swap(x, y):
|
|
56
|
+
return y, x
|
|
57
|
+
x, y = swap(x, y)
|
|
58
|
+
assrt.equal(x, 5)
|
|
59
|
+
assrt.equal(y, "foo")
|
|
60
|
+
|
|
61
|
+
count = 0
|
|
62
|
+
f, r = (def():
|
|
63
|
+
def fake_increment():
|
|
64
|
+
count += 1
|
|
65
|
+
def real_increment():
|
|
66
|
+
nonlocal count
|
|
67
|
+
count += 1
|
|
68
|
+
return fake_increment, real_increment
|
|
69
|
+
).call(this)
|
|
70
|
+
|
|
71
|
+
f()
|
|
72
|
+
assrt.equal(count, 0)
|
|
73
|
+
r()
|
|
74
|
+
assrt.equal(count, 1)
|
|
75
|
+
|
|
76
|
+
st = "this is a string"
|
|
77
|
+
assrt.equal(jstype(st), v"typeof st")
|
|
78
|
+
|
|
79
|
+
# testing inlined functions
|
|
80
|
+
inlined = [
|
|
81
|
+
def(x): return x+1;, def(x): return x+2;,
|
|
82
|
+
def(x): return x+3
|
|
83
|
+
,
|
|
84
|
+
def(x): return x+4
|
|
85
|
+
]
|
|
86
|
+
assrt.equal(inlined[0](1), 2)
|
|
87
|
+
assrt.equal(inlined[1](1), 3)
|
|
88
|
+
assrt.equal(inlined[2](1), 4)
|
|
89
|
+
assrt.equal(inlined[3](1), 5)
|
|
90
|
+
|
|
91
|
+
# decorators
|
|
92
|
+
def makebold(fn):
|
|
93
|
+
def wrapped(arg):
|
|
94
|
+
return "<b>" + fn(arg) + "</b>"
|
|
95
|
+
return wrapped
|
|
96
|
+
|
|
97
|
+
def makeitalic(fn):
|
|
98
|
+
def wrapped(arg):
|
|
99
|
+
return "<i>" + fn(arg) + "</i>"
|
|
100
|
+
return wrapped
|
|
101
|
+
|
|
102
|
+
@makebold
|
|
103
|
+
@makeitalic
|
|
104
|
+
def hello(something):
|
|
105
|
+
return "hello " + something
|
|
106
|
+
|
|
107
|
+
assrt.equal(hello("world"), "<b><i>hello world</i></b>")
|
|
108
|
+
assrt.equal(hello.__module__, '__main__')
|
|
109
|
+
assrt.equal(hello.__argnames__.length, 1)
|
|
110
|
+
assrt.equal(hello.__argnames__[0], 'arg')
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def simple_wrapper(f):
|
|
114
|
+
f.test_attr = 'test'
|
|
115
|
+
return f
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@simple_wrapper
|
|
119
|
+
def fw(x):
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
assrt.equal(fw.__module__, '__main__')
|
|
123
|
+
assrt.equal(fw.__argnames__.length, 1)
|
|
124
|
+
assrt.equal(fw.__argnames__[0], 'x')
|
|
125
|
+
# just because something is a reserved keyword in RapydScript, doesn't mean other libraries won't attempt to use it
|
|
126
|
+
# let's make sure we parse that correctly
|
|
127
|
+
five = {}
|
|
128
|
+
v"five.is = function(n) { return 5 == n };"
|
|
129
|
+
assrt.ok(five.is(5))
|
|
130
|
+
|
|
131
|
+
# function assignment via conditional
|
|
132
|
+
foo = (def(): return 5;) if 0 else (def(): return 6;)
|
|
133
|
+
bar = (def(): return 5;) if 0 < 1 else (def(): return 6;)
|
|
134
|
+
baz = (def():
|
|
135
|
+
return 5
|
|
136
|
+
) if 1 else (def():
|
|
137
|
+
return 6
|
|
138
|
+
)
|
|
139
|
+
assrt.equal(foo(), 6)
|
|
140
|
+
assrt.equal(bar(), 5)
|
|
141
|
+
assrt.equal(baz(), 5)
|
|
142
|
+
|
|
143
|
+
def trailing_comma(a, b,):
|
|
144
|
+
return a + b
|
|
145
|
+
assrt.equal(trailing_comma(1, 2), 3)
|
|
146
|
+
assrt.equal(trailing_comma(1, 2,), 3)
|
|
147
|
+
|
|
148
|
+
def return_string_with_newline():
|
|
149
|
+
return '''a
|
|
150
|
+
b'''
|
|
151
|
+
assrt.equal(return_string_with_newline(), 'a\nb')
|