pyscript-programming-language 1.11.1__tar.gz → 1.11.2__tar.gz

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 (86) hide show
  1. pyscript_programming_language-1.11.2/MANIFEST.in +4 -0
  2. {pyscript_programming_language-1.11.1/pyscript_programming_language.egg-info → pyscript_programming_language-1.11.2}/PKG-INFO +1 -1
  3. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/__main__.py +10 -11
  4. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/analyzer.py +2 -2
  5. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/cache.py +1 -1
  6. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/checks.py +1 -1
  7. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/constants.py +5 -3
  8. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/editor/bases.py +1 -1
  9. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/editor/gui.py +7 -9
  10. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/editor/terminal.py +18 -12
  11. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/handlers.py +3 -2
  12. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/highlight.py +28 -28
  13. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/interpreter.py +11 -11
  14. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/objects.py +6 -6
  15. pyscript_programming_language-1.11.2/pyscript/core/other/.nomedia +1 -0
  16. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/parser.py +20 -19
  17. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/position.py +27 -9
  18. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/pysbuiltins.py +19 -12
  19. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/runner.py +10 -4
  20. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/shell.py +3 -1
  21. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/utils/decorators.py +11 -7
  22. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/utils/generic.py +4 -2
  23. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/utils/module.py +1 -4
  24. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/utils/path.py +4 -1
  25. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/utils/string.py +1 -1
  26. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/version.py +2 -2
  27. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/ast/ast_literal_eval.py +7 -7
  28. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/brainfuck.pys +31 -28
  29. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/explorer.pys +0 -1
  30. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/fpstimer/py_fpstimer.py +1 -0
  31. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/inspect.pys +2 -3
  32. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/sys.pys +1 -1
  33. pyscript_programming_language-1.11.2/pyscript/lib/tokenize/tok_untokenize.py +64 -0
  34. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2/pyscript_programming_language.egg-info}/PKG-INFO +1 -1
  35. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/setup.py +2 -2
  36. pyscript_programming_language-1.11.1/MANIFEST.in +0 -3
  37. pyscript_programming_language-1.11.1/pyscript/core/other/.nomedia +0 -0
  38. pyscript_programming_language-1.11.1/pyscript/lib/tokenize/tok_untokenize.py +0 -27
  39. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/README.md +0 -0
  40. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/__init__.py +0 -0
  41. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/__init__.pyi +0 -0
  42. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/__init__.py +0 -0
  43. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/bases.py +0 -0
  44. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/buffer.py +0 -0
  45. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/context.py +0 -0
  46. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/editor/__init__.py +0 -0
  47. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/exceptions.py +0 -0
  48. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/lexer.py +0 -0
  49. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/mapping.py +0 -0
  50. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/nodes.py +0 -0
  51. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/other/PyScript.ico +0 -0
  52. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/other/copyright +0 -0
  53. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/other/credits +0 -0
  54. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/other/license +0 -0
  55. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/results.py +0 -0
  56. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/symtab.py +0 -0
  57. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/token.py +0 -0
  58. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/utils/__init__.py +0 -0
  59. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/utils/ansi.py +0 -0
  60. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/utils/debug.py +0 -0
  61. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/utils/jsdict.py +0 -0
  62. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/core/utils/similarity.py +0 -0
  63. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/__hello__.pys +0 -0
  64. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/ansi.pys +0 -0
  65. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/ast/__init__.pys +0 -0
  66. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/ast/ast_dump.py +0 -0
  67. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/ast/ast_unparse.py +0 -0
  68. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/ast/ast_walk.py +0 -0
  69. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/dis.pys +0 -0
  70. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/fpstimer/__init__.pys +0 -0
  71. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/getch.pys +0 -0
  72. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/jsdict.pys +0 -0
  73. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/keyword.pys +0 -0
  74. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/opcode.pys +0 -0
  75. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/parser.pys +0 -0
  76. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/site.pys +0 -0
  77. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/symtable.pys +0 -0
  78. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/token.pys +0 -0
  79. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/lib/tokenize/__init__.pys +0 -0
  80. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/site-packages/this.pys +0 -0
  81. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript/this.py +0 -0
  82. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
  83. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  84. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript_programming_language.egg-info/requires.txt +0 -0
  85. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  86. {pyscript_programming_language-1.11.1 → pyscript_programming_language-1.11.2}/setup.cfg +0 -0
@@ -0,0 +1,4 @@
1
+ include README.md
2
+
3
+ recursive-include pyscript *
4
+ recursive-exclude backup *
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.11.1
3
+ Version: 1.11.2
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://azzammuhyala.github.io/pyscript
6
6
  Author: azzammuhyala
@@ -7,17 +7,15 @@ from .core.highlight import (
7
7
  HLFMT_HTML, HLFMT_ANSI, HLFMT_BBCODE, pys_highlight, PygmentsPyScriptStyle, PygmentsPyScriptLexer
8
8
  )
9
9
  from .core.runner import _normalize_namespace, pys_runner, pys_shell
10
- from .core.utils.module import get_module_name_from_path, remove_python_path
11
- from .core.utils.path import normpath, getcwd
10
+ from .core.utils.module import remove_python_path
11
+ from .core.utils.path import getcwd, normpath, get_name_from_path
12
12
  from .core.version import __version__
13
13
 
14
14
  try:
15
15
  from pygments import highlight
16
16
  from pygments.formatters import (
17
- BBCodeFormatter,
18
- HtmlFormatter,
19
- LatexFormatter,
20
- TerminalFormatter, TerminalTrueColorFormatter, Terminal256Formatter
17
+ BBCodeFormatter, HtmlFormatter, LatexFormatter, TerminalFormatter, TerminalTrueColorFormatter,
18
+ Terminal256Formatter
21
19
  )
22
20
 
23
21
  FORMAT_PYGMENTS_MAP = {
@@ -45,7 +43,7 @@ FORMAT_HIGHLIGHT_MAP = {
45
43
  }
46
44
 
47
45
  parser = ArgumentParser(
48
- prog=f'{get_module_name_from_path(sys.executable)} -m pyscript',
46
+ prog=f'{get_name_from_path(sys.executable)} -m pyscript',
49
47
  description=f'PyScript Launcher for Python Version {".".join(map(str, sys.version_info))}'
50
48
  )
51
49
 
@@ -70,7 +68,7 @@ parser.add_argument(
70
68
 
71
69
  parser.add_argument(
72
70
  '-e', '--editor',
73
- choices=('terminal', 'gui'),
71
+ choices=('gui', 'terminal'),
74
72
  default=None,
75
73
  help="Open the editor panel from a 'file'",
76
74
  )
@@ -187,10 +185,10 @@ if args.file is not None:
187
185
 
188
186
  if args.editor:
189
187
  try:
190
- if args.editor == 'terminal':
191
- editor = PysTerminalEditor
192
- elif args.editor == 'gui':
188
+ if args.editor == 'gui':
193
189
  editor = PysGUIEditor
190
+ elif args.editor == 'terminal':
191
+ editor = PysTerminalEditor
194
192
  editor(file).run()
195
193
  except BaseException as e:
196
194
  argument_error('-e/--editor', e)
@@ -228,6 +226,7 @@ if args.file is not None:
228
226
  if args.inspect and not (sys.stdout.closed or sys.stderr.closed):
229
227
  if sys.stdin.closed:
230
228
  print("Can't run interactive shell: sys.stdin closed", file=sys.stderr)
229
+ code = 1
231
230
  else:
232
231
  code = pys_shell(
233
232
  globals=result.context.symbol_table,
@@ -1,5 +1,5 @@
1
1
  from .bases import Pys
2
- from .checks import is_unpack_assignment
2
+ from .checks import is_list
3
3
  from .constants import TOKENS, DEFAULT
4
4
  from .context import PysContext
5
5
  from .exceptions import PysTraceback
@@ -516,7 +516,7 @@ class PysAnalyzer(Pys):
516
516
 
517
517
  self.visit_slice_SubscriptNode(node.slice)
518
518
 
519
- elif is_unpack_assignment(type):
519
+ elif is_list(type):
520
520
  for element in node.elements:
521
521
  self.visit_declaration_AssignNode(element, message, operator_name)
522
522
  if self.error:
@@ -7,8 +7,8 @@ from .utils.decorators import inheritable, singleton
7
7
  from typing import Any, Callable, Literal
8
8
 
9
9
  loading_modules = set()
10
- modules = {}
11
10
  path = [SITE_PACKAGES_PATH, LIBRARIES_PATH]
11
+ modules = {}
12
12
  singletons = {}
13
13
 
14
14
  @singleton
@@ -14,7 +14,7 @@ is_statement = frozenset([
14
14
  PysAssertNode, PysDeleteNode, PysContinueNode, PysBreakNode
15
15
  ]).__contains__
16
16
 
17
- is_unpack_assignment = frozenset([
17
+ is_list = frozenset([
18
18
  PysSetNode, PysListNode, PysTupleNode
19
19
  ]).__contains__
20
20
 
@@ -14,6 +14,7 @@ ENV_PYSCRIPT_NO_EXCEPTHOOK = 'PYSCRIPT_NO_EXCEPTHOOK'
14
14
  ENV_PYSCRIPT_NO_GIL = 'PYSCRIPT_NO_GIL'
15
15
  ENV_PYSCRIPT_NO_READLINE = 'PYSCRIPT_NO_READLINE'
16
16
  ENV_PYSCRIPT_NO_TYPECHECK = 'PYSCRIPT_NO_TYPECHECK'
17
+ ENV_PYSCRIPT_MAXIMUM_TRACEBACK_LINE = 'PYSCRIPT_MAXIMUM_TRACEBACK_LINE'
17
18
 
18
19
  # tokens offset
19
20
  DOUBLE = 2**8
@@ -96,9 +97,10 @@ TOKENS = MappingProxyType({
96
97
  # keywords
97
98
  KEYWORDS = (
98
99
  '__debug__', 'False', 'None', 'True', 'and', 'as', 'assert', 'break', 'case', 'catch', 'class', 'constructor',
99
- 'continue', 'def', 'default', 'define', 'del', 'delete', 'do', 'elif', 'else', 'except', 'extends', 'false',
100
- 'finally', 'for', 'from', 'func', 'function', 'global', 'if', 'import', 'in', 'is', 'match', 'nil', 'none', 'null',
101
- 'not', 'true', 'typeof', 'of', 'or', 'raise', 'repeat', 'return', 'switch', 'throw', 'try', 'until', 'while', 'with'
100
+ 'continue', 'def', 'default', 'define', 'del', 'delete', 'do', 'elif', 'else', 'elseif', 'except', 'extends',
101
+ 'false', 'finally', 'for', 'from', 'func', 'function', 'global', 'if', 'import', 'in', 'is', 'match', 'nil', 'none',
102
+ 'null', 'not', 'true', 'typeof', 'of', 'or', 'raise', 'repeat', 'return', 'switch', 'throw', 'try', 'until',
103
+ 'while', 'with'
102
104
  )
103
105
 
104
106
  CONSTANT_KEYWORDS = (
@@ -28,7 +28,7 @@ class PysEditor(Pys):
28
28
  setimuattr(self.file, 'text', text)
29
29
  self.modified = False
30
30
 
31
- def run(self):
31
+ def run(self) -> None:
32
32
  if self.used:
33
33
  raise RuntimeError("one application object can only be used once")
34
34
  self.used = True
@@ -1,12 +1,10 @@
1
1
  from .bases import PysEditor
2
2
  from ..buffer import PysFileBuffer
3
+ from ..constants import ICON_PATH
4
+ from ..highlight import PygmentsPyScriptStyle, PygmentsPyScriptLexer
5
+ from ..version import __version__
3
6
 
4
7
  try:
5
-
6
- from ..constants import ICON_PATH
7
- from ..highlight import PygmentsPyScriptStyle, PygmentsPyScriptLexer
8
- from ..version import __version__
9
-
10
8
  from tkinter import END, Tk, Scrollbar, Text, messagebox
11
9
  from tkinter.font import Font
12
10
 
@@ -63,6 +61,10 @@ try:
63
61
  self.setup_tags()
64
62
  self.update()
65
63
 
64
+ def run(self) -> None:
65
+ PysEditor.run(self)
66
+ Tk.mainloop(self)
67
+
66
68
  def setup_tags(self):
67
69
  tag_configure = self.text.tag_configure
68
70
  for token, style in self.style.list_styles():
@@ -125,10 +127,6 @@ try:
125
127
  self.text.configure(wrap='char' if self.wrapped else 'none')
126
128
  return 'break'
127
129
 
128
- def run(self):
129
- PysEditor.run(self)
130
- Tk.mainloop(self)
131
-
132
130
  except ImportError as e:
133
131
  _error = e
134
132
 
@@ -1,11 +1,9 @@
1
1
  from .bases import PysEditor
2
2
  from ..buffer import PysFileBuffer
3
+ from ..highlight import PygmentsPyScriptStyle, PygmentsPyScriptLexer
4
+ from ..version import __version__
3
5
 
4
6
  try:
5
-
6
- from ..highlight import PygmentsPyScriptStyle, PygmentsPyScriptLexer
7
- from ..version import __version__
8
-
9
7
  from prompt_toolkit.application import Application
10
8
  from prompt_toolkit.filters import Condition
11
9
  from prompt_toolkit.formatted_text import ANSI
@@ -65,6 +63,10 @@ try:
65
63
  def _(event):
66
64
  self.wrapped = not self.wrapped
67
65
 
66
+ @self.key_bindings.add('c-z', filter=on_edit, eager=True)
67
+ def _(event):
68
+ self.current_buffer.undo()
69
+
68
70
  @self.key_bindings.add('c-s', filter=on_edit, eager=True)
69
71
  def _(event):
70
72
  self.save(self.text.text)
@@ -119,20 +121,24 @@ try:
119
121
  style=style_from_pygments_cls(PygmentsPyScriptStyle),
120
122
  key_bindings=self.key_bindings,
121
123
  full_screen=True,
122
- mouse_support=True
124
+ mouse_support=True,
125
+ paste_mode=True
123
126
  )
124
127
 
128
+ def run(self) -> None:
129
+ PysEditor.run(self)
130
+ Application.run(self)
131
+
125
132
  def on_change(self, buffer):
126
133
  self.modified = True
127
134
 
128
135
  def create_title(self):
129
- title = f' PyScript {__version__} - {self.basename}{"*" if self.modified else ""} '
130
- space = max(0, self.output.get_size().columns - len(title))
131
- return ANSI(f'\x1b[7m{title}{" " * space}\x1b[0m')
132
-
133
- def run(self):
134
- PysEditor.run(self)
135
- Application.run(self)
136
+ columns = self.output.get_size().columns
137
+ file = f'{self.basename}{"*" if self.modified else ""}'
138
+ title = f' PyScript {__version__} - {file} '
139
+ if len(title) > columns:
140
+ title = file
141
+ return ANSI(f'\x1b[7m{title}{" " * max(0, columns - len(title))}\x1b[0m')
136
142
 
137
143
  except ImportError as e:
138
144
  _error = e
@@ -6,6 +6,7 @@ from types import MethodType
6
6
 
7
7
  if environ.get(ENV_PYSCRIPT_NO_GIL) is None:
8
8
  from threading import RLock
9
+
9
10
  lock = RLock()
10
11
 
11
12
  def handle_call(object, context, position):
@@ -28,7 +29,7 @@ if environ.get(ENV_PYSCRIPT_NO_GIL) is None:
28
29
  if method is not None:
29
30
  handle_call(method, context, position)
30
31
 
31
- _GIL = True
32
+ GIL = True
32
33
  else:
33
34
 
34
35
  def handle_call(object, context, position):
@@ -49,4 +50,4 @@ else:
49
50
  if method is not None:
50
51
  handle_call(method, context, position)
51
52
 
52
- _GIL = False
53
+ GIL = False
@@ -373,21 +373,21 @@ class _PysHighlightFormatter(Pys):
373
373
  self._open = False
374
374
 
375
375
  def __call__(self, type: str, position: PysPosition, content: str) -> str:
376
- result = ''
377
-
378
376
  if type == 'end':
379
377
  if self._open:
380
- result += self.close_block(position, self._type)
378
+ result = self.close_block(position, self._type)
381
379
  self._open = False
380
+ else:
381
+ result = ''
382
382
  type = 'start'
383
383
 
384
384
  elif type == self._type and self._open:
385
- result += self.content_block(position, content)
385
+ result = self.content_block(position, content)
386
386
 
387
387
  else:
388
+ result = ''
388
389
  if self._open:
389
390
  result += self.close_block(position, self._type)
390
-
391
391
  result += self.open_block(position, type) + self.content_block(position, content)
392
392
  self._open = True
393
393
 
@@ -450,10 +450,10 @@ def pys_highlight(
450
450
  )
451
451
 
452
452
  tokens, _ = lexer.make_tokens()
453
-
454
453
  text = file.text
454
+
455
455
  result = ''
456
- last_index_position = 0
456
+ last_index = 0
457
457
  brackets_stack = []
458
458
 
459
459
  for i, token in enumerate(tokens):
@@ -461,66 +461,66 @@ def pys_highlight(
461
461
  tvalue = token.value
462
462
 
463
463
  if ttype == TOKENS['NULL']:
464
- type_fmt = 'end'
464
+ type_format = 'end'
465
465
 
466
466
  elif ttype == TOKENS['KEYWORD']:
467
- type_fmt = 'keyword-constant' if is_constant_keywords(tvalue) else 'keyword'
467
+ type_format = 'keyword-constant' if is_constant_keywords(tvalue) else 'keyword'
468
468
 
469
469
  elif ttype == TOKENS['IDENTIFIER']:
470
470
  if tvalue in BUILTIN_TYPES:
471
- type_fmt = 'identifier-type'
471
+ type_format = 'identifier-type'
472
472
  elif tvalue in BUILTIN_FUNCTIONS:
473
- type_fmt = 'identifier-function'
473
+ type_format = 'identifier-function'
474
474
  else:
475
475
  j = i - 1
476
476
  while j > 0 and tokens[j].type in (TOKENS['NEWLINE'], TOKENS['COMMENT']):
477
477
  j -= 1
478
478
  previous_token = tokens[j]
479
479
  if previous_token.match(TOKENS['KEYWORD'], 'class'):
480
- type_fmt = 'identifier-type'
480
+ type_format = 'identifier-type'
481
481
  elif previous_token.match(TOKENS['KEYWORD'], 'def', 'define', 'func', 'function'):
482
- type_fmt = 'identifier-function'
482
+ type_format = 'identifier-function'
483
483
  else:
484
484
  j = i + 1
485
485
  if (j < len(tokens) and tokens[j].type == TOKENS['LEFT-PARENTHESIS']):
486
- type_fmt = 'identifier-function'
486
+ type_format = 'identifier-function'
487
487
  else:
488
- type_fmt = 'identifier-constant' if tvalue.isupper() else 'identifier'
488
+ type_format = 'identifier-constant' if tvalue.isupper() else 'identifier'
489
489
 
490
490
  elif ttype == TOKENS['NUMBER']:
491
- type_fmt = 'number'
491
+ type_format = 'number'
492
492
 
493
493
  elif ttype == TOKENS['STRING']:
494
- type_fmt = 'string'
494
+ type_format = 'string'
495
495
 
496
496
  elif ttype == TOKENS['NEWLINE']:
497
- type_fmt = 'newline'
497
+ type_format = 'newline'
498
498
 
499
499
  elif ttype == TOKENS['COMMENT']:
500
- type_fmt = 'comment'
500
+ type_format = 'comment'
501
501
 
502
502
  elif is_bracket(ttype):
503
- type_fmt = f'brackets-{len(brackets_stack) % max_bracket_level}'
503
+ type_format = f'brackets-{len(brackets_stack) % max_bracket_level}'
504
504
  if is_left_bracket(ttype):
505
505
  brackets_stack.append(ttype)
506
506
  elif not (brackets_stack and BRACKETS_MAP[brackets_stack.pop()] == ttype):
507
- type_fmt = 'invalid'
507
+ type_format = 'invalid'
508
508
  else:
509
- type_fmt = f'brackets-{len(brackets_stack) % max_bracket_level}'
509
+ type_format = f'brackets-{len(brackets_stack) % max_bracket_level}'
510
510
 
511
511
  elif ttype == TOKENS['NONE']:
512
- type_fmt = 'invalid'
512
+ type_format = 'invalid'
513
513
 
514
514
  else:
515
- type_fmt = 'default'
515
+ type_format = 'default'
516
516
 
517
- if space := text[last_index_position:token.position.start]:
518
- result += format('default', PysPosition(file, last_index_position, token.position.start), space)
519
- result += format(type_fmt, token.position, text[token.position.start:token.position.end])
517
+ if space := text[last_index:token.position.start]:
518
+ result += format('default', PysPosition(file, last_index, token.position.start), space)
519
+ result += format(type_format, token.position, text[token.position.start:token.position.end])
520
520
 
521
521
  if ttype == TOKENS['NULL']:
522
522
  break
523
523
 
524
- last_index_position = token.position.end
524
+ last_index = token.position.end
525
525
 
526
526
  return result
@@ -1,6 +1,6 @@
1
1
  from .constants import TOKENS, DEBUG
2
2
  from .cache import undefined
3
- from .checks import is_unpack_assignment, is_equals, is_public_attribute
3
+ from .checks import is_list, is_equals, is_public_attribute
4
4
  from .context import PysClassContext
5
5
  from .exceptions import PysTraceback
6
6
  from .handlers import handle_call
@@ -255,17 +255,17 @@ def visit_ChainOperatorNode(node, context):
255
255
  with result(context, nposition):
256
256
 
257
257
  for i, toperand in enumerate(node.operations, start=1):
258
- omatch = toperand.match
259
258
  otype = toperand.type
259
+ ovalue = toperand.value
260
260
  nexpression = get_expression(i)
261
261
 
262
262
  right = register(get_visitor(nexpression.__class__)(nexpression, context))
263
263
  if should_return():
264
264
  return result
265
265
 
266
- if omatch(T_KEYWORD, 'in'):
266
+ if otype == T_KEYWORD and ovalue == 'in':
267
267
  value = left in right
268
- elif omatch(T_KEYWORD, 'is'):
268
+ elif otype == T_KEYWORD and ovalue == 'is':
269
269
  value = left is right
270
270
  elif otype == T_CE:
271
271
  handle_call(ce, context, nposition)
@@ -313,8 +313,8 @@ def visit_BinaryOperatorNode(node, context):
313
313
 
314
314
  register = result.register
315
315
  should_return = result.should_return
316
- omatch = node.operand.match
317
316
  otype = node.operand.type
317
+ ovalue = node.operand.value
318
318
  nleft = node.left
319
319
  nright = node.right
320
320
 
@@ -325,10 +325,10 @@ def visit_BinaryOperatorNode(node, context):
325
325
  with result(context, node.position):
326
326
  should_return_right = True
327
327
 
328
- if omatch(T_KEYWORD, 'and') or otype == T_AND:
328
+ if (otype == T_KEYWORD and ovalue == 'and') or otype == T_AND:
329
329
  if not left:
330
330
  return result.success(left)
331
- elif omatch(T_KEYWORD, 'or') or otype == T_OR:
331
+ elif (otype == T_KEYWORD and ovalue == 'or') or otype == T_OR:
332
332
  if left:
333
333
  return result.success(left)
334
334
  elif otype == T_NULLISH:
@@ -355,8 +355,8 @@ def visit_UnaryOperatorNode(node, context):
355
355
 
356
356
  register = result.register
357
357
  should_return = result.should_return
358
- omatch = node.operand.match
359
358
  otype = node.operand.type
359
+ ovalue = node.operand.value
360
360
  nvalue = node.value
361
361
 
362
362
  value = register(get_visitor(nvalue.__class__)(nvalue, context))
@@ -364,9 +364,9 @@ def visit_UnaryOperatorNode(node, context):
364
364
  return result
365
365
 
366
366
  with result(context, node.position):
367
- if omatch(T_KEYWORD, 'not') or otype == T_NOT:
367
+ if (otype == T_KEYWORD and ovalue == 'not') or otype == T_NOT:
368
368
  return result.success(not value)
369
- elif omatch(T_KEYWORD, 'typeof'):
369
+ elif (otype == T_KEYWORD and ovalue == 'typeof'):
370
370
  return result.success(type(value).__name__)
371
371
  return result.success(UNARY_FUNCTIONS_MAP(otype)(value))
372
372
 
@@ -1492,7 +1492,7 @@ def visit_declaration_AssignNode(node, context, value, operand=TOKENS['EQUAL']):
1492
1492
  if should_return():
1493
1493
  return result
1494
1494
 
1495
- elif is_unpack_assignment(ntype):
1495
+ elif is_list(ntype):
1496
1496
  position = node.position
1497
1497
 
1498
1498
  if not isinstance(value, Iterable):
@@ -47,7 +47,7 @@ class PysFunction(PysObject):
47
47
  self.__name__ = name = '<function>' if name is None else name
48
48
  self.__qualname__ = name if qualname is None else f'{qualname}.{name}'
49
49
  self.__code__ = PysCode(
50
- parameters=parameters,
50
+ parameters=tuple(parameters),
51
51
  body=body,
52
52
  context=context,
53
53
  position=position,
@@ -58,7 +58,7 @@ class PysFunction(PysObject):
58
58
  argument_names=tuple(argument_names),
59
59
  keyword_argument_names=tuple(keyword_argument_names),
60
60
  parameter_names=tuple(parameter_names),
61
- keyword_arguments=keyword_arguments
61
+ combine_keyword_arguments=keyword_arguments.__or__
62
62
  )
63
63
 
64
64
  def __repr__(self):
@@ -88,7 +88,7 @@ class PysFunction(PysObject):
88
88
  set_symbol(name, arg)
89
89
  add_argument(name)
90
90
 
91
- combined_keyword_arguments = code.keyword_arguments | kwargs
91
+ combined_keyword_arguments = code.combine_keyword_arguments(kwargs)
92
92
  pop_keyword_arguments = combined_keyword_arguments.pop
93
93
 
94
94
  for name, arg in zip(code.keyword_argument_names, args[len(registered_arguments):]):
@@ -177,11 +177,11 @@ class PysFunction(PysObject):
177
177
  )
178
178
  )
179
179
 
180
- if result.should_return() and not result.func_should_return:
180
+ if result.should_return():
181
+ if result.func_should_return:
182
+ return result.func_return_value
181
183
  raise PysSignal(result)
182
184
 
183
- return result.func_return_value
184
-
185
185
  class PysPythonFunction(PysFunction):
186
186
 
187
187
  def __init__(self, func):
@@ -1,5 +1,5 @@
1
1
  from .bases import Pys
2
- from .checks import is_left_bracket, is_right_bracket
2
+ from .checks import is_list, is_left_bracket, is_right_bracket
3
3
  from .constants import TOKENS, DEFAULT, DICT_TO_JSDICT
4
4
  from .context import PysContext
5
5
  from .exceptions import PysTraceback
@@ -1120,7 +1120,7 @@ class PysParser(Pys):
1120
1120
 
1121
1121
  while True:
1122
1122
 
1123
- if self.current_token.match(TOKENS['KEYWORD'], 'elif'):
1123
+ if self.current_token.match(TOKENS['KEYWORD'], 'elif', 'elseif'):
1124
1124
  result.register_advancement()
1125
1125
  self.advance()
1126
1126
  self.skip(result)
@@ -1861,13 +1861,15 @@ class PysParser(Pys):
1861
1861
 
1862
1862
  end = self.current_token.position.end
1863
1863
  name = self.current_token
1864
- bases = []
1864
+ has_bases = False
1865
1865
 
1866
1866
  result.register_advancement()
1867
1867
  self.advance()
1868
1868
  self.skip(result)
1869
1869
 
1870
1870
  if self.current_token.type == TOKENS['LEFT-PARENTHESIS']:
1871
+ has_bases = True
1872
+
1871
1873
  base = result.register(self.sequence_expression('tuple', should_sequence=True))
1872
1874
  if result.error:
1873
1875
  return result
@@ -1876,6 +1878,8 @@ class PysParser(Pys):
1876
1878
  bases = list(base.elements)
1877
1879
 
1878
1880
  elif self.current_token.match(TOKENS['KEYWORD'], 'extends'):
1881
+ has_bases = True
1882
+
1879
1883
  result.register_advancement()
1880
1884
  self.advance()
1881
1885
  self.skip(result)
@@ -1885,18 +1889,23 @@ class PysParser(Pys):
1885
1889
  return result
1886
1890
 
1887
1891
  end = base.position.end
1892
+ bases = list(base.elements) if is_list(base.__class__) else [base]
1888
1893
 
1889
- if isinstance(base, PysTupleNode):
1890
- if not base.elements:
1891
- return result.failure(self.new_error("empty base not allowed", bases.position))
1892
- bases = list(base.elements)
1894
+ else:
1895
+ bases = []
1893
1896
 
1894
- else:
1895
- bases.append(base)
1897
+ if self.current_token.type == TOKENS['COLON']:
1898
+ return result.failure(self.new_error("unlike python"))
1896
1899
 
1897
1900
  body = result.register(self.block_statements(), True)
1898
1901
  if result.error:
1899
- return result
1902
+ return result.failure(
1903
+ self.new_error(
1904
+ "expected statement, expression, '{', or ';'"
1905
+ if has_bases else
1906
+ "expected statement, expression, 'extends', '(', '{', or ';'"
1907
+ )
1908
+ )
1900
1909
 
1901
1910
  return result.success(
1902
1911
  PysClassNode(
@@ -2138,17 +2147,9 @@ class PysParser(Pys):
2138
2147
  if result.error:
2139
2148
  return result
2140
2149
 
2141
- if isinstance(expr, PysTupleNode):
2142
- targets = list(expr.elements)
2143
- if not targets:
2144
- return result.failure(self.new_error("empty target not allowed", expr.position))
2145
-
2146
- else:
2147
- targets = [expr]
2148
-
2149
2150
  return result.success(
2150
2151
  PysDeleteNode(
2151
- targets,
2152
+ list(expr.elements) if is_list(expr.__class__) else [expr],
2152
2153
  position
2153
2154
  )
2154
2155
  )