rapydscript-ng 0.8.0 → 0.8.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 (72) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +8 -0
  3. package/bin/build.ts +117 -0
  4. package/build_wheels.py +133 -0
  5. package/editor-plugins/README.md +80 -0
  6. package/editor-plugins/nvim.lua +321 -0
  7. package/package.json +1 -1
  8. package/publish.py +27 -17
  9. package/release/compiler.js +8125 -8093
  10. package/release/signatures.json +27 -27
  11. package/release/stdlib_modules.json +1 -0
  12. package/src/ast.pyj +379 -279
  13. package/src/baselib-builtins.pyj +47 -26
  14. package/src/baselib-containers.pyj +105 -92
  15. package/src/baselib-errors.pyj +8 -1
  16. package/src/baselib-internal.pyj +35 -20
  17. package/src/baselib-itertools.pyj +13 -7
  18. package/src/baselib-str.pyj +55 -80
  19. package/src/compiler.pyj +4 -4
  20. package/src/errors.pyj +3 -4
  21. package/src/lib/aes.pyj +46 -32
  22. package/src/lib/elementmaker.pyj +11 -9
  23. package/src/lib/encodings.pyj +15 -5
  24. package/src/lib/gettext.pyj +9 -4
  25. package/src/lib/math.pyj +106 -45
  26. package/src/lib/operator.pyj +10 -10
  27. package/src/lib/pythonize.pyj +2 -1
  28. package/src/lib/random.pyj +28 -21
  29. package/src/lib/re.pyj +490 -17
  30. package/src/lib/traceback.pyj +7 -2
  31. package/src/lib/uuid.pyj +2 -2
  32. package/src/output/classes.pyj +28 -27
  33. package/src/output/codegen.pyj +80 -83
  34. package/src/output/comments.pyj +8 -8
  35. package/src/output/exceptions.pyj +20 -21
  36. package/src/output/functions.pyj +37 -26
  37. package/src/output/literals.pyj +14 -10
  38. package/src/output/loops.pyj +63 -59
  39. package/src/output/modules.pyj +52 -23
  40. package/src/output/operators.pyj +40 -29
  41. package/src/output/statements.pyj +20 -14
  42. package/src/output/stream.pyj +33 -34
  43. package/src/output/utils.pyj +12 -8
  44. package/src/parse.pyj +234 -233
  45. package/src/string_interpolation.pyj +5 -3
  46. package/src/tokenizer.pyj +176 -148
  47. package/src/utils.pyj +31 -14
  48. package/test/fmt.pyj +94 -4
  49. package/test/generic.pyj +9 -0
  50. package/test/lsp.pyj +35 -0
  51. package/test/str.pyj +8 -0
  52. package/tools/cli.mjs +25 -4
  53. package/tools/compile.mjs +7 -3
  54. package/tools/compiler.mjs +34 -2
  55. package/tools/fmt.mjs +269 -22
  56. package/tools/ini.mjs +112 -1
  57. package/tools/lsp.mjs +56 -6
  58. package/tools/repl.mjs +5 -2
  59. package/tools/self.mjs +15 -0
  60. package/tools/test.mjs +100 -0
  61. package/tools/web_repl_export.mjs +4 -0
  62. package/tree-sitter/package.json +1 -1
  63. package/tree-sitter/tree-sitter.json +1 -1
  64. package/editor-plugins/nvim/rapydscript/README.md +0 -184
  65. package/editor-plugins/nvim/rapydscript/bin/rapydscript.so +0 -0
  66. package/editor-plugins/nvim/rapydscript/ftdetect/rapydscript.lua +0 -10
  67. package/editor-plugins/nvim/rapydscript/lua/rapydscript/health.lua +0 -88
  68. package/editor-plugins/nvim/rapydscript/lua/rapydscript/init.lua +0 -279
  69. /package/tree-sitter/queries/{rapydscript/highlights.scm → highlights.scm} +0 -0
  70. /package/tree-sitter/queries/{rapydscript/indents.scm → indents.scm} +0 -0
  71. /package/tree-sitter/queries/{rapydscript/injections.scm → injections.scm} +0 -0
  72. /package/tree-sitter/queries/{rapydscript/locals.scm → locals.scm} +0 -0
package/src/parse.pyj CHANGED
@@ -3,8 +3,6 @@
3
3
  # globals: readfile, writefile, stat_file, sha1sum, ast_from_json, ast_to_json, make_lazy_ast_module, decode_cache, encode_cache
4
4
  from __python__ import hash_literals
5
5
 
6
- from utils import make_predicate, array_to_hash, defaults, has_prop, cache_file_name
7
- from errors import SyntaxError, ImportError
8
6
  from ast import (
9
7
  AST_ArgsDef, AST_Array, AST_Assign, AST_Binary, AST_BlockStatement, AST_Break,
10
8
  AST_Call, AST_CallArg, AST_CallArgs, AST_Catch, AST_Class, AST_ClassCall, AST_Conditional,
@@ -23,11 +21,13 @@ AST_Throw, AST_Toplevel, AST_True, AST_Try, AST_UnaryPrefix,
23
21
  AST_Undefined, AST_Var, AST_VarDef, AST_Verbatim, AST_While, AST_With, AST_WithClause,
24
22
  AST_Yield, AST_Await, AST_Assert, AST_Existential, is_node_type, TreeWalker
25
23
  )
24
+ from errors import SyntaxError, ImportError
26
25
  from tokenizer import tokenizer, is_token, RESERVED_WORDS
26
+ from utils import make_predicate, array_to_hash, defaults, has_prop, cache_file_name
27
27
 
28
28
 
29
29
  COMPILER_VERSION = '__COMPILER_VERSION__'
30
- PYTHON_FLAGS = {'dict_literals':True, 'overload_getitem':True, 'bound_methods':True, 'hash_literals':True}
30
+ PYTHON_FLAGS = {'dict_literals': True, 'overload_getitem': True, 'bound_methods': True, 'hash_literals': True}
31
31
  CACHE_VERSION = 1
32
32
 
33
33
 
@@ -36,7 +36,7 @@ def get_compiler_version():
36
36
 
37
37
 
38
38
  def static_predicate(names):
39
- return {k:True for k in names.split(' ')}
39
+ return {k: True for k in names.split(' ')}
40
40
 
41
41
  NATIVE_CLASSES = {
42
42
  'Image': {},
@@ -60,14 +60,14 @@ NATIVE_CLASSES = {
60
60
  )
61
61
  },
62
62
  'String': {
63
- 'static': static_predicate("fromCharCode")
63
+ 'static': static_predicate('fromCharCode')
64
64
  },
65
65
  'Array': {
66
- 'static': static_predicate("isArray from of")
66
+ 'static': static_predicate('isArray from of')
67
67
  },
68
68
  'Function': {},
69
69
  'Date': {
70
- 'static': static_predicate("UTC now parse")
70
+ 'static': static_predicate('UTC now parse')
71
71
  },
72
72
  'ArrayBuffer': {
73
73
  'static': static_predicate('isView transfer')
@@ -117,34 +117,35 @@ UNARY_PREFIX = make_predicate('typeof void delete ~ - + ! @')
117
117
 
118
118
  ASSIGNMENT = make_predicate('= += -= /= //= *= %= >>= <<= >>>= |= ^= &=')
119
119
 
120
- PRECEDENCE = (def(a, ret):
120
+ PRECEDENCE = (def (a, ret):
121
121
  for i in range(a.length):
122
122
  b = a[i]
123
123
  for j in range(b.length):
124
- ret[b[j]] = i+1
124
+ ret[b[j]] = i + 1
125
125
  return ret
126
126
  )([
127
127
  # lowest precedence
128
- [ "||" ],
129
- [ "&&" ],
130
- [ "|" ],
131
- [ "^" ],
132
- [ "&" ],
133
- [ "==", "===", "!=", "!==" ],
134
- [ "<", ">", "<=", ">=", "in", "nin", "instanceof" ],
135
- [ ">>", "<<", ">>>" ],
136
- [ "+", "-" ],
137
- [ "*", "/", "//", "%" ],
138
- [ "**" ]
128
+ ['||'],
129
+ ['&&'],
130
+ ['|'],
131
+ ['^'],
132
+ ['&'],
133
+ ['==', '===', '!=', '!=='],
134
+ ['<', '>', '<=', '>=', 'in', 'nin', 'instanceof'],
135
+ ['>>', '<<', '>>>'],
136
+ ['+', '-'],
137
+ ['*', '/', '//', '%'],
138
+ ['**']
139
139
  # highest precedence
140
140
  ], {})
141
141
 
142
- STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ])
142
+ STATEMENTS_WITH_LABELS = array_to_hash(['for', 'do', 'while', 'switch'])
143
143
 
144
- ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name", "js" ])
144
+ ATOMIC_START_TOKEN = array_to_hash(['atom', 'num', 'string', 'regexp', 'name', 'js'])
145
145
 
146
146
  compile_time_decorators = ['staticmethod', 'external', 'property']
147
147
 
148
+
148
149
  def has_simple_decorator(decorators, name):
149
150
  remove = v'[]'
150
151
  for v'var i = 0; i < decorators.length; i++':
@@ -158,6 +159,7 @@ def has_simple_decorator(decorators, name):
158
159
  return True
159
160
  return False
160
161
 
162
+
161
163
  def has_setter_decorator(decorators, name):
162
164
  remove = v'[]'
163
165
  for v'var i = 0; i < decorators.length; i++':
@@ -171,9 +173,9 @@ def has_setter_decorator(decorators, name):
171
173
  return True
172
174
  return False
173
175
 
176
+
174
177
  # -----[ Parser ]-----
175
178
  def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_ids, imported_modules, importing_modules, options):
176
-
177
179
  def next():
178
180
  S.prev = S.token
179
181
  if S.peeked.length:
@@ -207,7 +209,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
207
209
  def unexpected(token):
208
210
  if token is undefined:
209
211
  token = S.token
210
- token_error(token, "Unexpected token: " + token.type + " «" + token.value + "»")
212
+ token_error(token, 'Unexpected token: ' + token.type + ' «' + token.value + '»')
211
213
 
212
214
  # --- Error recovery (only active when options.recover_errors is True) --------
213
215
  # These helpers let the LSP obtain a usable AST from a file that contains
@@ -231,30 +233,30 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
231
233
  # line); such errors are recorded and skipping continues. The tokenizer
232
234
  # advances its position for every such error (and never raises for an
233
235
  # unexpected character in recover mode), so this loop always terminates.
234
- while not is_("eof"):
236
+ while not is_('eof'):
235
237
  try:
236
238
  next()
237
239
  except as e:
238
240
  if is_recoverable_error(e):
239
241
  record_recovery(e)
240
- if is_("eof"):
242
+ if is_('eof'):
241
243
  return
242
244
  continue
243
245
  raise
244
- if is_("eof") or is_("punc", "}") or S.token.nlb:
246
+ if is_('eof') or is_('punc', '}') or S.token.nlb:
245
247
  return
246
248
 
247
249
  def expect_token(type, val):
248
250
  if is_(type, val):
249
251
  return next()
250
- token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" +
251
- ", expected " + type + " «" + val + "»")
252
+ token_error(S.token, 'Unexpected token ' + S.token.type + ' «' + S.token.value + '»' +
253
+ ', expected ' + type + ' «' + val + '»')
252
254
 
253
255
  def expect(punc):
254
- return expect_token("punc", punc)
256
+ return expect_token('punc', punc)
255
257
 
256
258
  def semicolon():
257
- if is_("punc", ";"):
259
+ if is_('punc', ';'):
258
260
  next()
259
261
  S.token.nlb = True
260
262
 
@@ -279,7 +281,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
279
281
  if obj.name:
280
282
  ans.push(obj.name.name)
281
283
  else:
282
- token_error(obj.start, "Top-level functions must have names")
284
+ token_error(obj.start, 'Top-level functions must have names')
283
285
  else:
284
286
  # skip inner scopes
285
287
  if is_node_type(obj, AST_Scope):
@@ -298,7 +300,6 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
298
300
  if body.alternative:
299
301
  ans = ans.concat(scan_for_top_level_callables(body.alternative))
300
302
 
301
-
302
303
  return ans
303
304
 
304
305
  def scan_for_classes(body):
@@ -341,10 +342,10 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
341
342
 
342
343
  def add_assign_lhs(lhs):
343
344
  if is_node_type(lhs, AST_Seq):
344
- lhs = new AST_Array({'elements':lhs.to_array()})
345
+ lhs = new AST_Array({'elements': lhs.to_array()})
345
346
  if is_node_type(lhs, AST_Array):
346
347
  # assignment to an implicit tuple
347
- push("ρσ_unpack")
348
+ push('ρσ_unpack')
348
349
  scan_in_array(lhs.elements)
349
350
  elif lhs.name:
350
351
  # assignment to a single variable
@@ -353,7 +354,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
353
354
  def add_for_in(stmt):
354
355
  if is_node_type(stmt.init, AST_Array):
355
356
  # iteration via implicit tuple
356
- push("ρσ_unpack")
357
+ push('ρσ_unpack')
357
358
  scan_in_array(stmt.init.elements)
358
359
  else:
359
360
  # iteration via a single variable
@@ -431,13 +432,11 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
431
432
  if opt:
432
433
  vars = vars.concat(scan_for_nonlocal_defs(opt))
433
434
 
434
-
435
435
  elif body.body:
436
436
  vars = vars.concat(scan_for_nonlocal_defs(body.body))
437
437
  if body.alternative:
438
438
  vars = vars.concat(scan_for_nonlocal_defs(body.alternative))
439
439
 
440
-
441
440
  return vars
442
441
 
443
442
  async def return_():
@@ -445,7 +444,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
445
444
  semicolon()
446
445
  value = None
447
446
  else:
448
- is_end_of_statement = S.token.nlb or is_("eof") or is_("punc", "}")
447
+ is_end_of_statement = S.token.nlb or is_('eof') or is_('punc', '}')
449
448
  if is_end_of_statement:
450
449
  value = None
451
450
  else:
@@ -469,50 +468,50 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
469
468
  p = prev()
470
469
  if p and not S.token.nlb and ATOMIC_START_TOKEN[p.type] and not is_('punc', ':'):
471
470
  unexpected()
472
- if tmp_ is "string":
471
+ if tmp_ is 'string':
473
472
  return await simple_statement()
474
- elif tmp_ is "shebang":
473
+ elif tmp_ is 'shebang':
475
474
  tmp_ = S.token.value
476
475
  next()
477
476
  return new AST_Directive({
478
477
  'value': tmp_
479
478
  })
480
- elif tmp_ is "num" or tmp_ is "regexp" or tmp_ is "operator" or tmp_ is "atom" or tmp_ is "js":
479
+ elif tmp_ is 'num' or tmp_ is 'regexp' or tmp_ is 'operator' or tmp_ is 'atom' or tmp_ is 'js':
481
480
  return await simple_statement()
482
- elif tmp_ is "punc":
481
+ elif tmp_ is 'punc':
483
482
  tmp_ = S.token.value
484
- if tmp_ is ":":
483
+ if tmp_ is ':':
485
484
  bs_body = await block_()
486
485
  return new AST_BlockStatement({
487
486
  'start': S.token,
488
487
  'body': bs_body,
489
488
  'end': prev()
490
489
  })
491
- elif tmp_ is "{" or tmp_ is "[" or tmp_ is "(":
490
+ elif tmp_ is '{' or tmp_ is '[' or tmp_ is '(':
492
491
  return await simple_statement()
493
- elif tmp_ is ";":
492
+ elif tmp_ is ';':
494
493
  next()
495
- return new AST_EmptyStatement({'stype':';', 'start':prev(), 'end':prev()})
494
+ return new AST_EmptyStatement({'stype': ';', 'start': prev(), 'end': prev()})
496
495
  else:
497
496
  unexpected()
498
- elif tmp_ is "name":
497
+ elif tmp_ is 'name':
499
498
  if (is_token(peek(), 'punc', ':')) token_error(peek(), 'invalid syntax, colon not allowed here')
500
499
  return await simple_statement()
501
- elif tmp_ is "keyword":
500
+ elif tmp_ is 'keyword':
502
501
  tmp_ = S.token.value
503
502
  next()
504
- if tmp_ is "break":
503
+ if tmp_ is 'break':
505
504
  return break_cont(AST_Break)
506
- elif tmp_ is "continue":
505
+ elif tmp_ is 'continue':
507
506
  return break_cont(AST_Continue)
508
- elif tmp_ is "debugger":
507
+ elif tmp_ is 'debugger':
509
508
  semicolon()
510
509
  return new AST_Debugger()
511
- elif tmp_ is "do":
510
+ elif tmp_ is 'do':
512
511
  do_body = await in_loop(statement)
513
- do_cond = await (async def():
514
- expect(".")
515
- expect_token("keyword", "while")
512
+ do_cond = await (async def ():
513
+ expect('.')
514
+ expect_token('keyword', 'while')
516
515
  tmp = await expression(True)
517
516
  if is_node_type(tmp, AST_Assign):
518
517
  croak('Assignments in do loop conditions are not allowed')
@@ -523,7 +522,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
523
522
  'body': do_body,
524
523
  'condition': do_cond,
525
524
  })
526
- elif tmp_ is "while":
525
+ elif tmp_ is 'while':
527
526
  while_cond = await expression(True)
528
527
  if is_node_type(while_cond, AST_Assign):
529
528
  croak('Assignments in while loop conditions are not allowed')
@@ -534,17 +533,17 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
534
533
  'condition': while_cond,
535
534
  'body': while_body
536
535
  })
537
- elif tmp_ is "for":
536
+ elif tmp_ is 'for':
538
537
  if is_('js'):
539
538
  return await for_js()
540
539
  return await for_()
541
- elif tmp_ is "from":
540
+ elif tmp_ is 'from':
542
541
  return await import_(True)
543
- elif tmp_ is "import":
542
+ elif tmp_ is 'import':
544
543
  return await import_(False)
545
- elif tmp_ is "class":
544
+ elif tmp_ is 'class':
546
545
  return await class_()
547
- elif tmp_ is "async":
546
+ elif tmp_ is 'async':
548
547
  if not is_('keyword', 'def'):
549
548
  croak("Expected 'def' after 'async'")
550
549
  next()
@@ -561,7 +560,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
561
560
  'body': chain,
562
561
  'end': prev()
563
562
  })
564
- elif tmp_ is "def":
563
+ elif tmp_ is 'def':
565
564
  start = prev()
566
565
  func = await function_(S.in_class[-1], False)
567
566
  func.start = start
@@ -582,13 +581,13 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
582
581
  if is_('punc', ','):
583
582
  next()
584
583
  msg = await expression(False)
585
- return new AST_Assert({'start': start, 'condition':cond, 'message':msg, 'end':prev()})
586
- elif tmp_ is "if":
584
+ return new AST_Assert({'start': start, 'condition': cond, 'message': msg, 'end': prev()})
585
+ elif tmp_ is 'if':
587
586
  return await if_()
588
- elif tmp_ is "pass":
587
+ elif tmp_ is 'pass':
589
588
  semicolon()
590
- return new AST_EmptyStatement({'stype':'pass', 'start':prev(), 'end':prev()})
591
- elif tmp_ is "return":
589
+ return new AST_EmptyStatement({'stype': 'pass', 'start': prev(), 'end': prev()})
590
+ elif tmp_ is 'return':
592
591
  if S.in_function is 0:
593
592
  croak("'return' outside of function")
594
593
  if S.functions[-1].is_generator:
@@ -596,21 +595,21 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
596
595
  S.functions[-1].is_generator = False
597
596
 
598
597
  ret_val = await return_()
599
- return new AST_Return({'value':ret_val})
600
- elif tmp_ is "await":
598
+ return new AST_Return({'value': ret_val})
599
+ elif tmp_ is 'await':
601
600
  if S.in_function is 0 or not S.functions[-1].is_async:
602
601
  croak("'await' outside of async function")
603
602
  value = await expr_atom(True)
604
603
  node = new AST_Await({'value': value})
605
604
  semicolon()
606
605
  return new AST_SimpleStatement({'body': node})
607
- elif tmp_ is "yield":
606
+ elif tmp_ is 'yield':
608
607
  return await yield_()
609
- elif tmp_ is "raise":
608
+ elif tmp_ is 'raise':
610
609
  if S.token.nlb:
611
610
  return new AST_Throw({
612
611
  'value': new AST_SymbolCatch({
613
- 'name': "ρσ_Exception"
612
+ 'name': 'ρσ_Exception'
614
613
  })
615
614
  })
616
615
 
@@ -619,9 +618,9 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
619
618
  return new AST_Throw({
620
619
  'value': tmp
621
620
  })
622
- elif tmp_ is "try":
621
+ elif tmp_ is 'try':
623
622
  return await try_()
624
- elif tmp_ is "nonlocal":
623
+ elif tmp_ is 'nonlocal':
625
624
  tmp = await nonlocal_()
626
625
  semicolon()
627
626
  return tmp
@@ -629,7 +628,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
629
628
  tmp = await nonlocal_(True)
630
629
  semicolon()
631
630
  return tmp
632
- elif tmp_ is "with":
631
+ elif tmp_ is 'with':
633
632
  return await with_()
634
633
  else:
635
634
  unexpected()
@@ -645,7 +644,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
645
644
  if is_('keyword', 'as'):
646
645
  next()
647
646
  alias = as_symbol(AST_SymbolAlias)
648
- clauses.push(new AST_WithClause({'expression':expr, 'alias':alias}))
647
+ clauses.push(new AST_WithClause({'expression': expr, 'alias': alias}))
649
648
  if is_('punc', ','):
650
649
  next()
651
650
  continue
@@ -671,7 +670,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
671
670
 
672
671
  def break_cont(t):
673
672
  if S.in_loop is 0:
674
- croak(t.name.slice(4) + " not inside a loop or switch")
673
+ croak(t.name.slice(4) + ' not inside a loop or switch')
675
674
  semicolon()
676
675
  return new t()
677
676
 
@@ -687,12 +686,12 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
687
686
  if is_yield_from:
688
687
  next()
689
688
  yld_val = await return_()
690
- return new AST_Yield({'is_yield_from':is_yield_from, 'value': yld_val})
689
+ return new AST_Yield({'is_yield_from': is_yield_from, 'value': yld_val})
691
690
 
692
691
  async def for_(list_comp):
693
692
  # expect("(")
694
693
  init = None
695
- if not is_("punc", ";"):
694
+ if not is_('punc', ';'):
696
695
  init = await expression(True, True)
697
696
  # standardize AST_Seq into array now for consistency
698
697
  if is_node_type(init, AST_Seq):
@@ -707,9 +706,9 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
707
706
  'end': init.end
708
707
  })
709
708
 
710
- if is_("operator", "in"):
709
+ if is_('operator', 'in'):
711
710
  if is_node_type(init, AST_Var) and init.definitions.length > 1:
712
- croak("Only one variable declaration allowed in for..in loop")
711
+ croak('Only one variable declaration allowed in for..in loop')
713
712
  next()
714
713
  return await for_in(init, list_comp)
715
714
 
@@ -758,7 +757,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
758
757
  return ERROR_CLASSES[expr.name]
759
758
 
760
759
  # traverse in reverse to check local variables first
761
- for s in range(S.classes.length-1, -1, -1):
760
+ for s in range(S.classes.length - 1, -1, -1):
762
761
  if has_prop(S.classes[s], expr.name):
763
762
  return S.classes[s][expr.name]
764
763
 
@@ -773,7 +772,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
773
772
  # now 'referenced_path' should contain the full path of potential class
774
773
  if len(referenced_path) > 1:
775
774
  class_name = referenced_path.join('.')
776
- for s in range(S.classes.length-1, -1, -1):
775
+ for s in range(S.classes.length - 1, -1, -1):
777
776
  if has_prop(S.classes[s], class_name):
778
777
  return S.classes[s][class_name]
779
778
  return False
@@ -802,6 +801,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
802
801
  # Use a single-element list to capture the resolve function from the Promise
803
802
  # executor without needing nonlocal (mutating a container, not rebinding).
804
803
  _rfn = v'[null]'
804
+
805
805
  def _capture_resolve(resolve):
806
806
  _rfn[0] = resolve
807
807
  loading_promises[key] = new Promise(_capture_resolve)
@@ -813,8 +813,8 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
813
813
  await do_import(package_module_id)
814
814
 
815
815
  if options.for_linting:
816
- imported_modules[key] = {'is_cached':True, 'classes':{}, 'module_id':key, 'exports':[],
817
- 'nonlocalvars':[], 'baselib':{}, 'outputs':{}, 'discard_asserts':options.discard_asserts}
816
+ imported_modules[key] = {'is_cached': True, 'classes': {}, 'module_id': key, 'exports': [],
817
+ 'nonlocalvars': [], 'baselib': {}, 'outputs': {}, 'discard_asserts': options.discard_asserts}
818
818
  return
819
819
 
820
820
  # stat_file returns {mtimeMs, content?}. For real filesystems mtimeMs is a
@@ -927,7 +927,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
927
927
  baselib_items[bitem] = True
928
928
 
929
929
  def read_python_flags():
930
- expect_token("keyword", "import")
930
+ expect_token('keyword', 'import')
931
931
  bracketed = is_('punc', '(')
932
932
  if bracketed:
933
933
  next()
@@ -951,15 +951,15 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
951
951
  else:
952
952
  continue
953
953
  break
954
- return new AST_EmptyStatement({'stype':'scoped_flags', 'start':prev(), 'end':prev()})
954
+ return new AST_EmptyStatement({'stype': 'scoped_flags', 'start': prev(), 'end': prev()})
955
955
 
956
956
  async def import_(from_import):
957
- ans = new AST_Imports({'imports':[]})
957
+ ans = new AST_Imports({'imports': []})
958
958
  while True:
959
959
  tok = tmp = name = last_tok = await expression(False)
960
960
  key = ''
961
961
  while is_node_type(tmp, AST_Dot):
962
- key = "." + tmp.property + key
962
+ key = '.' + tmp.property + key
963
963
  tmp = last_tok = tmp.expression
964
964
  key = tmp.name + key
965
965
  if from_import and key is '__python__':
@@ -972,8 +972,8 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
972
972
  'module': name,
973
973
  'key': key,
974
974
  'alias': alias,
975
- 'argnames':None,
976
- 'body':def():
975
+ 'argnames': None,
976
+ 'body': def ():
977
977
  return imported_modules[key]
978
978
  })
979
979
  aimp.start, aimp.end = tok.start, last_tok.end
@@ -991,7 +991,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
991
991
  imported_module_ids.push(imp.key)
992
992
  classes = imported_modules[key].classes
993
993
  if from_import:
994
- expect_token("keyword", "import")
994
+ expect_token('keyword', 'import')
995
995
  imp.argnames = argnames = []
996
996
  bracketed = is_('punc', '(')
997
997
  if bracketed:
@@ -1022,12 +1022,12 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1022
1022
  obj = classes[argvar.name]
1023
1023
  if obj:
1024
1024
  key = argvar.alias.name if argvar.alias else argvar.name
1025
- S.classes[-1][key] = { "static": obj.static, 'bound': obj.bound, 'classvars': obj.classvars }
1025
+ S.classes[-1][key] = {'static': obj.static, 'bound': obj.bound, 'classvars': obj.classvars}
1026
1026
  else:
1027
1027
  for cname in Object.keys(classes):
1028
1028
  obj = classes[cname]
1029
1029
  key = imp.alias.name if imp.alias else imp.key
1030
- S.classes[-1][key + '.' + obj.name.name] = { 'static': obj.static, 'bound': obj.bound, 'classvars': obj.classvars }
1030
+ S.classes[-1][key + '.' + obj.name.name] = {'static': obj.static, 'bound': obj.bound, 'classvars': obj.classvars}
1031
1031
 
1032
1032
  return ans
1033
1033
 
@@ -1040,7 +1040,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1040
1040
  externaldecorator = has_simple_decorator(S.decorators, 'external')
1041
1041
 
1042
1042
  class_details = {
1043
- "static": {},
1043
+ 'static': {},
1044
1044
  'bound': v'[]',
1045
1045
  'classvars': {},
1046
1046
  'processing': name.name,
@@ -1050,7 +1050,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1050
1050
  class_parent = None
1051
1051
 
1052
1052
  # read the bases of the class, if any
1053
- if is_("punc", "("):
1053
+ if is_('punc', '('):
1054
1054
  S.in_parenthesized_expr = True
1055
1055
  next()
1056
1056
  while True:
@@ -1067,7 +1067,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1067
1067
  continue
1068
1068
 
1069
1069
  docstrings = v'[]'
1070
- cls_decorators = (def():
1070
+ cls_decorators = (def ():
1071
1071
  d = []
1072
1072
  for decorator in S.decorators:
1073
1073
  d.push(new AST_Decorator({
@@ -1076,7 +1076,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1076
1076
  S.decorators = v'[]'
1077
1077
  return d
1078
1078
  )()
1079
- cls_body = await (async def(loop, labels):
1079
+ cls_body = await (async def (loop, labels):
1080
1080
  # navigate to correct location in the module tree and append the class
1081
1081
  S.in_class.push(name.name)
1082
1082
  S.classes[S.classes.length - 1][name.name] = class_details
@@ -1097,7 +1097,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1097
1097
  definition = new AST_Class({
1098
1098
  'name': name,
1099
1099
  'docstrings': docstrings,
1100
- 'module_id':module_id,
1100
+ 'module_id': module_id,
1101
1101
  'dynamic_properties': Object.create(None),
1102
1102
  'parent': class_parent,
1103
1103
  'bases': bases,
@@ -1119,10 +1119,11 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1119
1119
  if not descriptor:
1120
1120
  descriptor = definition.dynamic_properties[stmt.name.name] = {}
1121
1121
  descriptor['getter' if stmt.is_getter else 'setter'] = stmt
1122
- elif stmt.name.name is "__init__":
1122
+ elif stmt.name.name is '__init__':
1123
1123
  definition.init = stmt
1124
1124
  # find the class variables
1125
1125
  class_var_names = {}
1126
+
1126
1127
  # Ensure that if a class variable refers to another class variable in
1127
1128
  # its initialization, the referenced variables' names is correctly
1128
1129
  # mangled.
@@ -1140,7 +1141,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1140
1141
  class_var_names[varname] = True
1141
1142
  definition.classvars[varname] = True
1142
1143
  elif is_node_type(node, AST_SymbolRef) and has_prop(class_var_names, node.name):
1143
- node.thedef = new AST_SymbolDefun({'name':name.name + '.prototype.' + node.name})
1144
+ node.thedef = new AST_SymbolDefun({'name': name.name + '.prototype.' + node.name})
1144
1145
  if descend:
1145
1146
  descend.call(node)
1146
1147
  this._visit = visit_node
@@ -1168,17 +1169,17 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1168
1169
  croak('A method cannot be both static and a property getter/setter')
1169
1170
  S.classes[S.classes.length - 2][in_class].static[name.name] = True
1170
1171
  staticmethod = True
1171
- elif name.name is not "__init__" and S.scoped_flags.get('bound_methods'):
1172
+ elif name.name is not '__init__' and S.scoped_flags.get('bound_methods'):
1172
1173
  S.classes[S.classes.length - 2][in_class].bound.push(name.name)
1173
1174
 
1174
- expect("(")
1175
+ expect('(')
1175
1176
  S.in_parenthesized_expr = True
1176
1177
  ctor = AST_Method if in_class else AST_Function
1177
1178
  return_annotation = None
1178
1179
  is_generator = v'[]'
1179
1180
  docstrings = v'[]'
1180
1181
 
1181
- fn_argnames = await (async def():
1182
+ fn_argnames = await (async def ():
1182
1183
  a = v'[]'
1183
1184
  starargs_sym = undefined
1184
1185
  kwargs_sym = undefined
@@ -1189,7 +1190,6 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1189
1190
  def_line = S.input.context().tokline
1190
1191
  current_arg_name = None
1191
1192
  name_token = None
1192
-
1193
1193
  async def get_arg():
1194
1194
  nonlocal current_arg_name, name_token
1195
1195
  current_arg_name = S.token.value
@@ -1207,18 +1207,16 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1207
1207
  next()
1208
1208
  expect(':')
1209
1209
  annotation = await maybe_conditional()
1210
-
1211
1210
  # and now, do as_symbol without the next() at the end
1212
1211
  # since we are already at the next comma (or end bracket)
1213
- if not is_token(name_token, "name"):
1212
+ if not is_token(name_token, 'name'):
1214
1213
  # assuming the previous context in case
1215
1214
  # the annotation was over the line
1216
1215
  if S.input.context().tokline is not def_line:
1217
- croak("Name expected", name_ctx.tokline)
1216
+ croak('Name expected', name_ctx.tokline)
1218
1217
  else:
1219
- croak("Name expected")
1218
+ croak('Name expected')
1220
1219
  return None
1221
-
1222
1220
  sym = new AST_SymbolFunarg({
1223
1221
  'name': name_token.value,
1224
1222
  'start': S.token,
@@ -1227,15 +1225,14 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1227
1225
  })
1228
1226
  return sym
1229
1227
  else:
1230
- if not is_("name"):
1228
+ if not is_('name'):
1231
1229
  # there is no name, which is an error we should report on the
1232
1230
  # same line as the definition, so move to that is we're not already there.
1233
1231
  if S.input.context().tokline is not def_line:
1234
- croak("Name expected", def_line)
1232
+ croak('Name expected', def_line)
1235
1233
  else:
1236
- croak("Name expected")
1234
+ croak('Name expected')
1237
1235
  return None
1238
-
1239
1236
  sym = new AST_SymbolFunarg({
1240
1237
  'name': current_arg_name,
1241
1238
  'start': S.token,
@@ -1244,12 +1241,11 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1244
1241
  })
1245
1242
  next()
1246
1243
  return sym
1247
-
1248
- while not is_("punc", ")"):
1244
+ while not is_('punc', ')'):
1249
1245
  if first:
1250
1246
  first = False
1251
1247
  else:
1252
- expect(",")
1248
+ expect(',')
1253
1249
  if is_('punc', ')'):
1254
1250
  break
1255
1251
  if is_('operator', '**'):
@@ -1270,7 +1266,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1270
1266
  if starargs_sym or kwargs_sym:
1271
1267
  token_error(name_token, "Can't define a formal parameter after *args or **kwargs")
1272
1268
  a.push(await get_arg())
1273
- if is_("operator", "="):
1269
+ if is_('operator', '='):
1274
1270
  if kwargs_sym:
1275
1271
  token_error(name_token, "Can't define an optional formal parameter after **kwargs")
1276
1272
  next()
@@ -1279,10 +1275,9 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1279
1275
  else:
1280
1276
  if has_defaults:
1281
1277
  token_error(name_token, "Can't define required formal parameters after optional formal parameters")
1282
-
1283
1278
  next()
1284
1279
  # check if we have a return type annotation
1285
- if is_("punc", "->"):
1280
+ if is_('punc', '->'):
1286
1281
  next()
1287
1282
  nonlocal return_annotation
1288
1283
  return_annotation = await maybe_conditional()
@@ -1297,7 +1292,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1297
1292
  })
1298
1293
  )()
1299
1294
 
1300
- fn_decorators = (def():
1295
+ fn_decorators = (def ():
1301
1296
  d = v'[]'
1302
1297
  for decorator in S.decorators:
1303
1298
  d.push(new AST_Decorator({
@@ -1307,7 +1302,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1307
1302
  return d
1308
1303
  )()
1309
1304
 
1310
- fn_body = await (async def(loop, labels):
1305
+ fn_body = await (async def (loop, labels):
1311
1306
  S.in_class.push(False)
1312
1307
  S.classes.push({})
1313
1308
  S.scoped_flags.push()
@@ -1360,7 +1355,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1360
1355
  # detect local variables, strip function arguments
1361
1356
  assignments = scan_for_local_vars(definition.body)
1362
1357
  for i in range(assignments.length):
1363
- for j in range(definition.argnames.args.length+1):
1358
+ for j in range(definition.argnames.args.length + 1):
1364
1359
  if j is definition.argnames.args.length:
1365
1360
  definition.localvars.push(new_symbol(AST_SymbolVar, assignments[i]))
1366
1361
  elif j < definition.argnames.args.length and assignments[i] is definition.argnames.args[j].name:
@@ -1368,18 +1363,18 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1368
1363
 
1369
1364
  nonlocals = scan_for_nonlocal_defs(definition.body)
1370
1365
  nonlocals = {name for name in nonlocals}
1371
- definition.localvars = definition.localvars.filter(def(v): return not nonlocals.has(v.name);)
1366
+ definition.localvars = definition.localvars.filter(def (v): return not nonlocals.has(v.name);)
1372
1367
  return definition
1373
1368
 
1374
1369
  async def if_():
1375
1370
  cond = await expression(True)
1376
1371
  body = await statement()
1377
1372
  belse = None
1378
- if is_("keyword", "elif") or is_("keyword", "else"):
1379
- if is_("keyword", "else"):
1373
+ if is_('keyword', 'elif') or is_('keyword', 'else'):
1374
+ if is_('keyword', 'else'):
1380
1375
  next()
1381
1376
  else:
1382
- S.token.value = "if"
1377
+ S.token.value = 'if'
1383
1378
  # effectively converts 'elif' to 'else if'
1384
1379
  belse = await statement()
1385
1380
 
@@ -1397,11 +1392,11 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1397
1392
 
1398
1393
  async def block_(docstrings):
1399
1394
  prev_whitespace = S.token.leading_whitespace
1400
- expect(":")
1395
+ expect(':')
1401
1396
  a = v'[]'
1402
1397
  if not S.token.nlb:
1403
1398
  while not S.token.nlb:
1404
- if is_("eof"):
1399
+ if is_('eof'):
1405
1400
  if options.recover_errors:
1406
1401
  break
1407
1402
  unexpected()
@@ -1426,8 +1421,8 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1426
1421
  current_whitespace = S.token.leading_whitespace
1427
1422
  if current_whitespace.length is 0 or prev_whitespace is current_whitespace:
1428
1423
  croak('Expected an indented block')
1429
- while not is_("punc", "}"):
1430
- if is_("eof"):
1424
+ while not is_('punc', '}'):
1425
+ if is_('eof'):
1431
1426
  # end of file, terminate block automatically
1432
1427
  return a
1433
1428
  if options.recover_errors:
@@ -1455,18 +1450,18 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1455
1450
  bcatch = v'[]'
1456
1451
  bfinally = None
1457
1452
  belse = None
1458
- while is_("keyword", "except"):
1453
+ while is_('keyword', 'except'):
1459
1454
  start = S.token
1460
1455
  next()
1461
1456
  exceptions = []
1462
- if not is_("punc", ":") and not is_("keyword", "as"):
1457
+ if not is_('punc', ':') and not is_('keyword', 'as'):
1463
1458
  exceptions.push(as_symbol(AST_SymbolVar))
1464
- while is_("punc", ","):
1459
+ while is_('punc', ','):
1465
1460
  next()
1466
1461
  exceptions.push(as_symbol(AST_SymbolVar))
1467
1462
 
1468
1463
  name = None
1469
- if is_("keyword", "as"):
1464
+ if is_('keyword', 'as'):
1470
1465
  next()
1471
1466
  name = as_symbol(AST_SymbolCatch)
1472
1467
 
@@ -1479,7 +1474,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1479
1474
  'end': prev()
1480
1475
  }))
1481
1476
 
1482
- if is_("keyword", "else"):
1477
+ if is_('keyword', 'else'):
1483
1478
  start = S.token
1484
1479
  next()
1485
1480
  belse_body = await block_()
@@ -1489,7 +1484,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1489
1484
  'end': prev()
1490
1485
  })
1491
1486
 
1492
- if is_("keyword", "finally"):
1487
+ if is_('keyword', 'finally'):
1493
1488
  start = S.token
1494
1489
  next()
1495
1490
  bfinally_body = await block_()
@@ -1500,11 +1495,11 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1500
1495
  })
1501
1496
 
1502
1497
  if not bcatch.length and not bfinally:
1503
- croak("Missing except/finally blocks")
1498
+ croak('Missing except/finally blocks')
1504
1499
 
1505
1500
  return new AST_Try({
1506
1501
  'body': body,
1507
- 'bcatch': (new AST_Catch({ 'body': bcatch }) if bcatch.length else None),
1502
+ 'bcatch': (new AST_Catch({'body': bcatch}) if bcatch.length else None),
1508
1503
  'bfinally': bfinally,
1509
1504
  'belse': belse
1510
1505
  })
@@ -1525,7 +1520,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1525
1520
  'value': varval,
1526
1521
  'end': prev()
1527
1522
  }))
1528
- if not is_("punc", ","):
1523
+ if not is_('punc', ','):
1529
1524
  break
1530
1525
  next()
1531
1526
 
@@ -1544,10 +1539,10 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1544
1539
 
1545
1540
  async def new_():
1546
1541
  start = S.token
1547
- expect_token("operator", "new")
1542
+ expect_token('operator', 'new')
1548
1543
  newexp = await expr_atom(False)
1549
1544
 
1550
- if is_("punc", "("):
1545
+ if is_('punc', '('):
1551
1546
  S.in_parenthesized_expr = True
1552
1547
  next()
1553
1548
  args = await func_call_list()
@@ -1578,40 +1573,40 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1578
1573
  def token_as_atom_node():
1579
1574
  tok = S.token
1580
1575
  tmp_ = tok.type
1581
- if tmp_ is "name":
1576
+ if tmp_ is 'name':
1582
1577
  return token_as_symbol(tok, AST_SymbolRef)
1583
- elif tmp_ is "num":
1578
+ elif tmp_ is 'num':
1584
1579
  return new AST_Number({
1585
1580
  'start': tok,
1586
1581
  'end': tok,
1587
1582
  'value': tok.value
1588
1583
  })
1589
- elif tmp_ is "string":
1584
+ elif tmp_ is 'string':
1590
1585
  return string_()
1591
- elif tmp_ is "regexp":
1586
+ elif tmp_ is 'regexp':
1592
1587
  return new AST_RegExp({
1593
1588
  'start': tok,
1594
1589
  'end': tok,
1595
1590
  'value': tok.value
1596
1591
  })
1597
- elif tmp_ is "atom":
1592
+ elif tmp_ is 'atom':
1598
1593
  tmp__ = tok.value
1599
- if tmp__ is "False":
1594
+ if tmp__ is 'False':
1600
1595
  return new AST_False({
1601
1596
  'start': tok,
1602
1597
  'end': tok
1603
1598
  })
1604
- elif tmp__ is "True":
1599
+ elif tmp__ is 'True':
1605
1600
  return new AST_True({
1606
1601
  'start': tok,
1607
1602
  'end': tok
1608
1603
  })
1609
- elif tmp__ is "None":
1604
+ elif tmp__ is 'None':
1610
1605
  return new AST_Null({
1611
1606
  'start': tok,
1612
1607
  'end': tok
1613
1608
  })
1614
- elif tmp_ is "js":
1609
+ elif tmp_ is 'js':
1615
1610
  return new AST_Verbatim({
1616
1611
  'start': tok,
1617
1612
  'end': tok,
@@ -1625,18 +1620,18 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1625
1620
  return ret
1626
1621
 
1627
1622
  async def expr_atom(allow_calls):
1628
- if is_("operator", "new"):
1623
+ if is_('operator', 'new'):
1629
1624
  return await new_()
1630
1625
 
1631
1626
  start = S.token
1632
- if is_("punc"):
1627
+ if is_('punc'):
1633
1628
  tmp_ = start.value
1634
- if tmp_ is "(":
1629
+ if tmp_ is '(':
1635
1630
  S.in_parenthesized_expr = True
1636
1631
  next()
1637
1632
  if is_('punc', ')'):
1638
1633
  next()
1639
- return new AST_Array({'elements':[]})
1634
+ return new AST_Array({'elements': []})
1640
1635
  ex = await expression(True)
1641
1636
  if is_('keyword', 'for'):
1642
1637
  ret = await read_comprehension(new AST_GeneratorComprehension({'statement': ex}), ')')
@@ -1647,28 +1642,28 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1647
1642
  if is_node_type(ex, AST_SymbolRef):
1648
1643
  ex.parens = True
1649
1644
  if not is_node_type(ex, AST_GeneratorComprehension):
1650
- expect(")")
1645
+ expect(')')
1651
1646
  if is_node_type(ex, AST_UnaryPrefix):
1652
1647
  ex.parenthesized = True
1653
1648
  S.in_parenthesized_expr = False
1654
1649
  return await subscripts(ex, allow_calls)
1655
- elif tmp_ is "[":
1650
+ elif tmp_ is '[':
1656
1651
  return await subscripts(await array_(), allow_calls)
1657
- elif tmp_ is "{":
1652
+ elif tmp_ is '{':
1658
1653
  return await subscripts(await object_(), allow_calls)
1659
1654
 
1660
1655
  unexpected()
1661
1656
 
1662
- if is_("keyword", "class"):
1657
+ if is_('keyword', 'class'):
1663
1658
  next()
1664
1659
  cls = await class_()
1665
1660
  cls.start = start
1666
1661
  cls.end = prev()
1667
1662
  return await subscripts(cls, allow_calls)
1668
1663
 
1669
- if is_("keyword", "async"):
1664
+ if is_('keyword', 'async'):
1670
1665
  next()
1671
- if not is_("keyword", "def"):
1666
+ if not is_('keyword', 'def'):
1672
1667
  croak("Expected 'def' after 'async'")
1673
1668
  next()
1674
1669
  func = await function_(False, True, True)
@@ -1676,7 +1671,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1676
1671
  func.end = prev()
1677
1672
  return await subscripts(func, allow_calls)
1678
1673
 
1679
- if is_("keyword", "def"):
1674
+ if is_('keyword', 'def'):
1680
1675
  next()
1681
1676
  func = await function_(False, True)
1682
1677
  func.start = start
@@ -1703,22 +1698,22 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1703
1698
  first = True
1704
1699
  a = []
1705
1700
  saw_starargs = False
1706
- while not is_("punc", closing):
1701
+ while not is_('punc', closing):
1707
1702
  if saw_starargs:
1708
- token_error(prev(), "*args must be the last argument in a function call")
1703
+ token_error(prev(), '*args must be the last argument in a function call')
1709
1704
 
1710
1705
  if first:
1711
1706
  first = False
1712
1707
  else:
1713
- expect(",")
1714
- if allow_trailing_comma and is_("punc", closing):
1708
+ expect(',')
1709
+ if allow_trailing_comma and is_('punc', closing):
1715
1710
  break
1716
1711
 
1717
- if is_("operator", "*") and func_call:
1712
+ if is_('operator', '*') and func_call:
1718
1713
  saw_starargs = True
1719
1714
  next()
1720
1715
 
1721
- if is_("punc", ",") and allow_empty:
1716
+ if is_('punc', ',') and allow_empty:
1722
1717
  a.push(new AST_Hole({
1723
1718
  'start': S.token,
1724
1719
  'end': S.token
@@ -1747,9 +1742,9 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1747
1742
  if empty:
1748
1743
  return new AST_CallArgs({'args': a, 'kwargs': kwargs, 'kwarg_items': kwarg_items, 'starargs': starargs})
1749
1744
  single_comprehension = False
1750
- while not is_("punc", ')') and not is_('eof'):
1745
+ while not is_('punc', ')') and not is_('eof'):
1751
1746
  if not first:
1752
- expect(",")
1747
+ expect(',')
1753
1748
  if is_('punc', ')'):
1754
1749
  break
1755
1750
  if is_('operator', '*'):
@@ -1781,34 +1776,34 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1781
1776
 
1782
1777
  @embed_tokens
1783
1778
  async def array_():
1784
- expect("[")
1779
+ expect('[')
1785
1780
  expr = []
1786
- if not is_("punc", "]"):
1781
+ if not is_('punc', ']'):
1787
1782
  expr.push(await expression(False))
1788
- if is_("keyword", "for"):
1783
+ if is_('keyword', 'for'):
1789
1784
  # list comprehension
1790
1785
  return await read_comprehension(new AST_ListComprehension({'statement': expr[0]}), ']')
1791
1786
 
1792
- if not is_("punc", "]"):
1793
- expect(",")
1787
+ if not is_('punc', ']'):
1788
+ expect(',')
1794
1789
 
1795
- arr_rest = await expr_list("]", True, True)
1790
+ arr_rest = await expr_list(']', True, True)
1796
1791
  return new AST_Array({
1797
1792
  'elements': expr.concat(arr_rest)
1798
1793
  })
1799
1794
 
1800
1795
  @embed_tokens
1801
1796
  async def object_():
1802
- expect("{")
1797
+ expect('{')
1803
1798
  first = True
1804
1799
  has_non_const_keys = False
1805
1800
  is_pydict = S.scoped_flags.get('dict_literals', False)
1806
1801
  is_jshash = S.scoped_flags.get('hash_literals', False)
1807
1802
  a = []
1808
- while not is_("punc", "}"):
1803
+ while not is_('punc', '}'):
1809
1804
  if not first:
1810
- expect(",")
1811
- if is_("punc", "}"):
1805
+ expect(',')
1806
+ if is_('punc', '}'):
1812
1807
  # allow trailing comma
1813
1808
  break
1814
1809
  first = False
@@ -1823,13 +1818,13 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1823
1818
  ctx.expecting_object_literal_key = orig
1824
1819
  if is_('keyword', 'for'):
1825
1820
  # is_pydict is irrelevant here
1826
- return await read_comprehension(new AST_SetComprehension({'statement':left}), '}')
1821
+ return await read_comprehension(new AST_SetComprehension({'statement': left}), '}')
1827
1822
  if a.length is 0 and (is_('punc', ',') or is_('punc', '}')):
1828
1823
  end = prev()
1829
1824
  return await set_(start, end, left)
1830
1825
  if not is_node_type(left, AST_Constant):
1831
1826
  has_non_const_keys = True
1832
- expect(":")
1827
+ expect(':')
1833
1828
  obj_val = await expression(False)
1834
1829
  a.push(new AST_ObjectKeyVal({
1835
1830
  'start': start,
@@ -1849,17 +1844,17 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1849
1844
 
1850
1845
  async def set_(start, end, expr):
1851
1846
  ostart = start
1852
- a = [new AST_SetItem({'start':start, 'end':end, 'value':expr})]
1853
- while not is_("punc", "}"):
1854
- expect(",")
1847
+ a = [new AST_SetItem({'start': start, 'end': end, 'value': expr})]
1848
+ while not is_('punc', '}'):
1849
+ expect(',')
1855
1850
  start = S.token
1856
- if is_("punc", "}"):
1851
+ if is_('punc', '}'):
1857
1852
  # allow trailing comma
1858
1853
  break
1859
1854
  set_val = await expression(False)
1860
- a.push(new AST_SetItem({'start':start, 'value':set_val, 'end':prev()}))
1855
+ a.push(new AST_SetItem({'start': start, 'value': set_val, 'end': prev()}))
1861
1856
  next()
1862
- return new AST_Set({'items':a, 'start':ostart, 'end':prev()})
1857
+ return new AST_Set({'items': a, 'start': ostart, 'end': prev()})
1863
1858
 
1864
1859
  async def read_comprehension(obj, terminator):
1865
1860
  if is_node_type(obj, AST_GeneratorComprehension):
@@ -1874,7 +1869,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1874
1869
  if is_('punc', terminator):
1875
1870
  obj.condition = None
1876
1871
  else:
1877
- expect_token("keyword", "if")
1872
+ expect_token('keyword', 'if')
1878
1873
  obj.condition = await expression(True)
1879
1874
  expect(terminator)
1880
1875
  S.in_comprehension = False
@@ -1886,16 +1881,19 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1886
1881
  else:
1887
1882
  left = await expression(False)
1888
1883
  if not is_('punc', ':'):
1889
- return await read_comprehension(new AST_SetComprehension({'statement':left}), '}')
1884
+ return await read_comprehension(new AST_SetComprehension({'statement': left}), '}')
1890
1885
  expect(':')
1891
1886
  right = await expression(False)
1892
- return await read_comprehension(new AST_DictComprehension({'statement':left, 'value_statement':right, 'is_pydict':is_pydict, 'is_jshash':is_jshash}), '}')
1887
+ return await read_comprehension(
1888
+ new AST_DictComprehension({'statement': left, 'value_statement': right, 'is_pydict': is_pydict, 'is_jshash': is_jshash}),
1889
+ '}'
1890
+ )
1893
1891
 
1894
1892
  def as_name():
1895
1893
  tmp = S.token
1896
1894
  next()
1897
1895
  tmp_ = tmp.type
1898
- if tmp_ is "name" or tmp_ is "operator" or tmp_ is "keyword" or tmp_ is "atom":
1896
+ if tmp_ is 'name' or tmp_ is 'operator' or tmp_ is 'keyword' or tmp_ is 'atom':
1899
1897
  return tmp.value
1900
1898
  else:
1901
1899
  unexpected()
@@ -1911,9 +1909,9 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1911
1909
  })
1912
1910
 
1913
1911
  def as_symbol(ttype, noerror):
1914
- if not is_("name"):
1912
+ if not is_('name'):
1915
1913
  if not noerror:
1916
- croak("Name expected")
1914
+ croak('Name expected')
1917
1915
  return None
1918
1916
 
1919
1917
  sym = token_as_symbol(S.token, ttype)
@@ -1941,33 +1939,33 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1941
1939
  is_py_sub = S.scoped_flags.get('overload_getitem', False)
1942
1940
  slice_bounds = v'[]'
1943
1941
  is_slice = False
1944
- if is_("punc", ":"):
1942
+ if is_('punc', ':'):
1945
1943
  # slice [:n]
1946
1944
  slice_bounds.push(None)
1947
1945
  else:
1948
1946
  slice_bounds.push(await expression(False))
1949
1947
 
1950
- if is_("punc", ":"):
1948
+ if is_('punc', ':'):
1951
1949
  # slice [n:m?]
1952
1950
  is_slice = True
1953
1951
  next()
1954
- if is_("punc", ":"):
1952
+ if is_('punc', ':'):
1955
1953
  slice_bounds.push(None)
1956
- elif not is_("punc", "]"):
1954
+ elif not is_('punc', ']'):
1957
1955
  slice_bounds.push(await expression(False))
1958
1956
 
1959
- if is_("punc", ":"):
1957
+ if is_('punc', ':'):
1960
1958
  # slice [n:m:o?]
1961
1959
  next()
1962
- if is_("punc", "]"):
1960
+ if is_('punc', ']'):
1963
1961
  unexpected()
1964
1962
  else:
1965
1963
  slice_bounds.push(await expression(False))
1966
1964
 
1967
- expect("]")
1965
+ expect(']')
1968
1966
 
1969
1967
  if is_slice:
1970
- if is_("operator", '='):
1968
+ if is_('operator', '='):
1971
1969
  # splice-assignment (arr[start:end] = ...)
1972
1970
  next() # swallow the assignment
1973
1971
  splice_assign = await expression(True)
@@ -1997,14 +1995,14 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
1997
1995
  return await subscripts(new AST_Call({
1998
1996
  'start': start,
1999
1997
  'expression': new AST_SymbolRef({
2000
- 'name': 'ρσ_delslice' if S.in_delete else "ρσ_eslice"
1998
+ 'name': 'ρσ_delslice' if S.in_delete else 'ρσ_eslice'
2001
1999
  }),
2002
2000
  'args': new AST_CallArgs({'args': _ca, 'kwargs': v'[]', 'kwarg_items': v'[]', 'starargs': False}),
2003
2001
  'end': prev()
2004
2002
  }), allow_calls)
2005
2003
  else:
2006
2004
  # regular slice (arr[start:end])
2007
- slice_bounds = [new AST_Number({'value':0}) if i is None else i for i in slice_bounds]
2005
+ slice_bounds = [new AST_Number({'value': 0}) if i is None else i for i in slice_bounds]
2008
2006
  if S.in_delete:
2009
2007
  _ca2 = v'[]'
2010
2008
  _ca2.push(new AST_CallArg({'value': expr, 'is_array': False}))
@@ -2026,7 +2024,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2026
2024
  'expression': new AST_Dot({
2027
2025
  'start': start,
2028
2026
  'expression': expr,
2029
- 'property': "slice",
2027
+ 'property': 'slice',
2030
2028
  'end': prev()
2031
2029
  }),
2032
2030
  'args': new AST_CallArgs({'args': _ca3, 'kwargs': v'[]', 'kwarg_items': v'[]', 'starargs': False}),
@@ -2037,7 +2035,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2037
2035
  if is_py_sub:
2038
2036
  assignment = None
2039
2037
  assign_operator = ''
2040
- if is_("operator") and ASSIGNMENT[S.token.value]:
2038
+ if is_('operator') and ASSIGNMENT[S.token.value]:
2041
2039
  assign_operator = S.token.value[:-1]
2042
2040
  next()
2043
2041
  assignment = await expression(True)
@@ -2047,7 +2045,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2047
2045
  'property': slice_bounds[0] or new AST_Number({
2048
2046
  'value': 0
2049
2047
  }),
2050
- 'assignment':assignment,
2048
+ 'assignment': assignment,
2051
2049
  'assign_operator': assign_operator,
2052
2050
  'end': prev()
2053
2051
  }), allow_calls)
@@ -2087,9 +2085,9 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2087
2085
  classcall_args = await func_call_list()
2088
2086
  ret = await subscripts(new AST_ClassCall({
2089
2087
  'start': start,
2090
- "class": expr.expression,
2088
+ 'class': expr.expression,
2091
2089
  'method': funcname.property,
2092
- "static": is_static_method(c, funcname.property),
2090
+ 'static': is_static_method(c, funcname.property),
2093
2091
  'args': classcall_args,
2094
2092
  'end': prev()
2095
2093
  }), True)
@@ -2097,17 +2095,17 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2097
2095
  return ret
2098
2096
  elif is_node_type(expr, AST_SymbolRef):
2099
2097
  tmp_ = expr.name
2100
- if tmp_ is "jstype":
2098
+ if tmp_ is 'jstype':
2101
2099
  jstype_args = await func_call_list()
2102
2100
  ret = new AST_UnaryPrefix({
2103
2101
  'start': start,
2104
- 'operator': "typeof",
2102
+ 'operator': 'typeof',
2105
2103
  'expression': jstype_args.args[0].value,
2106
2104
  'end': prev()
2107
2105
  })
2108
2106
  S.in_parenthesized_expr = False
2109
2107
  return ret
2110
- elif tmp_ is "isinstance":
2108
+ elif tmp_ is 'isinstance':
2111
2109
  args = await func_call_list()
2112
2110
  if args.args.length is not 2:
2113
2111
  croak('isinstance() must be called with exactly two arguments')
@@ -2149,7 +2147,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2149
2147
  }), allow_calls)
2150
2148
 
2151
2149
  async def existential(expr, allow_calls):
2152
- ans = new AST_Existential({'start':expr.start, 'end':S.token, 'expression':expr})
2150
+ ans = new AST_Existential({'start': expr.start, 'end': S.token, 'expression': expr})
2153
2151
  next()
2154
2152
  ttype = S.token.type
2155
2153
  val = S.token.value
@@ -2175,13 +2173,13 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2175
2173
  return ans
2176
2174
 
2177
2175
  async def subscripts(expr, allow_calls):
2178
- if is_("punc", "."):
2176
+ if is_('punc', '.'):
2179
2177
  return await get_attr(expr, allow_calls)
2180
2178
 
2181
- if is_("punc", "[") and not S.token.nlb:
2179
+ if is_('punc', '[') and not S.token.nlb:
2182
2180
  return await getitem(expr, allow_calls)
2183
2181
 
2184
- if allow_calls and is_("punc", "(") and not S.token.nlb:
2182
+ if allow_calls and is_('punc', '(') and not S.token.nlb:
2185
2183
  return await call_(expr)
2186
2184
 
2187
2185
  if is_('punc', '?'):
@@ -2199,8 +2197,8 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2199
2197
  expr = await expression()
2200
2198
  S.parsing_decorator = False
2201
2199
  S.decorators.push(expr)
2202
- return new AST_EmptyStatement({'stype':'@', 'start':prev(), 'end':prev()})
2203
- if is_("operator") and UNARY_PREFIX[start.value]:
2200
+ return new AST_EmptyStatement({'stype': '@', 'start': prev(), 'end': prev()})
2201
+ if is_('operator') and UNARY_PREFIX[start.value]:
2204
2202
  next()
2205
2203
  is_parenthesized = is_('punc', '(')
2206
2204
  S.in_delete = start.value is 'delete'
@@ -2223,11 +2221,11 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2223
2221
 
2224
2222
  async def expr_op(left, min_prec, no_in):
2225
2223
  op = S.token.value if is_('operator') else None
2226
- if op is "!" and peek().type is "operator" and peek().value is "in":
2224
+ if op is '!' and peek().type is 'operator' and peek().value is 'in':
2227
2225
  next()
2228
2226
  S.token.value = op = 'nin'
2229
2227
 
2230
- if no_in and (op is "in" or op is 'nin'):
2228
+ if no_in and (op is 'in' or op is 'nin'):
2231
2229
  op = None
2232
2230
 
2233
2231
  prec = PRECEDENCE[op] if op is not None else None
@@ -2287,7 +2285,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2287
2285
  start = S.token
2288
2286
  left = await maybe_conditional(no_in)
2289
2287
  val = S.token.value
2290
- if is_("operator") and ASSIGNMENT[val]:
2288
+ if is_('operator') and ASSIGNMENT[val]:
2291
2289
  if only_plain_assignment and val is not '=':
2292
2290
  croak('Invalid assignment operator for chained assignment: ' + val)
2293
2291
  next()
@@ -2306,6 +2304,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2306
2304
  # around it to allow for tuple packing/unpacking
2307
2305
  start = S.token
2308
2306
  expr = await maybe_assign(no_in)
2307
+
2309
2308
  def build_seq(a):
2310
2309
  if a.length is 1:
2311
2310
  return a[0]
@@ -2318,7 +2317,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2318
2317
  })
2319
2318
  if commas:
2320
2319
  left = v'[ expr ]'
2321
- while is_("punc", ",") and not peek().nlb:
2320
+ while is_('punc', ',') and (not peek().nlb or S.in_parenthesized_expr):
2322
2321
  next()
2323
2322
  if is_node_type(expr, AST_Assign):
2324
2323
  left[-1] = left[-1].left
@@ -2367,7 +2366,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2367
2366
  docstrings = v'[]'
2368
2367
  first_token = True
2369
2368
  toplevel = options.toplevel
2370
- while not is_("eof"):
2369
+ while not is_('eof'):
2371
2370
  if options.recover_errors:
2372
2371
  try:
2373
2372
  element = await statement()
@@ -2492,6 +2491,7 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2492
2491
  else:
2493
2492
  if not has_se:
2494
2493
  se_found = v'[false]'
2494
+
2495
2495
  def se_check(se_node, se_descend): # noqa
2496
2496
  if is_node_type(se_node, AST_Call):
2497
2497
  se_found[0] = True
@@ -2527,15 +2527,16 @@ def create_parser_ctx(S, import_dirs, module_id, baselib_items, imported_module_
2527
2527
 
2528
2528
  return run_parser
2529
2529
 
2530
+
2530
2531
  async def parse(text, options):
2531
2532
  options = defaults(options, {
2532
- 'filename': None, # name of the file being parsed
2533
- 'module_id':'__main__', # The id of the module being parsed
2533
+ 'filename': None, # name of the file being parsed
2534
+ 'module_id': '__main__', # The id of the module being parsed
2534
2535
  'toplevel': None,
2535
- 'for_linting': False, # If True certain actions are not performed, such as importing modules
2536
+ 'for_linting': False, # If True certain actions are not performed, such as importing modules
2536
2537
  'import_dirs': v'[]',
2537
- 'classes': undefined, # Map of class names to AST_Class that are available in the global namespace (used by the REPL)
2538
- 'scoped_flags': {}, # Global scoped flags (used by the REPL)
2538
+ 'classes': undefined, # Map of class names to AST_Class that are available in the global namespace (used by the REPL)
2539
+ 'scoped_flags': {}, # Global scoped flags (used by the REPL)
2539
2540
  'discard_asserts': False,
2540
2541
  'module_cache_dir': '',
2541
2542
  'recover_errors': False, # When True, continue parsing past syntax errors (used by the LSP). See run_parser/block_.
@@ -2568,9 +2569,9 @@ async def parse(text, options):
2568
2569
  'in_parenthesized_expr': False,
2569
2570
  'in_delete': False,
2570
2571
  'in_loop': 0,
2571
- 'in_class': [ False ],
2572
- 'classes': [ {} ],
2573
- 'functions': [ {} ],
2572
+ 'in_class': [False],
2573
+ 'classes': [{}],
2574
+ 'functions': [{}],
2574
2575
  'labels': [],
2575
2576
  'decorators': v'[]',
2576
2577
  'parsing_decorator': False,
@@ -2594,7 +2595,7 @@ async def parse(text, options):
2594
2595
  if options.classes:
2595
2596
  for cname in options.classes:
2596
2597
  obj = options.classes[cname]
2597
- S.classes[0][cname] = { 'static':obj.static, 'bound':obj.bound, 'classvars': obj.classvars }
2598
+ S.classes[0][cname] = {'static': obj.static, 'bound': obj.bound, 'classvars': obj.classvars}
2598
2599
 
2599
2600
  if jstype(text) is 'string' and not options._src_hash:
2600
2601
  options._src_hash = sha1sum(text)