pyscript-programming-language 1.12.0__py3-none-any.whl

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 (76) hide show
  1. pyscript/__init__.py +49 -0
  2. pyscript/__init__.pyi +96 -0
  3. pyscript/__main__.py +303 -0
  4. pyscript/core/__init__.py +61 -0
  5. pyscript/core/analyzer.py +531 -0
  6. pyscript/core/bases.py +2 -0
  7. pyscript/core/buffer.py +43 -0
  8. pyscript/core/cache.py +70 -0
  9. pyscript/core/checks.py +42 -0
  10. pyscript/core/constants.py +123 -0
  11. pyscript/core/context.py +63 -0
  12. pyscript/core/editor/__init__.py +15 -0
  13. pyscript/core/editor/bases.py +35 -0
  14. pyscript/core/editor/gui.py +144 -0
  15. pyscript/core/editor/terminal.py +175 -0
  16. pyscript/core/exceptions.py +123 -0
  17. pyscript/core/handlers.py +57 -0
  18. pyscript/core/highlight.py +552 -0
  19. pyscript/core/interpreter.py +1546 -0
  20. pyscript/core/lexer.py +863 -0
  21. pyscript/core/mapping.py +139 -0
  22. pyscript/core/nodes.py +663 -0
  23. pyscript/core/objects.py +213 -0
  24. pyscript/core/parser.py +2456 -0
  25. pyscript/core/position.py +114 -0
  26. pyscript/core/pysbuiltins.py +703 -0
  27. pyscript/core/results.py +186 -0
  28. pyscript/core/runner.py +363 -0
  29. pyscript/core/shell.py +287 -0
  30. pyscript/core/symtab.py +103 -0
  31. pyscript/core/token.py +25 -0
  32. pyscript/core/utils/__init__.py +27 -0
  33. pyscript/core/utils/ansi.py +127 -0
  34. pyscript/core/utils/debug.py +60 -0
  35. pyscript/core/utils/decorators.py +53 -0
  36. pyscript/core/utils/generic.py +46 -0
  37. pyscript/core/utils/jsdict.py +32 -0
  38. pyscript/core/utils/module.py +28 -0
  39. pyscript/core/utils/path.py +29 -0
  40. pyscript/core/utils/similarity.py +22 -0
  41. pyscript/core/utils/string.py +49 -0
  42. pyscript/core/version.py +120 -0
  43. pyscript/lib/__hello__.pys +7 -0
  44. pyscript/lib/ansi.pys +14 -0
  45. pyscript/lib/ast/__init__.pys +36 -0
  46. pyscript/lib/ast/ast_dump.py +433 -0
  47. pyscript/lib/ast/ast_literal_eval.py +80 -0
  48. pyscript/lib/ast/ast_unparse.py +540 -0
  49. pyscript/lib/ast/ast_walk.py +256 -0
  50. pyscript/lib/brainfuck.pys +190 -0
  51. pyscript/lib/dis.pys +7 -0
  52. pyscript/lib/explorer.pys +218 -0
  53. pyscript/lib/fpstimer/__init__.pys +6 -0
  54. pyscript/lib/fpstimer/py_fpstimer.py +54 -0
  55. pyscript/lib/getch.pys +28 -0
  56. pyscript/lib/inspect.pys +25 -0
  57. pyscript/lib/jsdict.pys +5 -0
  58. pyscript/lib/keyword.pys +2 -0
  59. pyscript/lib/opcode.pys +1 -0
  60. pyscript/lib/parser.pys +165 -0
  61. pyscript/lib/site.pys +55 -0
  62. pyscript/lib/symtable.pys +5 -0
  63. pyscript/lib/token.pys +12 -0
  64. pyscript/lib/tokenize/__init__.pys +14 -0
  65. pyscript/lib/tokenize/tok_untokenize.py +64 -0
  66. pyscript/other/.nomedia +0 -0
  67. pyscript/other/PyScript.ico +0 -0
  68. pyscript/other/copyright +2 -0
  69. pyscript/other/credits +2 -0
  70. pyscript/other/license +21 -0
  71. pyscript/site-packages/this.pys +19 -0
  72. pyscript/this.py +8 -0
  73. pyscript_programming_language-1.12.0.dist-info/METADATA +133 -0
  74. pyscript_programming_language-1.12.0.dist-info/RECORD +76 -0
  75. pyscript_programming_language-1.12.0.dist-info/WHEEL +5 -0
  76. pyscript_programming_language-1.12.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1546 @@
1
+ from .constants import TOKENS, DEBUG
2
+ from .cache import undefined
3
+ from .checks import is_list, is_equals, is_public_attribute
4
+ from .context import PysClassContext
5
+ from .exceptions import PysTraceback
6
+ from .handlers import handle_call
7
+ from .mapping import BINARY_FUNCTIONS_MAP, UNARY_FUNCTIONS_MAP
8
+ from .nodes import PysNode, PysIdentifierNode, PysAttributeNode, PysSubscriptNode
9
+ from .objects import PysFunction
10
+ from .pysbuiltins import ce, nce, increment, decrement
11
+ from .results import PysRunTimeResult
12
+ from .symtab import PysClassSymbolTable, find_closest
13
+ from .utils.debug import get_error_args
14
+ from .utils.generic import getattribute, setimuattr, dkeys, is_object_of
15
+ from .utils.similarity import get_closest
16
+
17
+ from collections.abc import Iterable
18
+
19
+ T_KEYWORD = TOKENS['KEYWORD']
20
+ T_STRING = TOKENS['STRING']
21
+ T_AND = TOKENS['DOUBLE-AMPERSAND']
22
+ T_OR = TOKENS['DOUBLE-PIPE']
23
+ T_NOT = TOKENS['EXCLAMATION']
24
+ T_CE = TOKENS['EQUAL-TILDE']
25
+ T_NCE = TOKENS['EXCLAMATION-TILDE']
26
+ T_NULLISH = TOKENS['DOUBLE-QUESTION']
27
+
28
+ get_incremental_function = {
29
+ TOKENS['DOUBLE-PLUS']: increment,
30
+ TOKENS['DOUBLE-MINUS']: decrement
31
+ }.__getitem__
32
+
33
+ get_value_from_keyword = {
34
+ 'True': True,
35
+ 'False': False,
36
+ 'None': None,
37
+ 'true': True,
38
+ 'false': False,
39
+ 'nil': None,
40
+ 'none': None,
41
+ 'null': None
42
+ }.__getitem__
43
+
44
+ def visit_NumberNode(node, context):
45
+ return PysRunTimeResult().success(node.value.value)
46
+
47
+ def visit_StringNode(node, context):
48
+ return PysRunTimeResult().success(node.value.value)
49
+
50
+ def visit_KeywordNode(node, context):
51
+ name = node.name.value
52
+ return PysRunTimeResult().success(
53
+ (True if context.flags & DEBUG else False)
54
+ if name == '__debug__' else
55
+ get_value_from_keyword(name)
56
+ )
57
+
58
+ def visit_IdentifierNode(node, context):
59
+ result = PysRunTimeResult()
60
+
61
+ position = node.position
62
+ name = node.name.value
63
+ symbol_table = context.symbol_table
64
+
65
+ with result(context, position):
66
+ value = symbol_table.get(name)
67
+
68
+ if value is undefined:
69
+ closest_symbol = find_closest(symbol_table, name)
70
+
71
+ return result.failure(
72
+ PysTraceback(
73
+ NameError(
74
+ f"name {name!r} is not defined" +
75
+ (
76
+ ''
77
+ if closest_symbol is None else
78
+ f". Did you mean {closest_symbol!r}?"
79
+ )
80
+ ),
81
+ context,
82
+ position
83
+ )
84
+ )
85
+
86
+ if result.should_return():
87
+ return result
88
+
89
+ return result.success(value)
90
+
91
+ def visit_DictionaryNode(node, context):
92
+ result = PysRunTimeResult()
93
+
94
+ elements = node.class_type()
95
+
96
+ register = result.register
97
+ should_return = result.should_return
98
+ setitem = getattribute(elements, '__setitem__')
99
+
100
+ for nkey, nvalue in node.pairs:
101
+ key = register(get_visitor(nkey.__class__)(nkey, context))
102
+ if should_return():
103
+ return result
104
+
105
+ value = register(get_visitor(nvalue.__class__)(nvalue, context))
106
+ if should_return():
107
+ return result
108
+
109
+ with result(context, nkey.position):
110
+ setitem(key, value)
111
+
112
+ if should_return():
113
+ return result
114
+
115
+ return result.success(elements)
116
+
117
+ def visit_SetNode(node, context):
118
+ result = PysRunTimeResult()
119
+
120
+ elements = set()
121
+
122
+ register = result.register
123
+ should_return = result.should_return
124
+ add = elements.add
125
+
126
+ for nelement in node.elements:
127
+
128
+ with result(context, nelement.position):
129
+ add(register(get_visitor(nelement.__class__)(nelement, context)))
130
+
131
+ if should_return():
132
+ return result
133
+
134
+ return result.success(elements)
135
+
136
+ def visit_ListNode(node, context):
137
+ result = PysRunTimeResult()
138
+
139
+ elements = []
140
+
141
+ register = result.register
142
+ should_return = result.should_return
143
+ append = elements.append
144
+
145
+ for nelement in node.elements:
146
+ append(register(get_visitor(nelement.__class__)(nelement, context)))
147
+ if should_return():
148
+ return result
149
+
150
+ return result.success(elements)
151
+
152
+ def visit_TupleNode(node, context):
153
+ result = PysRunTimeResult()
154
+
155
+ elements = []
156
+
157
+ register = result.register
158
+ should_return = result.should_return
159
+ append = elements.append
160
+
161
+ for nelement in node.elements:
162
+ append(register(get_visitor(nelement.__class__)(nelement, context)))
163
+ if should_return():
164
+ return result
165
+
166
+ return result.success(tuple(elements))
167
+
168
+ def visit_AttributeNode(node, context):
169
+ result = PysRunTimeResult()
170
+
171
+ should_return = result.should_return
172
+ nattribute = node.attribute
173
+ ntarget = node.target
174
+
175
+ target = result.register(get_visitor(ntarget.__class__)(ntarget, context))
176
+ if should_return():
177
+ return result
178
+
179
+ with result(context, nattribute.position):
180
+ return result.success(getattr(target, nattribute.value))
181
+
182
+ if should_return():
183
+ return result
184
+
185
+ def visit_SubscriptNode(node, context):
186
+ result = PysRunTimeResult()
187
+
188
+ register = result.register
189
+ should_return = result.should_return
190
+ ntarget = node.target
191
+
192
+ target = register(get_visitor(ntarget.__class__)(ntarget, context))
193
+ if should_return():
194
+ return result
195
+
196
+ slice = register(visit_slice_SubscriptNode(node.slice, context))
197
+ if should_return():
198
+ return result
199
+
200
+ with result(context, node.position):
201
+ return result.success(target[slice])
202
+
203
+ if should_return():
204
+ return result
205
+
206
+ def visit_CallNode(node, context):
207
+ result = PysRunTimeResult()
208
+
209
+ args = []
210
+ kwargs = {}
211
+
212
+ register = result.register
213
+ should_return = result.should_return
214
+ append = args.append
215
+ setitem = kwargs.__setitem__
216
+ nposition = node.position
217
+ ntarget = node.target
218
+
219
+ target = register(get_visitor(ntarget.__class__)(ntarget, context))
220
+ if should_return():
221
+ return result
222
+
223
+ for nargument in node.arguments:
224
+
225
+ if nargument.__class__ is tuple:
226
+ keyword, nvalue = nargument
227
+ setitem(keyword.value, register(get_visitor(nvalue.__class__)(nvalue, context)))
228
+ if should_return():
229
+ return result
230
+
231
+ else:
232
+ append(register(get_visitor(nargument.__class__)(nargument, context)))
233
+ if should_return():
234
+ return result
235
+
236
+ with result(context, nposition):
237
+ handle_call(target, context, nposition)
238
+ return result.success(target(*args, **kwargs))
239
+
240
+ if should_return():
241
+ return result
242
+
243
+ def visit_ChainOperatorNode(node, context):
244
+ result = PysRunTimeResult()
245
+
246
+ register = result.register
247
+ should_return = result.should_return
248
+ nposition = node.position
249
+ get_expression = node.expressions.__getitem__
250
+ first = get_expression(0)
251
+
252
+ left = register(get_visitor(first.__class__)(first, context))
253
+ if should_return():
254
+ return result
255
+
256
+ with result(context, nposition):
257
+
258
+ for i, toperand in enumerate(node.operations, start=1):
259
+ otype = toperand.type
260
+ ovalue = toperand.value
261
+ nexpression = get_expression(i)
262
+
263
+ right = register(get_visitor(nexpression.__class__)(nexpression, context))
264
+ if should_return():
265
+ return result
266
+
267
+ if otype == T_KEYWORD and ovalue == 'in':
268
+ value = left in right
269
+ elif otype == T_KEYWORD and ovalue == 'is':
270
+ value = left is right
271
+ elif otype == T_CE:
272
+ handle_call(ce, context, nposition)
273
+ value = ce(left, right)
274
+ elif otype == T_NCE:
275
+ handle_call(nce, context, nposition)
276
+ value = nce(left, right)
277
+ else:
278
+ value = BINARY_FUNCTIONS_MAP(otype)(left, right)
279
+
280
+ if not value:
281
+ break
282
+
283
+ left = right
284
+
285
+ if should_return():
286
+ return result
287
+
288
+ return result.success(value)
289
+
290
+ def visit_TernaryOperatorNode(node, context):
291
+ result = PysRunTimeResult()
292
+
293
+ register = result.register
294
+ should_return = result.should_return
295
+ ncondition = node.condition
296
+
297
+ condition = register(get_visitor(ncondition.__class__)(ncondition, context))
298
+ if should_return():
299
+ return result
300
+
301
+ with result(context, node.position):
302
+ nvalue = node.valid if condition else node.invalid
303
+ value = register(get_visitor(nvalue.__class__)(nvalue, context))
304
+ if should_return():
305
+ return result
306
+
307
+ return result.success(value)
308
+
309
+ if should_return():
310
+ return result
311
+
312
+ def visit_BinaryOperatorNode(node, context):
313
+ result = PysRunTimeResult()
314
+
315
+ register = result.register
316
+ should_return = result.should_return
317
+ otype = node.operand.type
318
+ ovalue = node.operand.value
319
+ nleft = node.left
320
+ nright = node.right
321
+
322
+ left = register(get_visitor(nleft.__class__)(nleft, context))
323
+ if should_return():
324
+ return result
325
+
326
+ with result(context, node.position):
327
+ should_return_right = True
328
+
329
+ if (otype == T_KEYWORD and ovalue == 'and') or otype == T_AND:
330
+ if not left:
331
+ return result.success(left)
332
+ elif (otype == T_KEYWORD and ovalue == 'or') or otype == T_OR:
333
+ if left:
334
+ return result.success(left)
335
+ elif otype == T_NULLISH:
336
+ if left is not None:
337
+ return result.success(left)
338
+ else:
339
+ should_return_right = False
340
+
341
+ right = register(get_visitor(nright.__class__)(nright, context))
342
+ if should_return():
343
+ return result
344
+
345
+ return result.success(
346
+ right
347
+ if should_return_right else
348
+ BINARY_FUNCTIONS_MAP(otype)(left, right)
349
+ )
350
+
351
+ if should_return():
352
+ return result
353
+
354
+ def visit_UnaryOperatorNode(node, context):
355
+ result = PysRunTimeResult()
356
+
357
+ register = result.register
358
+ should_return = result.should_return
359
+ otype = node.operand.type
360
+ ovalue = node.operand.value
361
+ nvalue = node.value
362
+
363
+ value = register(get_visitor(nvalue.__class__)(nvalue, context))
364
+ if should_return():
365
+ return result
366
+
367
+ with result(context, node.position):
368
+ if (otype == T_KEYWORD and ovalue == 'not') or otype == T_NOT:
369
+ return result.success(not value)
370
+ elif (otype == T_KEYWORD and ovalue == 'typeof'):
371
+ return result.success(type(value).__name__)
372
+ return result.success(UNARY_FUNCTIONS_MAP(otype)(value))
373
+
374
+ if should_return():
375
+ return result
376
+
377
+ def visit_IncrementalNode(node, context):
378
+ result = PysRunTimeResult()
379
+
380
+ register = result.register
381
+ should_return = result.should_return
382
+ nposition = node.position
383
+ ntarget = node.target
384
+
385
+ value = register(get_visitor(ntarget.__class__)(ntarget, context))
386
+ if should_return():
387
+ return result
388
+
389
+ with result(context, nposition):
390
+ handle_call(function := get_incremental_function(node.operand.type), context, nposition)
391
+ increast_value = function(value)
392
+
393
+ if node.operand_position == 'left':
394
+ value = increast_value
395
+
396
+ register(visit_declaration_AssignmentNode(ntarget, context, increast_value))
397
+ if should_return():
398
+ return result
399
+
400
+ return result.success(value)
401
+
402
+ if should_return():
403
+ return result
404
+
405
+ def visit_StatementsNode(node, context):
406
+ result = PysRunTimeResult()
407
+
408
+ register = result.register
409
+ should_return = result.should_return
410
+ body = node.body
411
+
412
+ if len(body) == 1:
413
+ nvalue = body[0]
414
+ value = register(get_visitor(nvalue.__class__)(nvalue, context))
415
+ if should_return():
416
+ return result
417
+
418
+ return result.success(value)
419
+
420
+ for nelement in body:
421
+ register(get_visitor(nelement.__class__)(nelement, context))
422
+ if should_return():
423
+ return result
424
+
425
+ return result.success(None)
426
+
427
+ def visit_AssignmentNode(node, context):
428
+ result = PysRunTimeResult()
429
+
430
+ register = result.register
431
+ should_return = result.should_return
432
+ nvalue = node.value
433
+
434
+ value = register(get_visitor(nvalue.__class__)(nvalue, context))
435
+ if should_return():
436
+ return result
437
+
438
+ register(visit_declaration_AssignmentNode(node.target, context, value, node.operand.type))
439
+ if should_return():
440
+ return result
441
+
442
+ return result.success(value)
443
+
444
+ def visit_ImportNode(node, context):
445
+ result = PysRunTimeResult()
446
+
447
+ should_return = result.should_return
448
+ get_symbol = context.symbol_table.get
449
+ set_symbol = context.symbol_table.set
450
+ npackages = node.packages
451
+ tname, tas_name = node.name
452
+ name_position = tname.position
453
+
454
+ with result(context, name_position):
455
+ name_module = tname.value
456
+ use_python_package = False
457
+
458
+ require = get_symbol('require')
459
+
460
+ if require is undefined:
461
+ use_python_package = True
462
+ else:
463
+ handle_call(require, context, name_position)
464
+ try:
465
+ module = require(name_module)
466
+ except ModuleNotFoundError:
467
+ use_python_package = True
468
+
469
+ if use_python_package:
470
+ pyimport = get_symbol('pyimport')
471
+
472
+ if pyimport is undefined:
473
+ pyimport = get_symbol('__import__')
474
+
475
+ if pyimport is undefined:
476
+ return result.failure(
477
+ PysTraceback(
478
+ NameError("names 'require', 'pyimport', and '__import__' is not defined"),
479
+ context,
480
+ node.position
481
+ )
482
+ )
483
+
484
+ handle_call(pyimport, context, name_position)
485
+ module = pyimport(name_module)
486
+
487
+ if should_return():
488
+ return result
489
+
490
+ if npackages == 'all':
491
+
492
+ with result(context, name_position):
493
+ exported_from = '__all__'
494
+ exported_packages = getattr(module, exported_from, undefined)
495
+ if exported_packages is undefined:
496
+ exported_from = '__dir__()'
497
+ exported_packages = filter(is_public_attribute, dir(module))
498
+
499
+ for package in exported_packages:
500
+
501
+ if not isinstance(package, str):
502
+ return result.failure(
503
+ PysTraceback(
504
+ TypeError(
505
+ f"Item in {module.__name__}.{exported_from} must be str, not {type(package).__name__}"
506
+ ),
507
+ context,
508
+ name_position
509
+ )
510
+ )
511
+
512
+ set_symbol(package, getattr(module, package))
513
+
514
+ if should_return():
515
+ return result
516
+
517
+ elif npackages:
518
+
519
+ for tpackage, tas_package in npackages:
520
+
521
+ with result(context, tpackage.position):
522
+ set_symbol(
523
+ (tpackage if tas_package is None else tas_package).value,
524
+ getattr(module, tpackage.value)
525
+ )
526
+
527
+ if should_return():
528
+ return result
529
+
530
+ elif not (tname.type == T_STRING and tas_name is None):
531
+
532
+ with result(context, node.position):
533
+ set_symbol((tname if tas_name is None else tas_name).value, module)
534
+
535
+ if should_return():
536
+ return result
537
+
538
+ return result.success(None)
539
+
540
+ def visit_IfNode(node, context):
541
+ result = PysRunTimeResult()
542
+
543
+ register = result.register
544
+ should_return = result.should_return
545
+ else_body = node.else_body
546
+
547
+ for ncondition, body in node.cases_body:
548
+ condition = register(get_visitor(ncondition.__class__)(ncondition, context))
549
+ if should_return():
550
+ return result
551
+
552
+ with result(context, ncondition.position):
553
+ condition = True if condition else False
554
+
555
+ if should_return():
556
+ return result
557
+
558
+ if condition:
559
+ register(get_visitor(body.__class__)(body, context))
560
+ if should_return():
561
+ return result
562
+
563
+ return result.success(None)
564
+
565
+ if else_body:
566
+ register(get_visitor(else_body.__class__)(else_body, context))
567
+ if should_return():
568
+ return result
569
+
570
+ return result.success(None)
571
+
572
+ def visit_SwitchNode(node, context):
573
+ result = PysRunTimeResult()
574
+
575
+ register = result.register
576
+ should_return = result.should_return
577
+ default_body = node.default_body
578
+ ntarget = node.target
579
+
580
+ fall_through = False
581
+ no_match_found = True
582
+
583
+ target = register(get_visitor(ntarget.__class__)(ntarget, context))
584
+ if should_return():
585
+ return result
586
+
587
+ for ncondition, body in node.case_cases:
588
+ case = register(get_visitor(ncondition.__class__)(ncondition, context))
589
+ if should_return():
590
+ return result
591
+
592
+ with result(context, ncondition.position):
593
+ equal = True if target == case else False
594
+
595
+ if should_return():
596
+ return result
597
+
598
+ if fall_through or equal:
599
+ no_match_found = False
600
+
601
+ register(get_visitor(body.__class__)(body, context))
602
+ if should_return() and not result.should_break:
603
+ return result
604
+
605
+ if result.should_break:
606
+ result.should_break = False
607
+ fall_through = False
608
+ else:
609
+ fall_through = True
610
+
611
+ if (fall_through or no_match_found) and default_body:
612
+ register(get_visitor(default_body.__class__)(default_body, context))
613
+ if should_return() and not result.should_break:
614
+ return result
615
+
616
+ result.should_break = False
617
+
618
+ return result.success(None)
619
+
620
+ def visit_MatchNode(node, context):
621
+ result = PysRunTimeResult()
622
+
623
+ register = result.register
624
+ should_return = result.should_return
625
+ ntarget = node.target
626
+
627
+ compare = False
628
+
629
+ if ntarget:
630
+ target = register(get_visitor(ntarget.__class__)(ntarget, context))
631
+ if should_return():
632
+ return result
633
+
634
+ compare = True
635
+
636
+ for ncondition, nvalue in node.cases:
637
+ condition = register(get_visitor(ncondition.__class__)(ncondition, context))
638
+ if should_return():
639
+ return result
640
+
641
+ with result(context, ncondition.position):
642
+ valid = target == condition if compare else (True if condition else False)
643
+
644
+ if should_return():
645
+ return result
646
+
647
+ if valid:
648
+ value = register(get_visitor(nvalue.__class__)(nvalue, context))
649
+ if should_return():
650
+ return result
651
+
652
+ return result.success(value)
653
+
654
+ ndefault = node.default
655
+
656
+ if ndefault:
657
+ default = register(get_visitor(ndefault.__class__)(ndefault, context))
658
+ if should_return():
659
+ return result
660
+
661
+ return result.success(default)
662
+
663
+ return result.success(None)
664
+
665
+ def visit_TryNode(node, context):
666
+ result = PysRunTimeResult()
667
+
668
+ register = result.register
669
+ failure = result.failure
670
+ should_return = result.should_return
671
+ body = node.body
672
+ else_body = node.else_body
673
+ finally_body = node.finally_body
674
+
675
+ register(get_visitor(body.__class__)(body, context))
676
+ error = result.error
677
+
678
+ if error:
679
+ exception = error.exception
680
+ failure(None)
681
+
682
+ for (targets, tparameter), body in node.catch_cases:
683
+ handle_exception = True
684
+ stop = False
685
+
686
+ if targets:
687
+ handle_exception = False
688
+
689
+ for nerror_class in targets:
690
+ error_class = register(visit_IdentifierNode(nerror_class, context))
691
+ if result.error:
692
+ setimuattr(result.error, 'cause', error)
693
+ stop = True
694
+ break
695
+
696
+ if not (isinstance(error_class, type) and issubclass(error_class, BaseException)):
697
+ failure(
698
+ PysTraceback(
699
+ TypeError("catching classes that do not inherit from BaseException is not allowed"),
700
+ context,
701
+ nerror_class.position,
702
+ error
703
+ )
704
+ )
705
+ stop = True
706
+ break
707
+
708
+ if is_object_of(exception, error_class):
709
+ handle_exception = True
710
+ break
711
+
712
+ if stop:
713
+ break
714
+
715
+ elif handle_exception:
716
+
717
+ if tparameter:
718
+ with result(context, position := tparameter.position):
719
+ (symbol_table := context.symbol_table).set(parameter := tparameter.value, error.exception)
720
+ if should_return():
721
+ break
722
+
723
+ register(get_visitor(body.__class__)(body, context))
724
+ if result.error:
725
+ setimuattr(result.error, 'cause', error)
726
+
727
+ if tparameter:
728
+ with result(context, position):
729
+ symbol_table.remove(parameter)
730
+ if should_return():
731
+ break
732
+
733
+ break
734
+
735
+ else:
736
+ failure(error)
737
+
738
+ elif else_body:
739
+ register(get_visitor(else_body.__class__)(else_body, context))
740
+
741
+ if finally_body:
742
+ finally_result = PysRunTimeResult()
743
+ finally_result.register(get_visitor(finally_body.__class__)(finally_body, context))
744
+ if finally_result.should_return():
745
+ if finally_result.error:
746
+ setimuattr(finally_result.error, 'cause', result.error)
747
+ return finally_result
748
+
749
+ if should_return():
750
+ return result
751
+
752
+ return result.success(None)
753
+
754
+ def visit_WithNode(node, context):
755
+ result = PysRunTimeResult()
756
+
757
+ exits = []
758
+
759
+ register = result.register
760
+ failure = result.failure
761
+ should_return = result.should_return
762
+ append = exits.append
763
+ set_symbol = context.symbol_table.set
764
+
765
+ for ncontext, nalias in node.contexts:
766
+ context_value = register(get_visitor(ncontext.__class__)(ncontext, context))
767
+ if should_return():
768
+ break
769
+
770
+ ncontext_position = ncontext.position
771
+
772
+ with result(context, ncontext_position):
773
+ enter = getattr(context_value, '__enter__', undefined)
774
+ exit = getattr(context_value, '__exit__', undefined)
775
+
776
+ missed_enter = enter is undefined
777
+ missed_exit = exit is undefined
778
+
779
+ if missed_enter or missed_exit:
780
+ message = f"{type(context_value).__name__!r} object does not support the context manager protocol"
781
+
782
+ if missed_enter and missed_exit:
783
+ pass
784
+ elif missed_enter:
785
+ message += " (missed __enter__ method)"
786
+ elif missed_exit:
787
+ message += " (missed __exit__ method)"
788
+
789
+ result.failure(
790
+ PysTraceback(
791
+ TypeError(message),
792
+ context,
793
+ ncontext_position
794
+ )
795
+ )
796
+ break
797
+
798
+ handle_call(enter, context, ncontext_position)
799
+ enter_value = enter()
800
+ append((exit, ncontext_position))
801
+
802
+ if should_return():
803
+ break
804
+
805
+ if nalias:
806
+ with result(context, nalias.position):
807
+ set_symbol(nalias.value, enter_value)
808
+ if should_return():
809
+ break
810
+
811
+ if not should_return():
812
+ body = node.body
813
+ register(get_visitor(body.__class__)(body, context))
814
+
815
+ error = result.error
816
+
817
+ for exit, ncontext_position in reversed(exits):
818
+ with result(context, ncontext_position):
819
+ handle_call(exit, context, ncontext_position)
820
+ if exit(*get_error_args(error)):
821
+ failure(None)
822
+ error = None
823
+
824
+ if should_return():
825
+ if result.error and result.error is not error:
826
+ setimuattr(result.error, 'cause', error)
827
+ return result
828
+
829
+ return result.success(None)
830
+
831
+ def visit_ForNode(node, context):
832
+ result = PysRunTimeResult()
833
+
834
+ register = result.register
835
+ should_return = result.should_return
836
+ nheader = node.header
837
+ nheader_length = len(nheader)
838
+ body = node.body
839
+ body_class = body.__class__
840
+ else_body = node.else_body
841
+
842
+ if nheader_length == 2:
843
+ ndeclaration, niteration = nheader
844
+ niteration_position = niteration.position
845
+
846
+ iteration = register(get_visitor(niteration.__class__)(niteration, context))
847
+ if should_return():
848
+ return result
849
+
850
+ with result(context, niteration_position):
851
+ handle_call(getattr(iteration, '__iter__', None), context, niteration_position)
852
+ next = iter(iteration).__next__
853
+
854
+ if should_return():
855
+ return result
856
+
857
+ def condition():
858
+ with result(context, niteration_position):
859
+ handle_call(next, context, niteration_position)
860
+ register(visit_declaration_AssignmentNode(ndeclaration, context, next()))
861
+
862
+ if should_return():
863
+ if result.error and is_object_of(result.error.exception, StopIteration):
864
+ result.failure(None)
865
+ return False
866
+
867
+ return True
868
+
869
+ def update():
870
+ pass
871
+
872
+ elif nheader_length == 3:
873
+ ndeclaration, ncondition, nupdate = nheader
874
+
875
+ if ndeclaration:
876
+ register(get_visitor(ndeclaration.__class__)(ndeclaration, context))
877
+ if should_return():
878
+ return result
879
+
880
+ if ncondition:
881
+ ncondition_class = ncondition.__class__
882
+ ncondition_position = ncondition.position
883
+ def condition():
884
+ value = register(get_visitor(ncondition_class)(ncondition, context))
885
+ if should_return():
886
+ return False
887
+ with result(context, ncondition_position):
888
+ return True if value else False
889
+
890
+ else:
891
+ def condition():
892
+ return True
893
+
894
+ if nupdate:
895
+ nupdate_class = nupdate.__class__
896
+ def update():
897
+ register(get_visitor(nupdate_class)(nupdate, context))
898
+
899
+ else:
900
+ def update():
901
+ pass
902
+
903
+ while True:
904
+ done = condition()
905
+ if should_return():
906
+ return result
907
+
908
+ if not done:
909
+ break
910
+
911
+ register(get_visitor(body_class)(body, context))
912
+ if should_return():
913
+ if result.should_continue:
914
+ result.should_continue = False
915
+ elif result.should_break:
916
+ break
917
+ else:
918
+ return result
919
+
920
+ update()
921
+ if should_return():
922
+ return result
923
+
924
+ if result.should_break:
925
+ result.should_break = False
926
+
927
+ elif else_body:
928
+ register(get_visitor(else_body.__class__)(else_body, context))
929
+ if should_return():
930
+ return result
931
+
932
+ return result.success(None)
933
+
934
+ def visit_WhileNode(node, context):
935
+ result = PysRunTimeResult()
936
+
937
+ register = result.register
938
+ should_return = result.should_return
939
+ ncondition = node.condition
940
+ ncondition_class = ncondition.__class__
941
+ ncondition_position = ncondition.position
942
+ body = node.body
943
+ body_class = body.__class__
944
+ else_body = node.else_body
945
+
946
+ while True:
947
+ condition = register(get_visitor(ncondition_class)(ncondition, context))
948
+ if should_return():
949
+ return result
950
+
951
+ with result(context, ncondition_position):
952
+ if not condition:
953
+ break
954
+
955
+ if should_return():
956
+ return result
957
+
958
+ register(get_visitor(body_class)(body, context))
959
+ if should_return():
960
+ if result.should_continue:
961
+ result.should_continue = False
962
+ elif result.should_break:
963
+ break
964
+ else:
965
+ return result
966
+
967
+ if result.should_break:
968
+ result.should_break = False
969
+
970
+ elif else_body:
971
+ register(get_visitor(else_body.__class__)(else_body, context))
972
+ if should_return():
973
+ return result
974
+
975
+ return result.success(None)
976
+
977
+ def visit_DoWhileNode(node, context):
978
+ result = PysRunTimeResult()
979
+
980
+ register = result.register
981
+ should_return = result.should_return
982
+ ncondition = node.condition
983
+ ncondition_class = ncondition.__class__
984
+ ncondition_position = ncondition.position
985
+ body = node.body
986
+ body_class = body.__class__
987
+ else_body = node.else_body
988
+
989
+ while True:
990
+ register(get_visitor(body_class)(body, context))
991
+ if should_return():
992
+ if result.should_continue:
993
+ result.should_continue = False
994
+ elif result.should_break:
995
+ break
996
+ else:
997
+ return result
998
+
999
+ condition = register(get_visitor(ncondition_class)(ncondition, context))
1000
+ if should_return():
1001
+ return result
1002
+
1003
+ with result(context, ncondition_position):
1004
+ if not condition:
1005
+ break
1006
+
1007
+ if should_return():
1008
+ return result
1009
+
1010
+ if result.should_break:
1011
+ result.should_break = False
1012
+
1013
+ elif else_body:
1014
+ register(get_visitor(else_body.__class__)(else_body, context))
1015
+ if should_return():
1016
+ return result
1017
+
1018
+ return result.success(None)
1019
+
1020
+ def visit_RepeatNode(node, context):
1021
+ result = PysRunTimeResult()
1022
+
1023
+ register = result.register
1024
+ should_return = result.should_return
1025
+ ncondition = node.condition
1026
+ ncondition_class = ncondition.__class__
1027
+ ncondition_position = ncondition.position
1028
+ body = node.body
1029
+ body_class = body.__class__
1030
+ else_body = node.else_body
1031
+
1032
+ while True:
1033
+ register(get_visitor(body_class)(body, context))
1034
+ if should_return():
1035
+ if result.should_continue:
1036
+ result.should_continue = False
1037
+ elif result.should_break:
1038
+ break
1039
+ else:
1040
+ return result
1041
+
1042
+ condition = register(get_visitor(ncondition_class)(ncondition, context))
1043
+ if should_return():
1044
+ return result
1045
+
1046
+ with result(context, ncondition_position):
1047
+ if condition:
1048
+ break
1049
+
1050
+ if should_return():
1051
+ return result
1052
+
1053
+ if result.should_break:
1054
+ result.should_break = False
1055
+
1056
+ elif else_body:
1057
+ register(get_visitor(else_body.__class__)(else_body, context))
1058
+ if should_return():
1059
+ return result
1060
+
1061
+ return result.success(None)
1062
+
1063
+ def visit_ClassNode(node, context):
1064
+ result = PysRunTimeResult()
1065
+
1066
+ bases = []
1067
+
1068
+ register = result.register
1069
+ should_return = result.should_return
1070
+ append = bases.append
1071
+ nposition = node.position
1072
+ name = node.name.value
1073
+ body = node.body
1074
+ symbol_table = context.symbol_table
1075
+
1076
+ for nbase in node.bases:
1077
+ append(register(get_visitor(nbase.__class__)(nbase, context)))
1078
+ if should_return():
1079
+ return result
1080
+
1081
+ class_context = PysClassContext(
1082
+ name=name,
1083
+ symbol_table=PysClassSymbolTable(symbol_table),
1084
+ parent=context,
1085
+ parent_entry_position=nposition
1086
+ )
1087
+
1088
+ register(get_visitor(body.__class__)(body, class_context))
1089
+ if should_return():
1090
+ return result
1091
+
1092
+ with result(context, nposition):
1093
+ cls = type(name, tuple(bases), class_context.symbol_table.symbols)
1094
+ cls.__qualname__ = class_context.qualname
1095
+
1096
+ if should_return():
1097
+ return result
1098
+
1099
+ for ndecorator in reversed(node.decorators):
1100
+ decorator = register(get_visitor(ndecorator.__class__)(ndecorator, context))
1101
+ if should_return():
1102
+ return result
1103
+
1104
+ dposition = ndecorator.position
1105
+
1106
+ with result(context, dposition):
1107
+ handle_call(decorator, context, dposition)
1108
+ cls = decorator(cls)
1109
+
1110
+ if should_return():
1111
+ return result
1112
+
1113
+ with result(context, nposition):
1114
+ symbol_table.set(name, cls)
1115
+
1116
+ if should_return():
1117
+ return result
1118
+
1119
+ return result.success(None)
1120
+
1121
+ def visit_FunctionNode(node, context):
1122
+ result = PysRunTimeResult()
1123
+
1124
+ parameters = []
1125
+
1126
+ register = result.register
1127
+ should_return = result.should_return
1128
+ append = parameters.append
1129
+ nposition = node.position
1130
+ name = None if node.name is None else node.name.value
1131
+
1132
+ for nparameter in node.parameters:
1133
+
1134
+ if nparameter.__class__ is tuple:
1135
+ keyword, nvalue = nparameter
1136
+
1137
+ value = register(get_visitor(nvalue.__class__)(nvalue, context))
1138
+ if should_return():
1139
+ return result
1140
+
1141
+ append((keyword.value, value))
1142
+
1143
+ else:
1144
+ append(nparameter.value)
1145
+
1146
+ function = PysFunction(
1147
+ name=name,
1148
+ qualname=context.qualname,
1149
+ parameters=parameters,
1150
+ body=node.body,
1151
+ context=context,
1152
+ position=nposition
1153
+ )
1154
+
1155
+ for ndecorator in reversed(node.decorators):
1156
+ decorator = register(get_visitor(ndecorator.__class__)(ndecorator, context))
1157
+ if should_return():
1158
+ return result
1159
+
1160
+ dposition = ndecorator.position
1161
+
1162
+ with result(context, dposition):
1163
+ handle_call(decorator, context, dposition)
1164
+ function = decorator(function)
1165
+
1166
+ if should_return():
1167
+ return result
1168
+
1169
+ if name:
1170
+ with result(context, nposition):
1171
+ context.symbol_table.set(name, function)
1172
+ if should_return():
1173
+ return result
1174
+
1175
+ return result.success(function)
1176
+
1177
+ def visit_GlobalNode(node, context):
1178
+ context.symbol_table.globals.update(name.value for name in node.identifiers)
1179
+ return PysRunTimeResult().success(None)
1180
+
1181
+ def visit_ReturnNode(node, context):
1182
+ result = PysRunTimeResult()
1183
+
1184
+ nvalue = node.value
1185
+
1186
+ if nvalue:
1187
+ value = result.register(get_visitor(nvalue.__class__)(nvalue, context))
1188
+ if result.should_return():
1189
+ return result
1190
+ return result.success_return(value)
1191
+
1192
+ return result.success_return(None)
1193
+
1194
+ def visit_ThrowNode(node, context):
1195
+ result = PysRunTimeResult()
1196
+
1197
+ register = result.register
1198
+ should_return = result.should_return
1199
+ ntarget = node.target
1200
+ ncause = node.cause
1201
+
1202
+ target = register(get_visitor(ntarget.__class__)(ntarget, context))
1203
+ if should_return():
1204
+ return result
1205
+
1206
+ if not is_object_of(target, BaseException):
1207
+ return result.failure(
1208
+ PysTraceback(
1209
+ TypeError("exceptions must derive from BaseException"),
1210
+ context,
1211
+ ntarget.position
1212
+ )
1213
+ )
1214
+
1215
+ if ncause:
1216
+ cause = register(get_visitor(ncause.__class__)(ncause, context))
1217
+ if should_return():
1218
+ return result
1219
+
1220
+ if not is_object_of(cause, BaseException):
1221
+ return result.failure(
1222
+ PysTraceback(
1223
+ TypeError("exceptions must derive from BaseException"),
1224
+ context,
1225
+ ncause.position
1226
+ )
1227
+ )
1228
+
1229
+ cause = PysTraceback(
1230
+ cause,
1231
+ context,
1232
+ ncause.position
1233
+ )
1234
+
1235
+ else:
1236
+ cause = None
1237
+
1238
+ return result.failure(
1239
+ PysTraceback(
1240
+ target,
1241
+ context,
1242
+ node.position,
1243
+ cause,
1244
+ True if ncause else False
1245
+ )
1246
+ )
1247
+
1248
+ def visit_AssertNode(node, context):
1249
+ result = PysRunTimeResult()
1250
+
1251
+ if not (context.flags & DEBUG):
1252
+ register = result.register
1253
+ should_return = result.should_return
1254
+ ncondition = node.condition
1255
+
1256
+ condition = register(get_visitor(ncondition.__class__)(ncondition, context))
1257
+ if should_return():
1258
+ return result
1259
+
1260
+ with result(context, ncondition.position):
1261
+
1262
+ if not condition:
1263
+ nmessage = node.message
1264
+
1265
+ if nmessage:
1266
+ message = register(get_visitor(nmessage.__class__)(nmessage, context))
1267
+ if should_return():
1268
+ return result
1269
+
1270
+ return result.failure(
1271
+ PysTraceback(
1272
+ AssertionError(message),
1273
+ context,
1274
+ node.position
1275
+ )
1276
+ )
1277
+
1278
+ return result.failure(
1279
+ PysTraceback(
1280
+ AssertionError,
1281
+ context,
1282
+ node.position
1283
+ )
1284
+ )
1285
+
1286
+ if should_return():
1287
+ return result
1288
+
1289
+ return result.success(None)
1290
+
1291
+ def visit_DeleteNode(node, context):
1292
+ result = PysRunTimeResult()
1293
+
1294
+ register = result.register
1295
+ should_return = result.should_return
1296
+ symbol_table = context.symbol_table
1297
+
1298
+ for ntarget in node.targets:
1299
+ target_position = ntarget.position
1300
+ ntarget_type = ntarget.__class__
1301
+
1302
+ if ntarget_type is PysIdentifierNode:
1303
+ name = ntarget.name.value
1304
+
1305
+ with result(context, target_position):
1306
+
1307
+ if not symbol_table.remove(name):
1308
+ closest_symbol = get_closest(dkeys(symbol_table.symbols), name)
1309
+
1310
+ return result.failure(
1311
+ PysTraceback(
1312
+ NameError(
1313
+ (
1314
+ f"name {name!r} is not defined"
1315
+ if symbol_table.get(name) is undefined else
1316
+ f"name {name!r} is not defined on local"
1317
+ )
1318
+ +
1319
+ (
1320
+ ''
1321
+ if closest_symbol is None else
1322
+ f". Did you mean {closest_symbol!r}?"
1323
+ )
1324
+ ),
1325
+ context,
1326
+ target_position
1327
+ )
1328
+ )
1329
+
1330
+ if should_return():
1331
+ return result
1332
+
1333
+ elif ntarget_type is PysAttributeNode:
1334
+ tntarget = ntarget.target
1335
+ target = register(get_visitor(tntarget.__class__)(tntarget, context))
1336
+ if should_return():
1337
+ return result
1338
+
1339
+ with result(context, target_position):
1340
+ delattr(target, ntarget.attribute.value)
1341
+
1342
+ if should_return():
1343
+ return result
1344
+
1345
+ elif ntarget_type is PysSubscriptNode:
1346
+ tntarget = ntarget.target
1347
+ target = register(get_visitor(tntarget.__class__)(tntarget, context))
1348
+ if should_return():
1349
+ return result
1350
+
1351
+ slice = register(visit_slice_SubscriptNode(ntarget.slice, context))
1352
+ if should_return():
1353
+ return result
1354
+
1355
+ with result(context, target_position):
1356
+ del target[slice]
1357
+
1358
+ if should_return():
1359
+ return result
1360
+
1361
+ return result.success(None)
1362
+
1363
+ def visit_EllipsisNode(node, context):
1364
+ return PysRunTimeResult().success(...)
1365
+
1366
+ def visit_ContinueNode(node, context):
1367
+ return PysRunTimeResult().success_continue()
1368
+
1369
+ def visit_BreakNode(node, context):
1370
+ return PysRunTimeResult().success_break()
1371
+
1372
+ def visit_slice_SubscriptNode(node, context):
1373
+ result = PysRunTimeResult()
1374
+
1375
+ register = result.register
1376
+ should_return = result.should_return
1377
+ ntype = node.__class__
1378
+
1379
+ if ntype is slice:
1380
+ start = node.start
1381
+ stop = node.stop
1382
+ step = node.step
1383
+
1384
+ if start is not None:
1385
+ start = register(get_visitor(start.__class__)(start, context))
1386
+ if should_return():
1387
+ return result
1388
+
1389
+ if stop is not None:
1390
+ stop = register(get_visitor(stop.__class__)(stop, context))
1391
+ if should_return():
1392
+ return result
1393
+
1394
+ if step is not None:
1395
+ step = register(get_visitor(step.__class__)(step, context))
1396
+ if should_return():
1397
+ return result
1398
+
1399
+ return result.success(slice(start, stop, step))
1400
+
1401
+ elif ntype is tuple:
1402
+ slices = []
1403
+ append = slices.append
1404
+
1405
+ for element in node:
1406
+ append(register(visit_slice_SubscriptNode(element, context)))
1407
+ if should_return():
1408
+ return result
1409
+
1410
+ return result.success(tuple(slices))
1411
+
1412
+ else:
1413
+ value = register(get_visitor(node.__class__)(node, context))
1414
+ if should_return():
1415
+ return result
1416
+
1417
+ return result.success(value)
1418
+
1419
+ def visit_declaration_AssignmentNode(node, context, value, operand=TOKENS['EQUAL']):
1420
+ result = PysRunTimeResult()
1421
+
1422
+ register = result.register
1423
+ should_return = result.should_return
1424
+ ntype = node.__class__
1425
+
1426
+ if ntype is PysIdentifierNode:
1427
+ symbol_table = context.symbol_table
1428
+ name = node.name.value
1429
+
1430
+ with result(context, node.position):
1431
+
1432
+ if not symbol_table.set(name, value, operand=operand):
1433
+ closest_symbol = get_closest(dkeys(symbol_table.symbols), name)
1434
+
1435
+ result.failure(
1436
+ PysTraceback(
1437
+ NameError(
1438
+ (
1439
+ f"name {name!r} is not defined"
1440
+ if symbol_table.get(name) is undefined else
1441
+ f"name {name!r} is not defined on local"
1442
+ )
1443
+ +
1444
+ (
1445
+ ''
1446
+ if closest_symbol is None else
1447
+ f". Did you mean {closest_symbol!r}?"
1448
+ )
1449
+ ),
1450
+ context,
1451
+ node.position
1452
+ )
1453
+ )
1454
+
1455
+ if should_return():
1456
+ return result
1457
+
1458
+ elif ntype is PysAttributeNode:
1459
+ ntarget = node.target
1460
+ target = register(get_visitor(ntarget.__class__)(ntarget, context))
1461
+ if should_return():
1462
+ return result
1463
+
1464
+ attribute = node.attribute.value
1465
+
1466
+ with result(context, node.position):
1467
+ setattr(
1468
+ target,
1469
+ attribute,
1470
+ value
1471
+ if is_equals(operand) else
1472
+ BINARY_FUNCTIONS_MAP(operand)(getattr(target, attribute), value)
1473
+ )
1474
+
1475
+ if should_return():
1476
+ return result
1477
+
1478
+ elif ntype is PysSubscriptNode:
1479
+ ntarget = node.target
1480
+ target = register(get_visitor(ntarget.__class__)(ntarget, context))
1481
+ if should_return():
1482
+ return result
1483
+
1484
+ slice = register(visit_slice_SubscriptNode(node.slice, context))
1485
+ if should_return():
1486
+ return result
1487
+
1488
+ with result(context, node.position):
1489
+ target[slice] = value if is_equals(operand) else BINARY_FUNCTIONS_MAP(operand)(target[slice], value)
1490
+
1491
+ if should_return():
1492
+ return result
1493
+
1494
+ elif is_list(ntype):
1495
+ position = node.position
1496
+
1497
+ if not isinstance(value, Iterable):
1498
+ return result.failure(
1499
+ PysTraceback(
1500
+ TypeError(f"cannot unpack non-iterable {type(value).__name__} object"),
1501
+ context,
1502
+ position
1503
+ )
1504
+ )
1505
+
1506
+ elements = node.elements
1507
+ count = 0
1508
+
1509
+ with result(context, position):
1510
+
1511
+ for element, element_value in zip(elements, value):
1512
+ register(visit_declaration_AssignmentNode(element, context, element_value, operand))
1513
+ if should_return():
1514
+ return result
1515
+
1516
+ count += 1
1517
+
1518
+ if should_return():
1519
+ return result
1520
+
1521
+ length = len(elements)
1522
+
1523
+ if count < length:
1524
+ return result.failure(
1525
+ PysTraceback(
1526
+ ValueError(f"not enough values to unpack (expected {length}, got {count})"),
1527
+ context,
1528
+ node.position
1529
+ )
1530
+ )
1531
+
1532
+ elif count > length:
1533
+ return result.failure(
1534
+ PysTraceback(
1535
+ ValueError(f"to many values to unpack (expected {length})"),
1536
+ context,
1537
+ node.position
1538
+ )
1539
+ )
1540
+
1541
+ return result.success(None)
1542
+
1543
+ get_visitor = {
1544
+ class_node: globals()['visit_' + class_node.__name__.removeprefix('Pys')]
1545
+ for class_node in PysNode.__subclasses__()
1546
+ }.__getitem__