rapydscript-ns 0.8.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) 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 +8 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/PYTHON_DIFFERENCES_REPORT.md +2 -2
  8. package/PYTHON_FEATURE_COVERAGE.md +13 -13
  9. package/README.md +670 -6
  10. package/TODO.md +5 -6
  11. package/add-toc-to-readme +2 -2
  12. package/bin/export +75 -75
  13. package/bin/rapydscript +70 -70
  14. package/bin/web-repl-export +102 -102
  15. package/build +2 -2
  16. package/language-service/index.js +155 -6
  17. package/package.json +1 -1
  18. package/publish.py +37 -37
  19. package/release/baselib-plain-pretty.js +2006 -229
  20. package/release/baselib-plain-ugly.js +70 -3
  21. package/release/compiler.js +11554 -3870
  22. package/release/signatures.json +31 -29
  23. package/session.vim +4 -4
  24. package/setup.cfg +2 -2
  25. package/src/ast.pyj +93 -1
  26. package/src/baselib-builtins.pyj +22 -1
  27. package/src/baselib-containers.pyj +99 -0
  28. package/src/baselib-errors.pyj +44 -0
  29. package/src/baselib-internal.pyj +94 -4
  30. package/src/baselib-itertools.pyj +97 -97
  31. package/src/baselib-str.pyj +24 -0
  32. package/src/compiler.pyj +36 -36
  33. package/src/errors.pyj +30 -30
  34. package/src/lib/aes.pyj +646 -646
  35. package/src/lib/copy.pyj +120 -0
  36. package/src/lib/elementmaker.pyj +83 -83
  37. package/src/lib/encodings.pyj +126 -126
  38. package/src/lib/gettext.pyj +569 -569
  39. package/src/lib/itertools.pyj +580 -580
  40. package/src/lib/math.pyj +193 -193
  41. package/src/lib/operator.pyj +11 -11
  42. package/src/lib/pythonize.pyj +20 -20
  43. package/src/lib/random.pyj +118 -118
  44. package/src/lib/re.pyj +470 -470
  45. package/src/lib/react.pyj +74 -0
  46. package/src/lib/traceback.pyj +63 -63
  47. package/src/lib/uuid.pyj +77 -77
  48. package/src/monaco-language-service/builtins.js +5 -0
  49. package/src/monaco-language-service/diagnostics.js +25 -3
  50. package/src/monaco-language-service/dts.js +550 -550
  51. package/src/output/classes.pyj +108 -8
  52. package/src/output/codegen.pyj +16 -2
  53. package/src/output/comments.pyj +45 -45
  54. package/src/output/exceptions.pyj +201 -105
  55. package/src/output/functions.pyj +9 -0
  56. package/src/output/jsx.pyj +164 -0
  57. package/src/output/literals.pyj +28 -2
  58. package/src/output/modules.pyj +1 -1
  59. package/src/output/operators.pyj +8 -2
  60. package/src/output/statements.pyj +2 -2
  61. package/src/output/stream.pyj +1 -0
  62. package/src/output/treeshake.pyj +182 -182
  63. package/src/output/utils.pyj +72 -72
  64. package/src/parse.pyj +417 -113
  65. package/src/string_interpolation.pyj +72 -72
  66. package/src/tokenizer.pyj +29 -0
  67. package/src/unicode_aliases.pyj +576 -576
  68. package/src/utils.pyj +192 -192
  69. package/test/_import_one.pyj +37 -37
  70. package/test/_import_two/__init__.pyj +11 -11
  71. package/test/_import_two/level2/deep.pyj +4 -4
  72. package/test/_import_two/other.pyj +6 -6
  73. package/test/_import_two/sub.pyj +13 -13
  74. package/test/aes_vectors.pyj +421 -421
  75. package/test/annotations.pyj +80 -80
  76. package/test/decorators.pyj +77 -77
  77. package/test/docstrings.pyj +39 -39
  78. package/test/elementmaker_test.pyj +45 -45
  79. package/test/functions.pyj +151 -151
  80. package/test/generators.pyj +41 -41
  81. package/test/generic.pyj +370 -370
  82. package/test/imports.pyj +72 -72
  83. package/test/internationalization.pyj +73 -73
  84. package/test/lint.pyj +164 -164
  85. package/test/loops.pyj +85 -85
  86. package/test/numpy.pyj +734 -734
  87. package/test/omit_function_metadata.pyj +20 -20
  88. package/test/python_features.pyj +19 -6
  89. package/test/regexp.pyj +55 -55
  90. package/test/repl.pyj +121 -121
  91. package/test/scoped_flags.pyj +76 -76
  92. package/test/unit/index.js +2177 -64
  93. package/test/unit/language-service-dts.js +543 -543
  94. package/test/unit/language-service-hover.js +455 -455
  95. package/test/unit/language-service.js +590 -4
  96. package/test/unit/web-repl.js +303 -0
  97. package/tools/cli.js +547 -547
  98. package/tools/compile.js +219 -219
  99. package/tools/completer.js +131 -131
  100. package/tools/embedded_compiler.js +251 -251
  101. package/tools/gettext.js +185 -185
  102. package/tools/ini.js +65 -65
  103. package/tools/msgfmt.js +187 -187
  104. package/tools/repl.js +223 -223
  105. package/tools/test.js +118 -118
  106. package/tools/utils.js +128 -128
  107. package/tools/web_repl.js +95 -95
  108. package/try +41 -41
  109. package/web-repl/env.js +196 -74
  110. package/web-repl/index.html +163 -163
  111. package/web-repl/main.js +252 -254
  112. package/web-repl/prism.css +139 -139
  113. package/web-repl/prism.js +113 -113
  114. package/web-repl/rapydscript.js +224 -102
  115. package/web-repl/sha1.js +25 -25
  116. package/hack_demo.pyj +0 -112
@@ -0,0 +1,74 @@
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD
3
+ # RapydScript bindings for React.
4
+ #
5
+ # Supported: all standard hooks (useState, useEffect, useContext, useReducer,
6
+ # useCallback, useMemo, useRef, useImperativeHandle, useLayoutEffect,
7
+ # useDebugValue, useId, useTransition, useDeferredValue), core classes
8
+ # (Component, PureComponent), special elements (Fragment, StrictMode,
9
+ # Suspense, Profiler), and utilities (createElement, cloneElement,
10
+ # createContext, createRef, forwardRef, isValidElement, memo, lazy).
11
+ #
12
+ # Requires React to be available as a global variable. Load it via a CDN
13
+ # <script> tag, a bundler global shim, or any other mechanism before your
14
+ # compiled script runs.
15
+ #
16
+ # Usage:
17
+ # from __python__ import jsx
18
+ # from react import useState, useEffect, useRef
19
+ #
20
+ # def Counter():
21
+ # count, setCount = useState(0)
22
+ # def handleClick():
23
+ # setCount(count + 1)
24
+ # return <button onClick={handleClick}>{count}</button>
25
+ #
26
+ # For class components extend React.Component directly (no import needed):
27
+ #
28
+ # class MyComponent(React.Component):
29
+ # def render(self):
30
+ # return <div>{self.props.title}</div>
31
+
32
+ # ── Hooks (React 16.8+) ───────────────────────────────────────────────────────
33
+
34
+ useState = React.useState
35
+ useEffect = React.useEffect
36
+ useContext = React.useContext
37
+ useReducer = React.useReducer
38
+ useCallback = React.useCallback
39
+ useMemo = React.useMemo
40
+ useRef = React.useRef
41
+ useImperativeHandle = React.useImperativeHandle
42
+ useLayoutEffect = React.useLayoutEffect
43
+ useDebugValue = React.useDebugValue
44
+
45
+ # ── Hooks (React 18+) ────────────────────────────────────────────────────────
46
+
47
+ useId = React.useId
48
+ useTransition = React.useTransition
49
+ useDeferredValue = React.useDeferredValue
50
+ useSyncExternalStore = React.useSyncExternalStore
51
+ useInsertionEffect = React.useInsertionEffect
52
+
53
+ # ── Core classes ─────────────────────────────────────────────────────────────
54
+
55
+ Component = React.Component
56
+ PureComponent = React.PureComponent
57
+
58
+ # ── Special elements ─────────────────────────────────────────────────────────
59
+
60
+ Fragment = React.Fragment
61
+ StrictMode = React.StrictMode
62
+ Suspense = React.Suspense
63
+ Profiler = React.Profiler
64
+
65
+ # ── Utilities ────────────────────────────────────────────────────────────────
66
+
67
+ createElement = React.createElement
68
+ cloneElement = React.cloneElement
69
+ createContext = React.createContext
70
+ createRef = React.createRef
71
+ forwardRef = React.forwardRef
72
+ isValidElement = React.isValidElement
73
+ memo = React.memo
74
+ lazy = React.lazy
@@ -1,63 +1,63 @@
1
- # vim:fileencoding=utf-8
2
- # License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
- # globals: ρσ_str, ρσ_last_exception
4
-
5
-
6
- def _get_internal_traceback(err):
7
- if isinstance(err, Exception) and err.stack:
8
- lines = ρσ_str.splitlines(err.stack)
9
- final_lines = v'[]'
10
- found_sentinel = False
11
- for i, line in enumerate(lines):
12
- sline = ρσ_str.strip(line)
13
- if i is 0:
14
- final_lines.push(line)
15
- continue
16
- if found_sentinel:
17
- final_lines.push(line)
18
- continue
19
- # These two conditions work on desktop Chrome and Firefox to identify the correct
20
- # line in the traceback.
21
- if sline.startsWith('at new ' + err.name) or sline.startsWith(err.name + '@'):
22
- found_sentinel = True
23
- return final_lines.join('\n')
24
- return err and err.stack
25
-
26
- def format_exception(exc, limit):
27
- if jstype(exc) is 'undefined':
28
- exc = ρσ_last_exception
29
- if not isinstance(exc, Error):
30
- if exc and exc.toString:
31
- return [exc.toString()]
32
- return []
33
- tb = _get_internal_traceback(exc)
34
- if tb:
35
- lines = ρσ_str.splitlines(tb)
36
- e = lines[0]
37
- lines = lines[1:]
38
- if limit:
39
- lines = lines[:limit+1] if limit > 0 else lines[limit:]
40
- lines.reverse()
41
- lines.push(e)
42
- lines.insert(0, 'Traceback (most recent call last):')
43
- return [l+'\n' for l in lines]
44
- return [exc.toString()]
45
-
46
- def format_exc(limit):
47
- return format_exception(ρσ_last_exception, limit).join('')
48
-
49
- def print_exc(limit):
50
- print(format_exc(limit))
51
-
52
- def format_stack(limit):
53
- stack = Error().stack
54
- if not stack:
55
- return []
56
- lines = str.splitlines(stack)[2:]
57
- lines.reverse()
58
- if limit:
59
- lines = lines[:limit+1] if limit > 0 else lines[limit:]
60
- return [l + '\n' for l in lines]
61
-
62
- def print_stack(limit):
63
- print(format_stack(limit).join(''))
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
+ # globals: ρσ_str, ρσ_last_exception
4
+
5
+
6
+ def _get_internal_traceback(err):
7
+ if isinstance(err, Exception) and err.stack:
8
+ lines = ρσ_str.splitlines(err.stack)
9
+ final_lines = v'[]'
10
+ found_sentinel = False
11
+ for i, line in enumerate(lines):
12
+ sline = ρσ_str.strip(line)
13
+ if i is 0:
14
+ final_lines.push(line)
15
+ continue
16
+ if found_sentinel:
17
+ final_lines.push(line)
18
+ continue
19
+ # These two conditions work on desktop Chrome and Firefox to identify the correct
20
+ # line in the traceback.
21
+ if sline.startsWith('at new ' + err.name) or sline.startsWith(err.name + '@'):
22
+ found_sentinel = True
23
+ return final_lines.join('\n')
24
+ return err and err.stack
25
+
26
+ def format_exception(exc, limit):
27
+ if jstype(exc) is 'undefined':
28
+ exc = ρσ_last_exception
29
+ if not isinstance(exc, Error):
30
+ if exc and exc.toString:
31
+ return [exc.toString()]
32
+ return []
33
+ tb = _get_internal_traceback(exc)
34
+ if tb:
35
+ lines = ρσ_str.splitlines(tb)
36
+ e = lines[0]
37
+ lines = lines[1:]
38
+ if limit:
39
+ lines = lines[:limit+1] if limit > 0 else lines[limit:]
40
+ lines.reverse()
41
+ lines.push(e)
42
+ lines.insert(0, 'Traceback (most recent call last):')
43
+ return [l+'\n' for l in lines]
44
+ return [exc.toString()]
45
+
46
+ def format_exc(limit):
47
+ return format_exception(ρσ_last_exception, limit).join('')
48
+
49
+ def print_exc(limit):
50
+ print(format_exc(limit))
51
+
52
+ def format_stack(limit):
53
+ stack = Error().stack
54
+ if not stack:
55
+ return []
56
+ lines = str.splitlines(stack)[2:]
57
+ lines.reverse()
58
+ if limit:
59
+ lines = lines[:limit+1] if limit > 0 else lines[limit:]
60
+ return [l + '\n' for l in lines]
61
+
62
+ def print_stack(limit):
63
+ print(format_stack(limit).join(''))
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 + '==')
@@ -169,6 +169,11 @@ const STUBS = [
169
169
  return_type: 'list',
170
170
  doc: 'Create a list from an iterable, or an empty list.' }),
171
171
 
172
+ new BuiltinInfo({ name: 'next',
173
+ params: [p('iterator'), p('default', { optional: true })],
174
+ return_type: 'any',
175
+ doc: 'Retrieve the next item from an iterator. If the iterator is exhausted, return default; if default is not given, raise StopIteration.' }),
176
+
172
177
  new BuiltinInfo({ name: 'map',
173
178
  params: [p('function'), p('iterable'), p('*iterables', { rest: true })],
174
179
  return_type: 'iterable',
@@ -22,6 +22,20 @@ const MESSAGES = {
22
22
  'dup-method': 'The method "{name}" was defined previously at line: {line}',
23
23
  };
24
24
 
25
+ // Built-in stdlib modules that are always available in RapydScript (bundled
26
+ // with the compiler from src/lib/). These should never produce 'Unknown module'
27
+ // errors regardless of what virtualFiles or stdlibFiles are configured.
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',
32
+ // Pseudo-modules for language feature flags (from __python__ import ...)
33
+ '__python__', '__builtins__',
34
+ ];
35
+
36
+ const _STDLIB_MODULE_SET = Object.create(null);
37
+ STDLIB_MODULES.forEach(m => { _STDLIB_MODULE_SET[m] = true; });
38
+
25
39
  // Symbols always available in RapydScript (from tools/lint.js BUILTINS list).
26
40
  export const BASE_BUILTINS = (
27
41
  'this self window document chr ord iterator_symbol print len range dir' +
@@ -30,11 +44,11 @@ export const BASE_BUILTINS = (
30
44
  ' isNaN JSON Math list set list_wrap ρσ_modules require bool int bin' +
31
45
  ' float iter Error EvalError set_wrap frozenset RangeError ReferenceError SyntaxError' +
32
46
  ' str TypeError URIError Exception AssertionError IndexError AttributeError KeyError' +
33
- ' ValueError ZeroDivisionError map hex filter zip dict dict_wrap UnicodeDecodeError HTMLCollection' +
47
+ ' ValueError ZeroDivisionError ImportError ModuleNotFoundError StopIteration map hex filter zip dict dict_wrap UnicodeDecodeError HTMLCollection' +
34
48
  ' NodeList alert console Node Symbol NamedNodeMap ρσ_eslice ρσ_delslice Number' +
35
49
  ' Boolean encodeURIComponent decodeURIComponent setTimeout setInterval' +
36
50
  ' setImmediate clearTimeout clearInterval clearImmediate requestAnimationFrame' +
37
- ' id repr sorted __name__ equals get_module ρσ_str jstype divmod NaN super Ellipsis slice'
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'
38
52
  ).split(' ');
39
53
 
40
54
  // ---------------------------------------------------------------------------
@@ -384,7 +398,13 @@ function Linter(RS, toplevel, code, builtins, knownModules) {
384
398
  };
385
399
 
386
400
  this.handle_symbol_funarg = function() {
387
- this.add_binding(this.current_node.name);
401
+ const node = this.current_node;
402
+ this.add_binding(node.name);
403
+ // Suppress undefined-symbol errors for type names used in argument
404
+ // annotations: `def foo(x: MyType):` — MyType is a hint, not a ref.
405
+ if (node.annotation instanceof RS.AST_SymbolRef) {
406
+ node.annotation.lint_visited = true;
407
+ }
388
408
  };
389
409
 
390
410
  this.handle_comprehension = function() {
@@ -681,6 +701,8 @@ export class Diagnostics {
681
701
  const sf = options.stdlibFiles;
682
702
  if ((vf && Object.keys(vf).length > 0) || (sf && Object.keys(sf).length > 0)) {
683
703
  knownModules = Object.create(null);
704
+ // Always include built-in stdlib so they never produce bad-import errors.
705
+ Object.assign(knownModules, _STDLIB_MODULE_SET);
684
706
  if (vf) Object.keys(vf).forEach(k => { knownModules[k] = true; });
685
707
  if (sf) Object.keys(sf).forEach(k => { knownModules[k] = true; });
686
708
  }