rapydscript-ns 0.9.0 → 0.9.2

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.
Files changed (100) hide show
  1. package/.agignore +1 -1
  2. package/.github/workflows/ci.yml +38 -38
  3. package/=template.pyj +5 -5
  4. package/CHANGELOG.md +10 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/README.md +7 -6
  8. package/TODO.md +116 -1
  9. package/add-toc-to-readme +2 -2
  10. package/bin/export +75 -75
  11. package/bin/rapydscript +70 -70
  12. package/bin/web-repl-export +102 -102
  13. package/build +2 -2
  14. package/language-service/index.js +9 -9
  15. package/language-service/language-service.d.ts +1 -1
  16. package/package.json +6 -2
  17. package/publish.py +37 -37
  18. package/release/compiler.js +246 -231
  19. package/release/signatures.json +23 -23
  20. package/session.vim +4 -4
  21. package/setup.cfg +2 -2
  22. package/src/compiler.pyj +36 -36
  23. package/src/errors.pyj +30 -30
  24. package/src/lib/aes.pyj +646 -646
  25. package/src/lib/contextlib.pyj +379 -0
  26. package/src/lib/copy.pyj +120 -120
  27. package/src/lib/datetime.pyj +712 -0
  28. package/src/lib/elementmaker.pyj +83 -83
  29. package/src/lib/encodings.pyj +126 -126
  30. package/src/lib/gettext.pyj +569 -569
  31. package/src/lib/io.pyj +500 -0
  32. package/src/lib/itertools.pyj +580 -580
  33. package/src/lib/json.pyj +227 -0
  34. package/src/lib/math.pyj +193 -193
  35. package/src/lib/operator.pyj +11 -11
  36. package/src/lib/pythonize.pyj +20 -20
  37. package/src/lib/random.pyj +118 -118
  38. package/src/lib/react.pyj +74 -74
  39. package/src/lib/traceback.pyj +63 -63
  40. package/src/lib/uuid.pyj +77 -77
  41. package/src/monaco-language-service/diagnostics.js +4 -4
  42. package/src/monaco-language-service/dts.js +550 -550
  43. package/src/monaco-language-service/index.js +2 -2
  44. package/src/output/comments.pyj +45 -45
  45. package/src/output/exceptions.pyj +201 -201
  46. package/src/output/jsx.pyj +164 -164
  47. package/src/output/loops.pyj +9 -0
  48. package/src/output/treeshake.pyj +182 -182
  49. package/src/output/utils.pyj +72 -72
  50. package/src/string_interpolation.pyj +72 -72
  51. package/src/tokenizer.pyj +1 -1
  52. package/src/unicode_aliases.pyj +576 -576
  53. package/src/utils.pyj +192 -192
  54. package/test/_import_one.pyj +37 -37
  55. package/test/_import_two/__init__.pyj +11 -11
  56. package/test/_import_two/level2/deep.pyj +4 -4
  57. package/test/_import_two/other.pyj +6 -6
  58. package/test/_import_two/sub.pyj +13 -13
  59. package/test/aes_vectors.pyj +421 -421
  60. package/test/annotations.pyj +80 -80
  61. package/test/contextlib.pyj +362 -0
  62. package/test/datetime.pyj +500 -0
  63. package/test/debugger_stmt.pyj +41 -0
  64. package/test/decorators.pyj +77 -77
  65. package/test/docstrings.pyj +39 -39
  66. package/test/elementmaker_test.pyj +45 -45
  67. package/test/functions.pyj +151 -151
  68. package/test/generators.pyj +41 -41
  69. package/test/generic.pyj +370 -370
  70. package/test/imports.pyj +72 -72
  71. package/test/internationalization.pyj +73 -73
  72. package/test/io.pyj +316 -0
  73. package/test/json.pyj +196 -0
  74. package/test/lint.pyj +164 -164
  75. package/test/loops.pyj +85 -85
  76. package/test/numpy.pyj +734 -734
  77. package/test/omit_function_metadata.pyj +20 -20
  78. package/test/repl.pyj +121 -121
  79. package/test/scoped_flags.pyj +76 -76
  80. package/test/unit/index.js +66 -0
  81. package/test/unit/language-service-dts.js +543 -543
  82. package/test/unit/language-service-hover.js +455 -455
  83. package/test/unit/language-service.js +1 -1
  84. package/test/unit/web-repl.js +533 -0
  85. package/tools/compiler.d.ts +367 -0
  86. package/tools/completer.js +131 -131
  87. package/tools/gettext.js +185 -185
  88. package/tools/ini.js +65 -65
  89. package/tools/msgfmt.js +187 -187
  90. package/tools/repl.js +223 -223
  91. package/tools/test.js +118 -118
  92. package/tools/utils.js +128 -128
  93. package/tools/web_repl.js +95 -95
  94. package/try +41 -41
  95. package/web-repl/env.js +196 -196
  96. package/web-repl/index.html +163 -163
  97. package/web-repl/prism.css +139 -139
  98. package/web-repl/prism.js +113 -113
  99. package/web-repl/rapydscript.js +224 -224
  100. package/web-repl/sha1.js +25 -25
@@ -1,80 +1,80 @@
1
- def add(a: int, b: float):
2
- return a + b
3
-
4
- assrt.ok(add.__annotations__)
5
- assrt.equal(add.__annotations__['a'], int)
6
- assrt.equal(add.__annotations__['b'], float)
7
- assrt.equal(add.__annotations__['return'], undefined)
8
-
9
- def sum(ls: list) -> int:
10
- pass
11
-
12
- assrt.ok(not (sum.__annotations__ == undefined))
13
- assrt.deepEqual(sum.__annotations__, {
14
- 'ls': list,
15
- 'return': int
16
- })
17
-
18
- def optional(a:int=10):
19
- return a
20
-
21
- assrt.ok(not (optional.__annotations__ == undefined))
22
- assrt.equal(optional.__annotations__.a, int)
23
- assrt.equal(optional.__defaults__.a, 10)
24
-
25
- def otherexpr(a:3+4) -> [1, 2]:
26
- pass
27
-
28
- assrt.ok(not (otherexpr.__annotations__ == undefined))
29
- assrt.equal(otherexpr.__annotations__['a'], 7)
30
- assrt.deepEqual(otherexpr.__annotations__['return'], [1, 2])
31
-
32
- def basic(x:float):
33
- pass
34
-
35
- assrt.deepEqual(basic.__annotations__, {
36
- 'x': float
37
- })
38
-
39
- def kwstarargs(*args:list, **kwargs:dict) -> int:
40
- pass
41
-
42
- assrt.equal(kwstarargs.__annotations__['return'], int)
43
-
44
- def nothing():
45
- pass
46
-
47
- assrt.ok(nothing.__annotations__ == undefined)
48
- assrt.throws(def():
49
- nothing.__annotations__['return']
50
- )
51
-
52
- test = def(x: int):
53
- pass
54
-
55
- assrt.deepEqual(test.__annotations__, {
56
- 'x': int
57
- })
58
-
59
- anonreturn = def() -> 'test':
60
- pass
61
-
62
- assrt.equal(anonreturn.__annotations__['return'], 'test')
63
-
64
- assrt.equal(def asexpr(a: int):
65
- a
66
- .__annotations__['a'], int)
67
-
68
- assrt.deepEqual(def(a: int) -> float:
69
- a + 10.0
70
- .__annotations__, {
71
- 'a': int,
72
- 'return': float
73
- })
74
-
75
- class A:
76
-
77
- def f(self, a : int, b: 'x') -> float:
78
- pass
79
-
80
- assrt.deepEqual(A.prototype.f.__annotations__, {'a':int, 'b':'x', 'return': float})
1
+ def add(a: int, b: float):
2
+ return a + b
3
+
4
+ assrt.ok(add.__annotations__)
5
+ assrt.equal(add.__annotations__['a'], int)
6
+ assrt.equal(add.__annotations__['b'], float)
7
+ assrt.equal(add.__annotations__['return'], undefined)
8
+
9
+ def sum(ls: list) -> int:
10
+ pass
11
+
12
+ assrt.ok(not (sum.__annotations__ == undefined))
13
+ assrt.deepEqual(sum.__annotations__, {
14
+ 'ls': list,
15
+ 'return': int
16
+ })
17
+
18
+ def optional(a:int=10):
19
+ return a
20
+
21
+ assrt.ok(not (optional.__annotations__ == undefined))
22
+ assrt.equal(optional.__annotations__.a, int)
23
+ assrt.equal(optional.__defaults__.a, 10)
24
+
25
+ def otherexpr(a:3+4) -> [1, 2]:
26
+ pass
27
+
28
+ assrt.ok(not (otherexpr.__annotations__ == undefined))
29
+ assrt.equal(otherexpr.__annotations__['a'], 7)
30
+ assrt.deepEqual(otherexpr.__annotations__['return'], [1, 2])
31
+
32
+ def basic(x:float):
33
+ pass
34
+
35
+ assrt.deepEqual(basic.__annotations__, {
36
+ 'x': float
37
+ })
38
+
39
+ def kwstarargs(*args:list, **kwargs:dict) -> int:
40
+ pass
41
+
42
+ assrt.equal(kwstarargs.__annotations__['return'], int)
43
+
44
+ def nothing():
45
+ pass
46
+
47
+ assrt.ok(nothing.__annotations__ == undefined)
48
+ assrt.throws(def():
49
+ nothing.__annotations__['return']
50
+ )
51
+
52
+ test = def(x: int):
53
+ pass
54
+
55
+ assrt.deepEqual(test.__annotations__, {
56
+ 'x': int
57
+ })
58
+
59
+ anonreturn = def() -> 'test':
60
+ pass
61
+
62
+ assrt.equal(anonreturn.__annotations__['return'], 'test')
63
+
64
+ assrt.equal(def asexpr(a: int):
65
+ a
66
+ .__annotations__['a'], int)
67
+
68
+ assrt.deepEqual(def(a: int) -> float:
69
+ a + 10.0
70
+ .__annotations__, {
71
+ 'a': int,
72
+ 'return': float
73
+ })
74
+
75
+ class A:
76
+
77
+ def f(self, a : int, b: 'x') -> float:
78
+ pass
79
+
80
+ assrt.deepEqual(A.prototype.f.__annotations__, {'a':int, 'b':'x', 'return': float})
@@ -0,0 +1,362 @@
1
+ # globals: assrt
2
+ # vim:fileencoding=utf-8
3
+ #
4
+ # contextlib.pyj — tests for the contextlib standard library module.
5
+
6
+ ae = assrt.equal
7
+ ade = assrt.deepEqual
8
+ ok = assrt.ok
9
+
10
+ from contextlib import (
11
+ AbstractContextManager, contextmanager, closing,
12
+ nullcontext, suppress, ExitStack
13
+ )
14
+
15
+
16
+ # ── 1. AbstractContextManager ─────────────────────────────────────────────────
17
+
18
+ class _SimpleCM(AbstractContextManager):
19
+ def __init__(self):
20
+ self.exited = False
21
+ self.exc_type = None
22
+ def __exit__(self, exc_type=None, exc_val=None, exc_tb=None):
23
+ self.exited = True
24
+ self.exc_type = exc_type
25
+ return False
26
+
27
+ _cm = _SimpleCM()
28
+ with _cm as val:
29
+ ae(val, _cm) # __enter__ returns self
30
+
31
+ ok(_cm.exited)
32
+ ae(_cm.exc_type, None) # no exception
33
+
34
+ # AbstractContextManager with default __exit__ (no-op)
35
+ class _DefaultExit(AbstractContextManager):
36
+ pass
37
+
38
+ _de = _DefaultExit()
39
+ with _de as v:
40
+ ae(v, _de)
41
+
42
+ # ── 2. closing ────────────────────────────────────────────────────────────────
43
+
44
+ class _Closeable:
45
+ def __init__(self):
46
+ self.closed = False
47
+ def close(self):
48
+ self.closed = True
49
+
50
+ _obj = _Closeable()
51
+ with closing(_obj) as c:
52
+ ae(c, _obj)
53
+ ok(not c.closed)
54
+ ok(_obj.closed) # close() called on exit
55
+
56
+ # close() is called even when an exception occurs
57
+ _obj2 = _Closeable()
58
+ _raised = False
59
+ try:
60
+ with closing(_obj2):
61
+ raise ValueError('oops')
62
+ except ValueError:
63
+ _raised = True
64
+ ok(_raised)
65
+ ok(_obj2.closed) # still closed despite exception
66
+
67
+ # ── 3. nullcontext ────────────────────────────────────────────────────────────
68
+
69
+ with nullcontext() as v:
70
+ ae(v, None)
71
+
72
+ with nullcontext(42) as v:
73
+ ae(v, 42)
74
+
75
+ with nullcontext('hello') as s:
76
+ ae(s, 'hello')
77
+
78
+ # ── 4. suppress ───────────────────────────────────────────────────────────────
79
+
80
+ # Suppress a matching exception — execution continues after the with block
81
+ _reached = False
82
+ with suppress(ValueError):
83
+ raise ValueError('ignored')
84
+ _reached = True
85
+ ok(_reached)
86
+
87
+ # Suppress one of several listed types
88
+ _reached2 = False
89
+ with suppress(KeyError, ValueError):
90
+ raise KeyError('ignored')
91
+ _reached2 = True
92
+ ok(_reached2)
93
+
94
+ # Non-matching exception propagates
95
+ _non_match = False
96
+ try:
97
+ with suppress(KeyError):
98
+ raise ValueError('not suppressed')
99
+ except ValueError:
100
+ _non_match = True
101
+ ok(_non_match)
102
+
103
+ # No exception — block runs normally
104
+ _no_exc = False
105
+ with suppress(ValueError):
106
+ _no_exc = True
107
+ ok(_no_exc)
108
+
109
+ # suppress returns self from __enter__
110
+ with suppress(TypeError) as ctx:
111
+ ok(ctx is not None)
112
+
113
+ # ── 5. contextmanager ─────────────────────────────────────────────────────────
114
+
115
+ # Basic: yield value becomes the `as` target
116
+ @contextmanager
117
+ def _cm_basic(val):
118
+ yield val
119
+
120
+ with _cm_basic(99) as v:
121
+ ae(v, 99)
122
+
123
+ # setup/teardown order
124
+ _log = []
125
+
126
+ @contextmanager
127
+ def _cm_log(name):
128
+ _log.push('enter:' + name)
129
+ try:
130
+ yield name
131
+ finally:
132
+ _log.push('exit:' + name)
133
+
134
+ with _cm_log('x') as v:
135
+ ae(v, 'x')
136
+ _log.push('body')
137
+
138
+ ade(_log, ['enter:x', 'body', 'exit:x'])
139
+
140
+ # exception in the body is thrown into the generator and re-raised if not caught
141
+ _teardown_ran = False
142
+ _body_exc_caught = False
143
+
144
+ @contextmanager
145
+ def _cm_reraise():
146
+ global _teardown_ran
147
+ try:
148
+ yield 'val'
149
+ finally:
150
+ _teardown_ran = True
151
+
152
+ try:
153
+ with _cm_reraise():
154
+ raise ValueError('oops')
155
+ except ValueError:
156
+ _body_exc_caught = True
157
+ ok(_teardown_ran)
158
+ ok(_body_exc_caught)
159
+
160
+ # generator catches the exception and suppresses it (returns True from __exit__)
161
+ _suppress_log = []
162
+
163
+ @contextmanager
164
+ def _cm_suppress_exc():
165
+ try:
166
+ yield
167
+ except ValueError:
168
+ _suppress_log.push('caught ValueError')
169
+
170
+ _after_suppress = False
171
+ with _cm_suppress_exc():
172
+ raise ValueError('caught by generator')
173
+ _after_suppress = True
174
+ ok(_after_suppress)
175
+ ade(_suppress_log, ['caught ValueError'])
176
+
177
+ # contextmanager with setup / cleanup and no yield value
178
+ _setup_done = False
179
+ _cleanup_done = False
180
+
181
+ @contextmanager
182
+ def _cm_setup_cleanup():
183
+ global _setup_done, _cleanup_done
184
+ _setup_done = True
185
+ yield
186
+ _cleanup_done = True
187
+
188
+ with _cm_setup_cleanup():
189
+ ok(_setup_done)
190
+
191
+ ok(_cleanup_done)
192
+
193
+ # nested contextmanagers
194
+ _nest_log = []
195
+
196
+ @contextmanager
197
+ def _cm_nest(label):
198
+ _nest_log.push('in:' + label)
199
+ yield label
200
+ _nest_log.push('out:' + label)
201
+
202
+ with _cm_nest('a') as a:
203
+ with _cm_nest('b') as b:
204
+ ae(a, 'a')
205
+ ae(b, 'b')
206
+
207
+ ade(_nest_log, ['in:a', 'in:b', 'out:b', 'out:a'])
208
+
209
+ # ── 6. ExitStack ──────────────────────────────────────────────────────────────
210
+
211
+ # Basic usage as a context manager
212
+ _es_entered = False
213
+ _es_exited = False
214
+
215
+ class _TrackedCM:
216
+ def __init__(self, name):
217
+ self.name = name
218
+ self.entered = False
219
+ self.exited = False
220
+ def __enter__(self):
221
+ self.entered = True
222
+ return self.name
223
+ def __exit__(self, exc_type=None, exc_val=None, exc_tb=None):
224
+ self.exited = True
225
+ return False
226
+
227
+ _cm_a = _TrackedCM('a')
228
+ _cm_b = _TrackedCM('b')
229
+
230
+ with ExitStack() as stack:
231
+ va = stack.enter_context(_cm_a)
232
+ vb = stack.enter_context(_cm_b)
233
+ ae(va, 'a')
234
+ ae(vb, 'b')
235
+ ok(_cm_a.entered)
236
+ ok(_cm_b.entered)
237
+
238
+ ok(_cm_a.exited)
239
+ ok(_cm_b.exited)
240
+
241
+ # LIFO exit order
242
+ _exit_order = []
243
+
244
+ class _OrderedCM:
245
+ def __init__(self, label):
246
+ self.label = label
247
+ def __enter__(self):
248
+ return self
249
+ def __exit__(self, exc_type=None, exc_val=None, exc_tb=None):
250
+ _exit_order.push(self.label)
251
+ return False
252
+
253
+ with ExitStack() as stack:
254
+ stack.enter_context(_OrderedCM('first'))
255
+ stack.enter_context(_OrderedCM('second'))
256
+ stack.enter_context(_OrderedCM('third'))
257
+
258
+ ade(_exit_order, ['third', 'second', 'first'])
259
+
260
+ # callback() is called on exit
261
+ _cb_called = False
262
+ _cb_arg = None
263
+
264
+ def _my_callback(x):
265
+ global _cb_called, _cb_arg
266
+ _cb_called = True
267
+ _cb_arg = x
268
+
269
+ with ExitStack() as stack:
270
+ stack.callback(_my_callback, 'hello')
271
+
272
+ ok(_cb_called)
273
+ ae(_cb_arg, 'hello')
274
+
275
+ # push() with a raw callable
276
+ _push_called = False
277
+
278
+ def _raw_exit(exc_type=None, exc_val=None, exc_tb=None):
279
+ global _push_called
280
+ _push_called = True
281
+ return False
282
+
283
+ with ExitStack() as stack:
284
+ stack.push(_raw_exit)
285
+
286
+ ok(_push_called)
287
+
288
+ # push() with a context manager object (does not call __enter__)
289
+ _push_cm = _TrackedCM('pushed')
290
+ with ExitStack() as stack:
291
+ stack.push(_push_cm)
292
+
293
+ ok(not _push_cm.entered) # __enter__ was NOT called by push()
294
+ ok(_push_cm.exited) # __exit__ WAS called
295
+
296
+ # exception in the with block is passed to registered __exit__ methods
297
+ _exc_saw_exc = False
298
+
299
+ class _SeeExc:
300
+ def __enter__(self): return self
301
+ def __exit__(self, exc_type=None, exc_val=None, exc_tb=None):
302
+ global _exc_saw_exc
303
+ if exc_type is not None:
304
+ _exc_saw_exc = True
305
+ return False # don't suppress
306
+
307
+ _exc_propagated = False
308
+ try:
309
+ with ExitStack() as stack:
310
+ stack.enter_context(_SeeExc())
311
+ raise ValueError('test')
312
+ except ValueError:
313
+ _exc_propagated = True
314
+
315
+ ok(_exc_saw_exc)
316
+ ok(_exc_propagated)
317
+
318
+ # a cleanup that suppresses the exception
319
+ _suppressed_by_stack = False
320
+
321
+ class _SuppressCM:
322
+ def __enter__(self): return self
323
+ def __exit__(self, exc_type=None, exc_val=None, exc_tb=None):
324
+ return True # suppress whatever is active
325
+
326
+ _after_stack_suppress = False
327
+ with ExitStack() as stack:
328
+ stack.enter_context(_SuppressCM())
329
+ raise KeyError('suppressed by stack')
330
+ _after_stack_suppress = True
331
+ ok(_after_stack_suppress)
332
+
333
+ # close() works outside of a `with` block
334
+ _close_log = []
335
+
336
+ class _CloseTracked:
337
+ def __enter__(self): return self
338
+ def __exit__(self, exc_type=None, exc_val=None, exc_tb=None):
339
+ _close_log.push('closed')
340
+ return False
341
+
342
+ stack2 = ExitStack()
343
+ stack2.enter_context(_CloseTracked())
344
+ stack2.close()
345
+ ade(_close_log, ['closed'])
346
+
347
+ # ── 7. Multiple context managers in one `with` statement ─────────────────────
348
+
349
+ # This exercises the compiler's multi-clause `with` support alongside our CMs
350
+ _multi_log = []
351
+
352
+ @contextmanager
353
+ def _cm_multi(label):
354
+ _multi_log.push('enter:' + label)
355
+ yield label
356
+ _multi_log.push('exit:' + label)
357
+
358
+ with _cm_multi('p') as p, _cm_multi('q') as q:
359
+ ae(p, 'p')
360
+ ae(q, 'q')
361
+
362
+ ade(_multi_log, ['enter:p', 'enter:q', 'exit:q', 'exit:p'])