rapydscript-ns 0.9.2 → 0.9.3

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 (151) 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 +19 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/PYTHON_GAPS.md +420 -0
  8. package/README.md +153 -29
  9. package/TODO.md +16 -118
  10. package/add-toc-to-readme +2 -2
  11. package/bin/export +75 -75
  12. package/bin/rapydscript +70 -70
  13. package/bin/web-repl-export +102 -102
  14. package/build +2 -2
  15. package/language-service/index.js +237 -8
  16. package/memory/project_string_impl.md +43 -0
  17. package/package.json +1 -1
  18. package/publish.py +37 -37
  19. package/release/baselib-plain-pretty.js +248 -38
  20. package/release/baselib-plain-ugly.js +8 -8
  21. package/release/compiler.js +778 -277
  22. package/release/signatures.json +30 -30
  23. package/session.vim +4 -4
  24. package/setup.cfg +2 -2
  25. package/src/ast.pyj +4 -1
  26. package/src/baselib-builtins.pyj +56 -2
  27. package/src/baselib-containers.pyj +2 -0
  28. package/src/baselib-errors.pyj +7 -3
  29. package/src/baselib-internal.pyj +51 -6
  30. package/src/baselib-str.pyj +5 -3
  31. package/src/compiler.pyj +36 -36
  32. package/src/errors.pyj +30 -30
  33. package/src/lib/aes.pyj +646 -646
  34. package/src/lib/asyncio.pyj +534 -0
  35. package/src/lib/base64.pyj +399 -0
  36. package/src/lib/bisect.pyj +73 -0
  37. package/src/lib/collections.pyj +1 -1
  38. package/src/lib/copy.pyj +120 -120
  39. package/src/lib/csv.pyj +494 -0
  40. package/src/lib/elementmaker.pyj +83 -83
  41. package/src/lib/encodings.pyj +126 -126
  42. package/src/lib/gettext.pyj +569 -569
  43. package/src/lib/heapq.pyj +98 -0
  44. package/src/lib/html.pyj +382 -0
  45. package/src/lib/http/__init__.pyj +98 -0
  46. package/src/lib/http/client.pyj +304 -0
  47. package/src/lib/http/cookies.pyj +236 -0
  48. package/src/lib/itertools.pyj +580 -580
  49. package/src/lib/logging.pyj +672 -0
  50. package/src/lib/math.pyj +193 -193
  51. package/src/lib/operator.pyj +11 -11
  52. package/src/lib/pythonize.pyj +20 -20
  53. package/src/lib/random.pyj +118 -118
  54. package/src/lib/react.pyj +74 -74
  55. package/src/lib/string.pyj +357 -0
  56. package/src/lib/textwrap.pyj +329 -0
  57. package/src/lib/traceback.pyj +63 -63
  58. package/src/lib/urllib/__init__.pyj +14 -0
  59. package/src/lib/urllib/error.pyj +66 -0
  60. package/src/lib/urllib/parse.pyj +475 -0
  61. package/src/lib/urllib/request.pyj +86 -0
  62. package/src/lib/uuid.pyj +77 -77
  63. package/src/monaco-language-service/analyzer.js +5 -2
  64. package/src/monaco-language-service/completions.js +26 -0
  65. package/src/monaco-language-service/diagnostics.js +202 -3
  66. package/src/monaco-language-service/dts.js +550 -550
  67. package/src/monaco-language-service/scope.js +1 -0
  68. package/src/output/comments.pyj +45 -45
  69. package/src/output/exceptions.pyj +201 -201
  70. package/src/output/functions.pyj +152 -6
  71. package/src/output/jsx.pyj +164 -164
  72. package/src/output/loops.pyj +17 -2
  73. package/src/output/modules.pyj +1 -1
  74. package/src/output/operators.pyj +15 -0
  75. package/src/output/stream.pyj +0 -1
  76. package/src/output/treeshake.pyj +182 -182
  77. package/src/output/utils.pyj +72 -72
  78. package/src/parse.pyj +80 -17
  79. package/src/string_interpolation.pyj +72 -72
  80. package/src/tokenizer.pyj +1 -1
  81. package/src/unicode_aliases.pyj +576 -576
  82. package/src/utils.pyj +192 -192
  83. package/test/_import_one.pyj +37 -37
  84. package/test/_import_two/__init__.pyj +11 -11
  85. package/test/_import_two/level2/deep.pyj +4 -4
  86. package/test/_import_two/other.pyj +6 -6
  87. package/test/_import_two/sub.pyj +13 -13
  88. package/test/aes_vectors.pyj +421 -421
  89. package/test/annotations.pyj +80 -80
  90. package/test/async_generators.pyj +144 -0
  91. package/test/asyncio.pyj +307 -0
  92. package/test/base64.pyj +202 -0
  93. package/test/bisect.pyj +178 -0
  94. package/test/csv.pyj +405 -0
  95. package/test/decorators.pyj +77 -77
  96. package/test/docstrings.pyj +39 -39
  97. package/test/elementmaker_test.pyj +45 -45
  98. package/test/float_special.pyj +64 -0
  99. package/test/functions.pyj +151 -151
  100. package/test/generators.pyj +41 -41
  101. package/test/generic.pyj +370 -370
  102. package/test/heapq.pyj +174 -0
  103. package/test/html.pyj +212 -0
  104. package/test/http.pyj +259 -0
  105. package/test/imports.pyj +79 -72
  106. package/test/internationalization.pyj +73 -73
  107. package/test/lint.pyj +164 -164
  108. package/test/logging.pyj +356 -0
  109. package/test/long.pyj +130 -0
  110. package/test/loops.pyj +85 -85
  111. package/test/numpy.pyj +734 -734
  112. package/test/parenthesized_with.pyj +141 -0
  113. package/test/python_compat.pyj +3 -5
  114. package/test/python_modulo.pyj +76 -0
  115. package/test/python_modulo_off.pyj +21 -0
  116. package/test/repl.pyj +121 -121
  117. package/test/scoped_flags.pyj +76 -76
  118. package/test/str.pyj +14 -0
  119. package/test/string.pyj +245 -0
  120. package/test/textwrap.pyj +172 -0
  121. package/test/type_display.pyj +48 -0
  122. package/test/type_enforcement.pyj +164 -0
  123. package/test/unit/index.js +14 -6
  124. package/test/unit/language-service-completions.js +119 -0
  125. package/test/unit/language-service-dts.js +543 -543
  126. package/test/unit/language-service-hover.js +455 -455
  127. package/test/unit/language-service-scope.js +32 -0
  128. package/test/unit/language-service.js +127 -3
  129. package/test/unit/run-language-service.js +17 -3
  130. package/test/unit/web-repl.js +2094 -29
  131. package/test/urllib.pyj +193 -0
  132. package/tools/compile.js +1 -1
  133. package/tools/compiler.d.ts +367 -367
  134. package/tools/completer.js +131 -131
  135. package/tools/embedded_compiler.js +7 -7
  136. package/tools/gettext.js +185 -185
  137. package/tools/ini.js +65 -65
  138. package/tools/msgfmt.js +187 -187
  139. package/tools/repl.js +223 -223
  140. package/tools/test.js +118 -118
  141. package/tools/utils.js +128 -128
  142. package/tools/web_repl.js +95 -95
  143. package/try +41 -41
  144. package/web-repl/env.js +196 -196
  145. package/web-repl/index.html +163 -163
  146. package/web-repl/main.js +1 -1
  147. package/web-repl/prism.css +139 -139
  148. package/web-repl/prism.js +113 -113
  149. package/web-repl/rapydscript.js +224 -224
  150. package/web-repl/sha1.js +25 -25
  151. package/test/omit_function_metadata.pyj +0 -20
@@ -33,6 +33,7 @@ export class SymbolInfo {
33
33
  this.return_type = opts.return_type || null; // annotated return type, e.g. 'list', 'str', 'MyClass'
34
34
  this.source_module = opts.source_module || null; // module name when kind='import' (from X import Y)
35
35
  this.original_name = opts.original_name || null; // pre-alias name for imports (from X import Y as Z → 'Y')
36
+ this.is_bare_import = opts.is_bare_import || false; // true for `import X` (vs `from X import Y`)
36
37
  }
37
38
  }
38
39
 
@@ -1,45 +1,45 @@
1
- # vim:fileencoding=utf-8
2
- # License: BSD Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
3
- from __python__ import hash_literals
4
-
5
- from ast import AST_Exit, is_node_type
6
-
7
-
8
- def output_comments(comments, output, nlb):
9
- for comm in comments:
10
- if comm.type is "comment1":
11
- output.print("//" + comm.value + "\n")
12
- output.indent()
13
- elif comm.type is "comment2":
14
- output.print("/*" + comm.value + "*/")
15
- if nlb:
16
- output.print("\n")
17
- output.indent()
18
- else:
19
- output.space()
20
-
21
-
22
- def print_comments(self, output):
23
- c = output.options.comments
24
- if c:
25
- start = self.start
26
- if start and not start._comments_dumped:
27
- start._comments_dumped = True
28
- comments = start.comments_before
29
- # XXX: ugly fix for https://github.com/mishoo/RapydScript2/issues/112
30
- # if this node is `return` or `throw`, we cannot allow comments before
31
- # the returned or thrown value.
32
- if is_node_type(self, AST_Exit) and self.value and self.value.start.comments_before and self.value.start.comments_before.length > 0:
33
- comments = (comments or v'[]').concat(self.value.start.comments_before)
34
- self.value.start.comments_before = v'[]'
35
-
36
- if c.test:
37
- comments = comments.filter(def(comment):
38
- return c.test(comment.value)
39
- )
40
- elif jstype(c) is "function":
41
- comments = comments.filter(def(comment):
42
- return c(self, comment)
43
- )
44
-
45
- output_comments(comments, output, start.nlb)
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
3
+ from __python__ import hash_literals
4
+
5
+ from ast import AST_Exit, is_node_type
6
+
7
+
8
+ def output_comments(comments, output, nlb):
9
+ for comm in comments:
10
+ if comm.type is "comment1":
11
+ output.print("//" + comm.value + "\n")
12
+ output.indent()
13
+ elif comm.type is "comment2":
14
+ output.print("/*" + comm.value + "*/")
15
+ if nlb:
16
+ output.print("\n")
17
+ output.indent()
18
+ else:
19
+ output.space()
20
+
21
+
22
+ def print_comments(self, output):
23
+ c = output.options.comments
24
+ if c:
25
+ start = self.start
26
+ if start and not start._comments_dumped:
27
+ start._comments_dumped = True
28
+ comments = start.comments_before
29
+ # XXX: ugly fix for https://github.com/mishoo/RapydScript2/issues/112
30
+ # if this node is `return` or `throw`, we cannot allow comments before
31
+ # the returned or thrown value.
32
+ if is_node_type(self, AST_Exit) and self.value and self.value.start.comments_before and self.value.start.comments_before.length > 0:
33
+ comments = (comments or v'[]').concat(self.value.start.comments_before)
34
+ self.value.start.comments_before = v'[]'
35
+
36
+ if c.test:
37
+ comments = comments.filter(def(comment):
38
+ return c.test(comment.value)
39
+ )
40
+ elif jstype(c) is "function":
41
+ comments = comments.filter(def(comment):
42
+ return c(self, comment)
43
+ )
44
+
45
+ output_comments(comments, output, start.nlb)
@@ -1,201 +1,201 @@
1
- # vim:fileencoding=utf-8
2
- # License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
- from __python__ import hash_literals
4
-
5
- from output.statements import print_bracketed, display_body
6
-
7
-
8
- def print_try(self, output):
9
- else_var_name = None
10
- def update_output_var(output):
11
- output.indent(), output.assign(else_var_name), output.print('true'), output.end_statement()
12
- if self.belse:
13
- else_var_name = output.new_try_else_counter()
14
- output.assign('var ' + else_var_name), output.print('false'), output.end_statement(), output.indent()
15
- output.print("try")
16
- output.space()
17
- print_bracketed(self, output, False, None, None, update_output_var if else_var_name else None)
18
- if self.bcatch:
19
- output.space()
20
- print_catch(self.bcatch, output)
21
-
22
- if self.bfinally:
23
- output.space()
24
- print_finally(self.bfinally, output, self.belse, else_var_name)
25
- elif self.belse:
26
- output.newline()
27
- print_else(self.belse, else_var_name, output)
28
-
29
-
30
- def print_catch(self, output):
31
- # Dispatch to except* handler when any clause is an exception group handler
32
- if self.body.length and self.body[0].is_star:
33
- print_catch_star(self, output)
34
- return
35
- output.print("catch")
36
- output.space()
37
- output.with_parens(def():
38
- output.print("ρσ_Exception")
39
- )
40
- output.space()
41
- output.with_block(def():
42
- output.indent()
43
- output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
44
- output.indent()
45
- no_default = True
46
- for i, exception in enumerate(self.body):
47
- if i:
48
- output.print("else ")
49
-
50
- if exception.errors.length:
51
- output.print("if")
52
- output.space()
53
- output.with_parens(def():
54
- for i, err in enumerate(exception.errors):
55
- if i:
56
- output.newline()
57
- output.indent()
58
- output.print("||")
59
- output.space()
60
-
61
- output.print("ρσ_Exception")
62
- output.space()
63
- output.print("instanceof")
64
- output.space()
65
- if err.name is 'Exception':
66
- output.print('Error')
67
- else:
68
- err.print(output)
69
- )
70
- output.space()
71
- else:
72
- no_default = False
73
- print_bracketed(exception, output, True)
74
- output.space()
75
- if no_default:
76
- output.print("else")
77
- output.space()
78
- output.with_block(def():
79
- output.indent()
80
- output.print("throw")
81
- output.space()
82
- output.print("ρσ_Exception")
83
- output.semicolon()
84
- output.newline()
85
- )
86
- output.newline()
87
- )
88
-
89
-
90
- def _eg_type_cond(errors, varname):
91
- # Build a JS condition string testing varname against each error type
92
- parts = []
93
- for err in errors:
94
- if err.name is 'Exception':
95
- parts.push(varname + " instanceof Error")
96
- else:
97
- parts.push(varname + " instanceof " + err.name)
98
- return parts.join(" || ")
99
-
100
-
101
- def print_catch_star(self, output):
102
- output.print("catch")
103
- output.space()
104
- output.with_parens(def():
105
- output.print("ρσ_Exception")
106
- )
107
- output.space()
108
- output.with_block(def():
109
- output.indent()
110
- output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
111
-
112
- # Normalise: wrap non-ExceptionGroup exception into a one-element array
113
- output.indent()
114
- output.print("var ρσ_eg_exceptions = (ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.exceptions.slice() : [ρσ_Exception]")
115
- output.semicolon(), output.newline()
116
- output.indent()
117
- output.print("var ρσ_eg_raised = []")
118
- output.semicolon(), output.newline()
119
-
120
- for ei, exception in enumerate(self.body):
121
- idx = str(ei)
122
- if exception.errors.length:
123
- cond = _eg_type_cond(exception.errors, "ρσ_et")
124
- output.indent()
125
- output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.filter(function(ρσ_et) { return " + cond + "; })")
126
- output.semicolon(), output.newline()
127
- output.indent()
128
- output.print("ρσ_eg_exceptions = ρσ_eg_exceptions.filter(function(ρσ_et) { return !(" + cond + "); })")
129
- output.semicolon(), output.newline()
130
- else:
131
- # Bare except*: take all remaining
132
- output.indent()
133
- output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.slice()")
134
- output.semicolon(), output.newline()
135
- output.indent()
136
- output.print("ρσ_eg_exceptions = []")
137
- output.semicolon(), output.newline()
138
-
139
- output.indent()
140
- output.print("if (ρσ_eg_matched_" + idx + ".length > 0)")
141
- output.space()
142
- output.with_block(def():
143
- if exception.argname:
144
- output.indent()
145
- output.print("var ")
146
- output.assign(exception.argname)
147
- output.print("(ρσ_Exception instanceof ExceptionGroup) ? new ExceptionGroup(ρσ_Exception.message, ρσ_eg_matched_" + idx + ") : ρσ_eg_matched_" + idx + "[0]")
148
- output.semicolon(), output.newline()
149
- output.indent()
150
- output.print("try")
151
- output.space()
152
- output.with_block(def():
153
- display_body(exception.body, False, output)
154
- )
155
- output.print(" catch (ρσ_eg_exc_" + idx + ")")
156
- output.space()
157
- output.with_block(def():
158
- output.indent()
159
- output.print("ρσ_eg_raised.push(ρσ_eg_exc_" + idx + ")")
160
- output.semicolon(), output.newline()
161
- )
162
- output.newline()
163
- )
164
- output.newline()
165
-
166
- # Re-raise unmatched exceptions and any raised by handlers
167
- output.indent()
168
- output.print("var ρσ_eg_unhandled = ρσ_eg_exceptions.concat(ρσ_eg_raised)")
169
- output.semicolon(), output.newline()
170
- output.indent()
171
- output.print("if (ρσ_eg_unhandled.length > 0)")
172
- output.space()
173
- output.with_block(def():
174
- output.indent()
175
- output.print("throw (ρσ_eg_unhandled.length === 1 && !(ρσ_Exception instanceof ExceptionGroup)) ? ρσ_eg_unhandled[0] : new ExceptionGroup((ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.message : \"unhandled exceptions\", ρσ_eg_unhandled)")
176
- output.semicolon(), output.newline()
177
- )
178
- output.newline()
179
- )
180
-
181
-
182
- def print_finally(self, output, belse, else_var_name):
183
- output.print("finally")
184
- output.space()
185
- if else_var_name:
186
- output.with_block(def():
187
- output.indent(), output.print("try")
188
- output.space()
189
- output.with_block(def():
190
- print_else(belse, else_var_name, output)
191
- )
192
- print_finally(self, output)
193
- )
194
- else:
195
- print_bracketed(self, output)
196
-
197
-
198
- def print_else(self, else_var_name, output):
199
- output.indent(), output.spaced('if', '(' + else_var_name + ')')
200
- output.space()
201
- print_bracketed(self, output)
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
+ from __python__ import hash_literals
4
+
5
+ from output.statements import print_bracketed, display_body
6
+
7
+
8
+ def print_try(self, output):
9
+ else_var_name = None
10
+ def update_output_var(output):
11
+ output.indent(), output.assign(else_var_name), output.print('true'), output.end_statement()
12
+ if self.belse:
13
+ else_var_name = output.new_try_else_counter()
14
+ output.assign('var ' + else_var_name), output.print('false'), output.end_statement(), output.indent()
15
+ output.print("try")
16
+ output.space()
17
+ print_bracketed(self, output, False, None, None, update_output_var if else_var_name else None)
18
+ if self.bcatch:
19
+ output.space()
20
+ print_catch(self.bcatch, output)
21
+
22
+ if self.bfinally:
23
+ output.space()
24
+ print_finally(self.bfinally, output, self.belse, else_var_name)
25
+ elif self.belse:
26
+ output.newline()
27
+ print_else(self.belse, else_var_name, output)
28
+
29
+
30
+ def print_catch(self, output):
31
+ # Dispatch to except* handler when any clause is an exception group handler
32
+ if self.body.length and self.body[0].is_star:
33
+ print_catch_star(self, output)
34
+ return
35
+ output.print("catch")
36
+ output.space()
37
+ output.with_parens(def():
38
+ output.print("ρσ_Exception")
39
+ )
40
+ output.space()
41
+ output.with_block(def():
42
+ output.indent()
43
+ output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
44
+ output.indent()
45
+ no_default = True
46
+ for i, exception in enumerate(self.body):
47
+ if i:
48
+ output.print("else ")
49
+
50
+ if exception.errors.length:
51
+ output.print("if")
52
+ output.space()
53
+ output.with_parens(def():
54
+ for i, err in enumerate(exception.errors):
55
+ if i:
56
+ output.newline()
57
+ output.indent()
58
+ output.print("||")
59
+ output.space()
60
+
61
+ output.print("ρσ_Exception")
62
+ output.space()
63
+ output.print("instanceof")
64
+ output.space()
65
+ if err.name is 'Exception':
66
+ output.print('Error')
67
+ else:
68
+ err.print(output)
69
+ )
70
+ output.space()
71
+ else:
72
+ no_default = False
73
+ print_bracketed(exception, output, True)
74
+ output.space()
75
+ if no_default:
76
+ output.print("else")
77
+ output.space()
78
+ output.with_block(def():
79
+ output.indent()
80
+ output.print("throw")
81
+ output.space()
82
+ output.print("ρσ_Exception")
83
+ output.semicolon()
84
+ output.newline()
85
+ )
86
+ output.newline()
87
+ )
88
+
89
+
90
+ def _eg_type_cond(errors, varname):
91
+ # Build a JS condition string testing varname against each error type
92
+ parts = []
93
+ for err in errors:
94
+ if err.name is 'Exception':
95
+ parts.push(varname + " instanceof Error")
96
+ else:
97
+ parts.push(varname + " instanceof " + err.name)
98
+ return parts.join(" || ")
99
+
100
+
101
+ def print_catch_star(self, output):
102
+ output.print("catch")
103
+ output.space()
104
+ output.with_parens(def():
105
+ output.print("ρσ_Exception")
106
+ )
107
+ output.space()
108
+ output.with_block(def():
109
+ output.indent()
110
+ output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
111
+
112
+ # Normalise: wrap non-ExceptionGroup exception into a one-element array
113
+ output.indent()
114
+ output.print("var ρσ_eg_exceptions = (ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.exceptions.slice() : [ρσ_Exception]")
115
+ output.semicolon(), output.newline()
116
+ output.indent()
117
+ output.print("var ρσ_eg_raised = []")
118
+ output.semicolon(), output.newline()
119
+
120
+ for ei, exception in enumerate(self.body):
121
+ idx = str(ei)
122
+ if exception.errors.length:
123
+ cond = _eg_type_cond(exception.errors, "ρσ_et")
124
+ output.indent()
125
+ output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.filter(function(ρσ_et) { return " + cond + "; })")
126
+ output.semicolon(), output.newline()
127
+ output.indent()
128
+ output.print("ρσ_eg_exceptions = ρσ_eg_exceptions.filter(function(ρσ_et) { return !(" + cond + "); })")
129
+ output.semicolon(), output.newline()
130
+ else:
131
+ # Bare except*: take all remaining
132
+ output.indent()
133
+ output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.slice()")
134
+ output.semicolon(), output.newline()
135
+ output.indent()
136
+ output.print("ρσ_eg_exceptions = []")
137
+ output.semicolon(), output.newline()
138
+
139
+ output.indent()
140
+ output.print("if (ρσ_eg_matched_" + idx + ".length > 0)")
141
+ output.space()
142
+ output.with_block(def():
143
+ if exception.argname:
144
+ output.indent()
145
+ output.print("var ")
146
+ output.assign(exception.argname)
147
+ output.print("(ρσ_Exception instanceof ExceptionGroup) ? new ExceptionGroup(ρσ_Exception.message, ρσ_eg_matched_" + idx + ") : ρσ_eg_matched_" + idx + "[0]")
148
+ output.semicolon(), output.newline()
149
+ output.indent()
150
+ output.print("try")
151
+ output.space()
152
+ output.with_block(def():
153
+ display_body(exception.body, False, output)
154
+ )
155
+ output.print(" catch (ρσ_eg_exc_" + idx + ")")
156
+ output.space()
157
+ output.with_block(def():
158
+ output.indent()
159
+ output.print("ρσ_eg_raised.push(ρσ_eg_exc_" + idx + ")")
160
+ output.semicolon(), output.newline()
161
+ )
162
+ output.newline()
163
+ )
164
+ output.newline()
165
+
166
+ # Re-raise unmatched exceptions and any raised by handlers
167
+ output.indent()
168
+ output.print("var ρσ_eg_unhandled = ρσ_eg_exceptions.concat(ρσ_eg_raised)")
169
+ output.semicolon(), output.newline()
170
+ output.indent()
171
+ output.print("if (ρσ_eg_unhandled.length > 0)")
172
+ output.space()
173
+ output.with_block(def():
174
+ output.indent()
175
+ output.print("throw (ρσ_eg_unhandled.length === 1 && !(ρσ_Exception instanceof ExceptionGroup)) ? ρσ_eg_unhandled[0] : new ExceptionGroup((ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.message : \"unhandled exceptions\", ρσ_eg_unhandled)")
176
+ output.semicolon(), output.newline()
177
+ )
178
+ output.newline()
179
+ )
180
+
181
+
182
+ def print_finally(self, output, belse, else_var_name):
183
+ output.print("finally")
184
+ output.space()
185
+ if else_var_name:
186
+ output.with_block(def():
187
+ output.indent(), output.print("try")
188
+ output.space()
189
+ output.with_block(def():
190
+ print_else(belse, else_var_name, output)
191
+ )
192
+ print_finally(self, output)
193
+ )
194
+ else:
195
+ print_bracketed(self, output)
196
+
197
+
198
+ def print_else(self, else_var_name, output):
199
+ output.indent(), output.spaced('if', '(' + else_var_name + ')')
200
+ output.space()
201
+ print_bracketed(self, output)