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.
Files changed (132) 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 +18 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/README.md +715 -169
  8. package/TODO.md +9 -2
  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 +36 -27
  15. package/package.json +1 -1
  16. package/publish.py +37 -37
  17. package/release/baselib-plain-pretty.js +2358 -168
  18. package/release/baselib-plain-ugly.js +73 -3
  19. package/release/compiler.js +6282 -3092
  20. package/release/signatures.json +31 -30
  21. package/session.vim +4 -4
  22. package/setup.cfg +2 -2
  23. package/src/ast.pyj +1 -0
  24. package/src/baselib-builtins.pyj +340 -2
  25. package/src/baselib-bytes.pyj +664 -0
  26. package/src/baselib-errors.pyj +1 -1
  27. package/src/baselib-internal.pyj +267 -60
  28. package/src/baselib-itertools.pyj +110 -97
  29. package/src/baselib-str.pyj +22 -4
  30. package/src/compiler.pyj +36 -36
  31. package/src/errors.pyj +30 -30
  32. package/src/lib/abc.pyj +317 -0
  33. package/src/lib/aes.pyj +646 -646
  34. package/src/lib/copy.pyj +120 -120
  35. package/src/lib/dataclasses.pyj +532 -0
  36. package/src/lib/elementmaker.pyj +83 -83
  37. package/src/lib/encodings.pyj +126 -126
  38. package/src/lib/enum.pyj +125 -0
  39. package/src/lib/gettext.pyj +569 -569
  40. package/src/lib/itertools.pyj +580 -580
  41. package/src/lib/math.pyj +193 -193
  42. package/src/lib/operator.pyj +11 -11
  43. package/src/lib/pythonize.pyj +20 -20
  44. package/src/lib/random.pyj +118 -118
  45. package/src/lib/re.pyj +504 -470
  46. package/src/lib/react.pyj +74 -74
  47. package/src/lib/traceback.pyj +63 -63
  48. package/src/lib/typing.pyj +577 -0
  49. package/src/lib/uuid.pyj +77 -77
  50. package/src/monaco-language-service/builtins.js +14 -4
  51. package/src/monaco-language-service/diagnostics.js +19 -20
  52. package/src/monaco-language-service/dts.js +550 -550
  53. package/src/output/classes.pyj +62 -26
  54. package/src/output/comments.pyj +45 -45
  55. package/src/output/exceptions.pyj +201 -201
  56. package/src/output/functions.pyj +78 -5
  57. package/src/output/jsx.pyj +164 -164
  58. package/src/output/loops.pyj +5 -2
  59. package/src/output/operators.pyj +100 -34
  60. package/src/output/treeshake.pyj +182 -182
  61. package/src/output/utils.pyj +72 -72
  62. package/src/parse.pyj +80 -16
  63. package/src/string_interpolation.pyj +72 -72
  64. package/src/tokenizer.pyj +9 -4
  65. package/src/unicode_aliases.pyj +576 -576
  66. package/src/utils.pyj +192 -192
  67. package/test/_import_one.pyj +37 -37
  68. package/test/_import_two/__init__.pyj +11 -11
  69. package/test/_import_two/level2/deep.pyj +4 -4
  70. package/test/_import_two/other.pyj +6 -6
  71. package/test/_import_two/sub.pyj +13 -13
  72. package/test/abc.pyj +291 -0
  73. package/test/aes_vectors.pyj +421 -421
  74. package/test/annotations.pyj +80 -80
  75. package/test/arithmetic_nostrict.pyj +88 -0
  76. package/test/arithmetic_types.pyj +169 -0
  77. package/test/baselib.pyj +91 -0
  78. package/test/bytes.pyj +467 -0
  79. package/test/classes.pyj +1 -0
  80. package/test/comparison_ops.pyj +173 -0
  81. package/test/dataclasses.pyj +253 -0
  82. package/test/decorators.pyj +77 -77
  83. package/test/docstrings.pyj +39 -39
  84. package/test/elementmaker_test.pyj +45 -45
  85. package/test/enum.pyj +134 -0
  86. package/test/eval_exec.pyj +56 -0
  87. package/test/format.pyj +148 -0
  88. package/test/functions.pyj +151 -151
  89. package/test/generators.pyj +41 -41
  90. package/test/generic.pyj +370 -370
  91. package/test/imports.pyj +72 -72
  92. package/test/internationalization.pyj +73 -73
  93. package/test/lint.pyj +164 -164
  94. package/test/loops.pyj +85 -85
  95. package/test/numpy.pyj +734 -734
  96. package/test/object.pyj +64 -0
  97. package/test/omit_function_metadata.pyj +20 -20
  98. package/test/python_compat.pyj +17 -15
  99. package/test/python_features.pyj +70 -15
  100. package/test/regexp.pyj +83 -55
  101. package/test/repl.pyj +121 -121
  102. package/test/scoped_flags.pyj +76 -76
  103. package/test/tuples.pyj +96 -0
  104. package/test/typing.pyj +469 -0
  105. package/test/unit/index.js +116 -7
  106. package/test/unit/language-service-dts.js +543 -543
  107. package/test/unit/language-service-hover.js +455 -455
  108. package/test/unit/language-service.js +84 -0
  109. package/test/unit/web-repl.js +804 -1
  110. package/test/vars_locals_globals.pyj +94 -0
  111. package/tools/cli.js +558 -547
  112. package/tools/compile.js +224 -219
  113. package/tools/completer.js +131 -131
  114. package/tools/embedded_compiler.js +262 -251
  115. package/tools/gettext.js +185 -185
  116. package/tools/ini.js +65 -65
  117. package/tools/lint.js +16 -19
  118. package/tools/msgfmt.js +187 -187
  119. package/tools/repl.js +223 -223
  120. package/tools/test.js +118 -118
  121. package/tools/utils.js +128 -128
  122. package/tools/web_repl.js +95 -95
  123. package/try +41 -41
  124. package/web-repl/env.js +196 -196
  125. package/web-repl/index.html +163 -163
  126. package/web-repl/main.js +252 -252
  127. package/web-repl/prism.css +139 -139
  128. package/web-repl/prism.js +113 -113
  129. package/web-repl/rapydscript.js +224 -224
  130. package/web-repl/sha1.js +25 -25
  131. package/PYTHON_DIFFERENCES_REPORT.md +0 -291
  132. package/PYTHON_FEATURE_COVERAGE.md +0 -200
package/src/lib/uuid.pyj CHANGED
@@ -1,77 +1,77 @@
1
- # vim:fileencoding=utf-8
2
- # License: BSD Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
3
- # globals: crypto
4
- from __python__ import hash_literals
5
-
6
- from encodings import hexlify, urlsafe_b64decode, urlsafe_b64encode
7
-
8
- RFC_4122 = 1
9
-
10
- if jstype(crypto) is 'object' and crypto.getRandomValues:
11
- random_bytes = def (num):
12
- ans = Uint8Array(num or 16)
13
- crypto.getRandomValues(ans)
14
- return ans
15
- else:
16
- random_bytes = def (num):
17
- ans = Uint8Array(num or 16)
18
- for i in range(ans.length):
19
- ans[i] = Math.floor(Math.random() * 256)
20
- return ans
21
-
22
-
23
- def uuid4_bytes():
24
- data = random_bytes()
25
- data[6] = 0b01000000 | (data[6] & 0b1111)
26
- data[8] = (((data[8] >> 4) & 0b11 | 0b1000) << 4) | (data[8] & 0b1111)
27
- return data
28
-
29
-
30
- def as_str():
31
- h = this.hex
32
- return h[:8] + '-' + h[8:12] + '-' + h[12:16] + '-' + h[16:20] + '-' + h[20:]
33
-
34
-
35
- def uuid4():
36
- b = uuid4_bytes()
37
- return {
38
- 'hex': hexlify(b),
39
- 'bytes': b,
40
- 'variant': RFC_4122,
41
- 'version': 4,
42
- '__str__': as_str,
43
- 'toString': as_str,
44
- }
45
-
46
-
47
- def num_to_string(numbers, alphabet, pad_to_length):
48
- ans = v'[]'
49
- alphabet_len = alphabet.length
50
- numbers = Array.prototype.slice.call(numbers)
51
- for v'var i = 0; i < numbers.length - 1; i++':
52
- x = divmod(numbers[i], alphabet_len)
53
- numbers[i] = x[0]
54
- numbers[i+1] += x[1]
55
- for v'var i = 0; i < numbers.length; i++':
56
- number = numbers[i]
57
- while number:
58
- x = divmod(number, alphabet_len)
59
- number = x[0]
60
- ans.push(alphabet[x[1]])
61
- if pad_to_length and pad_to_length > ans.length:
62
- ans.push(alphabet[0].repeat(pad_to_length - ans.length))
63
- return ans.join('')
64
-
65
-
66
- def short_uuid():
67
- # A totally random uuid encoded using only URL and filename safe characters
68
- return urlsafe_b64encode(random_bytes(), '')
69
-
70
-
71
- def short_uuid4():
72
- # A uuid4 encoded using only URL and filename safe characters
73
- return urlsafe_b64encode(uuid4_bytes(), '')
74
-
75
-
76
- def decode_short_uuid(val):
77
- return urlsafe_b64decode(val + '==')
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
3
+ # globals: crypto
4
+ from __python__ import hash_literals
5
+
6
+ from encodings import hexlify, urlsafe_b64decode, urlsafe_b64encode
7
+
8
+ RFC_4122 = 1
9
+
10
+ if jstype(crypto) is 'object' and crypto.getRandomValues:
11
+ random_bytes = def (num):
12
+ ans = Uint8Array(num or 16)
13
+ crypto.getRandomValues(ans)
14
+ return ans
15
+ else:
16
+ random_bytes = def (num):
17
+ ans = Uint8Array(num or 16)
18
+ for i in range(ans.length):
19
+ ans[i] = Math.floor(Math.random() * 256)
20
+ return ans
21
+
22
+
23
+ def uuid4_bytes():
24
+ data = random_bytes()
25
+ data[6] = 0b01000000 | (data[6] & 0b1111)
26
+ data[8] = (((data[8] >> 4) & 0b11 | 0b1000) << 4) | (data[8] & 0b1111)
27
+ return data
28
+
29
+
30
+ def as_str():
31
+ h = this.hex
32
+ return h[:8] + '-' + h[8:12] + '-' + h[12:16] + '-' + h[16:20] + '-' + h[20:]
33
+
34
+
35
+ def uuid4():
36
+ b = uuid4_bytes()
37
+ return {
38
+ 'hex': hexlify(b),
39
+ 'bytes': b,
40
+ 'variant': RFC_4122,
41
+ 'version': 4,
42
+ '__str__': as_str,
43
+ 'toString': as_str,
44
+ }
45
+
46
+
47
+ def num_to_string(numbers, alphabet, pad_to_length):
48
+ ans = v'[]'
49
+ alphabet_len = alphabet.length
50
+ numbers = Array.prototype.slice.call(numbers)
51
+ for v'var i = 0; i < numbers.length - 1; i++':
52
+ x = divmod(numbers[i], alphabet_len)
53
+ numbers[i] = x[0]
54
+ numbers[i+1] += x[1]
55
+ for v'var i = 0; i < numbers.length; i++':
56
+ number = numbers[i]
57
+ while number:
58
+ x = divmod(number, alphabet_len)
59
+ number = x[0]
60
+ ans.push(alphabet[x[1]])
61
+ if pad_to_length and pad_to_length > ans.length:
62
+ ans.push(alphabet[0].repeat(pad_to_length - ans.length))
63
+ return ans.join('')
64
+
65
+
66
+ def short_uuid():
67
+ # A totally random uuid encoded using only URL and filename safe characters
68
+ return urlsafe_b64encode(random_bytes(), '')
69
+
70
+
71
+ def short_uuid4():
72
+ # A uuid4 encoded using only URL and filename safe characters
73
+ return urlsafe_b64encode(uuid4_bytes(), '')
74
+
75
+
76
+ def decode_short_uuid(val):
77
+ return urlsafe_b64decode(val + '==')
@@ -79,6 +79,11 @@ const STUBS = [
79
79
  return_type: 'str',
80
80
  doc: 'Return the string representing a character at Unicode code point i.' }),
81
81
 
82
+ new BuiltinInfo({ name: 'complex', kind: 'class',
83
+ params: [p('real_or_string', { optional: true }), p('imag', { type: 'number', optional: true })],
84
+ return_type: 'complex',
85
+ doc: 'Create a complex number.\n\nForms:\n- `complex()` → `0j`\n- `complex(x)` → `x+0j` (from int/float/bool/complex), or parse Python complex string\n- `complex(real, imag)` → `real + imag*j`\n\nLiteral syntax: `4j` is equivalent to `complex(0, 4)`, and `3+4j` creates a complex number via addition.\n\nAttributes:\n- `.real` — the real part (float)\n- `.imag` — the imaginary part (float)\n\nMethods:\n- `.conjugate()` — return the complex conjugate `(real - imag*j)`\n\nSupports: `+`, `-`, `*`, `/`, `**`, unary `-`/`+`, `abs()`, `bool()`, `==`, `repr()`, `str()`.\n\nExample:\n\n c = complex(3, 4)\n c.real # 3\n c.imag # 4\n abs(c) # 5.0\n c.conjugate() # (3-4j)\n c * complex(1, 2) # (-5+10j)\n 3 + 4j # (3+4j) — literal syntax' }),
86
+
82
87
  new BuiltinInfo({ name: 'dict', kind: 'class',
83
88
  params: [p('**kwargs', { rest: true })],
84
89
  return_type: 'dict',
@@ -112,7 +117,7 @@ const STUBS = [
112
117
  new BuiltinInfo({ name: 'float', kind: 'class',
113
118
  params: [p('x', { optional: true })],
114
119
  return_type: 'float',
115
- doc: 'Return a floating-point number from x.' }),
120
+ doc: 'Return a floating-point number from x.\n\nInstance method:\n- `.is_integer()` — return `True` if the float has no fractional part (i.e. is a whole number), `False` otherwise. `Infinity` and `NaN` return `False`.\n\nExample:\n\n (1.0).is_integer() # True\n (1.5).is_integer() # False\n (1e10).is_integer() # True' }),
116
121
 
117
122
  new BuiltinInfo({ name: 'getattr',
118
123
  params: [p('obj'), p('name', { type: 'str' }), p('default', { optional: true })],
@@ -142,7 +147,7 @@ const STUBS = [
142
147
  new BuiltinInfo({ name: 'int', kind: 'class',
143
148
  params: [p('x', { optional: true }), p('base', { type: 'int', optional: true })],
144
149
  return_type: 'int',
145
- doc: 'Return an integer from x, optionally in the given base.' }),
150
+ doc: 'Return an integer from x, optionally in the given base.\n\nInstance method:\n- `.bit_length()` — return the number of bits needed to represent the integer in binary, excluding the sign and leading zeros. Equivalent to `floor(log2(abs(n))) + 1` for nonzero `n`; returns `0` for `0`.\n\nExample:\n\n (0).bit_length() # 0\n (1).bit_length() # 1\n (255).bit_length() # 8\n (256).bit_length() # 9\n (-5).bit_length() # 3 (sign ignored)' }),
146
151
 
147
152
  new BuiltinInfo({ name: 'isinstance',
148
153
  params: [p('obj'), p('classinfo')],
@@ -174,6 +179,11 @@ const STUBS = [
174
179
  return_type: 'any',
175
180
  doc: 'Retrieve the next item from an iterator. If the iterator is exhausted, return default; if default is not given, raise StopIteration.' }),
176
181
 
182
+ new BuiltinInfo({ name: 'object', kind: 'class',
183
+ params: [],
184
+ return_type: 'object',
185
+ doc: 'Create a new featureless base object instance.\n\nThe base class of all Python classes. Calling `object()` with no arguments returns a new, unique instance useful as a sentinel value:\n\n MISSING = object() # unique sentinel\n if value is MISSING:\n ...\n\nKey behaviours:\n- Each call returns a distinct instance (`object() is not object()`).\n- `isinstance(x, object)` returns `True` for any `object()` instance (and subclasses).\n- `class Foo(object):` works as an explicit base class.\n- `repr()` returns `\'<object object at 0x…>\'`.\n- `hash()` returns a stable identity hash.\n\nNote: unlike Python, you *can* add arbitrary attributes to an `object()` instance in RapydScript (JS objects are open by default).' }),
186
+
177
187
  new BuiltinInfo({ name: 'map',
178
188
  params: [p('function'), p('iterable'), p('*iterables', { rest: true })],
179
189
  return_type: 'iterable',
@@ -265,9 +275,9 @@ const STUBS = [
265
275
  doc: 'Return the type of an object.' }),
266
276
 
267
277
  new BuiltinInfo({ name: 'zip',
268
- params: [p('*iterables', { rest: true })],
278
+ params: [p('*iterables', { rest: true }), p('strict', { optional: true })],
269
279
  return_type: 'iterable',
270
- doc: 'Return an iterator of tuples, where each tuple groups the i-th element from each iterable.' }),
280
+ doc: 'Return an iterator of tuples, where each tuple groups the i-th element from each iterable. With strict=True, raises ValueError if the iterables have different lengths.' }),
271
281
 
272
282
  // ── RapydScript-specific ──────────────────────────────────────────────
273
283
  new BuiltinInfo({ name: 'jstype',
@@ -26,9 +26,9 @@ const MESSAGES = {
26
26
  // with the compiler from src/lib/). These should never produce 'Unknown module'
27
27
  // errors regardless of what virtualFiles or stdlibFiles are configured.
28
28
  export const STDLIB_MODULES = [
29
- 'aes', 'collections', 'copy', 'elementmaker', 'encodings', 'functools',
30
- 'gettext', 'itertools', 'math', 'numpy', 'operator', 'pythonize',
31
- 'random', 're', 'react', 'traceback', 'uuid',
29
+ 'abc', 'aes', 'collections', 'copy', 'dataclasses', 'elementmaker', 'encodings', 'enum',
30
+ 'functools', 'gettext', 'itertools', 'math', 'numpy', 'operator',
31
+ 'pythonize', 'random', 're', 'react', 'traceback', 'typing', 'uuid',
32
32
  // Pseudo-modules for language feature flags (from __python__ import ...)
33
33
  '__python__', '__builtins__',
34
34
  ];
@@ -39,16 +39,16 @@ STDLIB_MODULES.forEach(m => { _STDLIB_MODULE_SET[m] = true; });
39
39
  // Symbols always available in RapydScript (from tools/lint.js BUILTINS list).
40
40
  export const BASE_BUILTINS = (
41
41
  'this self window document chr ord iterator_symbol print len range dir' +
42
- ' eval undefined arguments abs max min enumerate pow callable reversed sum' +
42
+ ' eval exec undefined arguments abs max min enumerate pow callable reversed sum' +
43
43
  ' getattr isFinite setattr hasattr parseInt parseFloat options_object' +
44
44
  ' isNaN JSON Math list set list_wrap ρσ_modules require bool int bin' +
45
- ' float iter Error EvalError set_wrap frozenset RangeError ReferenceError SyntaxError' +
45
+ ' float complex iter Error EvalError set_wrap frozenset RangeError ReferenceError SyntaxError' +
46
46
  ' str TypeError URIError Exception AssertionError IndexError AttributeError KeyError' +
47
47
  ' ValueError ZeroDivisionError ImportError ModuleNotFoundError StopIteration map hex filter zip dict dict_wrap UnicodeDecodeError HTMLCollection' +
48
48
  ' NodeList alert console Node Symbol NamedNodeMap ρσ_eslice ρσ_delslice Number' +
49
49
  ' Boolean encodeURIComponent decodeURIComponent setTimeout setInterval' +
50
50
  ' setImmediate clearTimeout clearInterval clearImmediate requestAnimationFrame' +
51
- ' id repr sorted __name__ equals get_module ρσ_str jstype divmod NaN super Ellipsis slice all any next __import__ ρσ_new ρσ_object_new hash ρσ_object_setattr ρσ_object_getattr ρσ_object_delattr ExceptionGroup BaseExceptionGroup tuple'
51
+ ' id repr sorted __name__ equals get_module ρσ_str jstype divmod NaN super Ellipsis slice all any next __import__ ρσ_new ρσ_object_new hash ρσ_object_setattr ρσ_object_getattr ρσ_object_delattr ExceptionGroup BaseExceptionGroup tuple bytes bytearray format object vars locals globals'
52
52
  ).split(' ');
53
53
 
54
54
  // ---------------------------------------------------------------------------
@@ -423,24 +423,23 @@ function Linter(RS, toplevel, code, builtins, knownModules) {
423
423
 
424
424
  this.handle_for_in = function() {
425
425
  const node = this.current_node;
426
+ const add_loop_var = (cnode) => {
427
+ if (cnode instanceof RS.AST_Seq) {
428
+ cnode.to_array().forEach(add_loop_var);
429
+ } else if (cnode instanceof RS.AST_Array) {
430
+ cnode.elements.forEach(add_loop_var);
431
+ } else if (cnode instanceof RS.AST_SymbolRef) {
432
+ this.current_node = cnode;
433
+ cnode.lint_visited = true;
434
+ this.add_binding(cnode.name).is_loop = true;
435
+ this.current_node = node;
436
+ }
437
+ };
426
438
  if (node.init instanceof RS.AST_SymbolRef) {
427
439
  this.add_binding(node.init.name).is_loop = true;
428
440
  node.init.lint_visited = true;
429
441
  } else if (node.init instanceof RS.AST_Array) {
430
- node.init.elements.forEach(cnode => {
431
- if (cnode instanceof RS.AST_Seq) cnode = cnode.to_array();
432
- if (cnode instanceof RS.AST_SymbolRef) cnode = [cnode];
433
- if (Array.isArray(cnode)) {
434
- cnode.forEach(elem => {
435
- if (elem instanceof RS.AST_SymbolRef) {
436
- this.current_node = elem;
437
- elem.lint_visited = true;
438
- this.add_binding(elem.name).is_loop = true;
439
- this.current_node = node;
440
- }
441
- });
442
- }
443
- });
442
+ node.init.elements.forEach(add_loop_var);
444
443
  }
445
444
  };
446
445