pyscript-programming-language 1.12.11__tar.gz → 1.12.12__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 (88) hide show
  1. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/PKG-INFO +5 -2
  2. pyscript_programming_language-1.12.12/changelog.md +10 -0
  3. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyproject.toml +5 -2
  4. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/__main__.py +61 -46
  5. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/cache.py +3 -2
  6. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/checks.py +2 -1
  7. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/constants.py +2 -0
  8. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/editor/gui.py +42 -7
  9. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/exceptions.py +4 -4
  10. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/highlight.py +26 -15
  11. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/interpreter.py +34 -17
  12. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/lexer.py +2 -2
  13. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/parser.py +4 -1
  14. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/pysbuiltins.py +41 -38
  15. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/pystypes.py +14 -10
  16. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/results.py +6 -8
  17. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/runner.py +12 -8
  18. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/shell.py +2 -2
  19. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/symtab.py +2 -2
  20. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/decorators.py +1 -2
  21. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/generic.py +6 -3
  22. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/version.py +2 -2
  23. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ast/ast_dump.py +4 -3
  24. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/site.pys +3 -5
  25. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/tokenize/tok_untokenize.py +2 -2
  26. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript_programming_language.egg-info/PKG-INFO +5 -2
  27. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/setup.py +5 -2
  28. pyscript_programming_language-1.12.11/changelog.md +0 -13
  29. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/MANIFEST.in +0 -0
  30. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/README.md +0 -0
  31. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/__init__.py +0 -0
  32. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/__init__.pyi +0 -0
  33. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/__init__.py +0 -0
  34. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/analyzer.py +0 -0
  35. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/bases.py +0 -0
  36. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/buffer.py +0 -0
  37. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/context.py +0 -0
  38. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/editor/__init__.py +0 -0
  39. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/editor/bases.py +0 -0
  40. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/editor/terminal.py +0 -0
  41. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/handlers.py +0 -0
  42. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/mapping.py +0 -0
  43. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/nodes.py +0 -0
  44. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/position.py +0 -0
  45. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/token.py +0 -0
  46. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/__init__.py +0 -0
  47. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/ansi.py +0 -0
  48. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/debug.py +0 -0
  49. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/module.py +0 -0
  50. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/path.py +0 -0
  51. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/similarity.py +0 -0
  52. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/string.py +0 -0
  53. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/__hello__.pys +0 -0
  54. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ansi.pys +0 -0
  55. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ast/__init__.pys +0 -0
  56. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ast/ast_literal_eval.py +0 -0
  57. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ast/ast_unparse.py +0 -0
  58. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ast/ast_walk.py +0 -0
  59. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/brainfuck.pys +0 -0
  60. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/code.pys +0 -0
  61. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/dis.pys +0 -0
  62. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/explorer.pys +0 -0
  63. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/fpstimer/__init__.pys +0 -0
  64. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/fpstimer/py_fpstimer.py +0 -0
  65. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/getch/__init__.pys +0 -0
  66. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/getch/py_getch.py +0 -0
  67. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/history.pys +0 -0
  68. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/inspect.pys +0 -0
  69. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/jsdict.pys +0 -0
  70. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/keyword.pys +0 -0
  71. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/opcode.pys +0 -0
  72. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/parser.pys +0 -0
  73. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/pdisplay.pys +0 -0
  74. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/symtable.pys +0 -0
  75. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/token.pys +0 -0
  76. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/tokenize/__init__.pys +0 -0
  77. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/other/.nomedia +0 -0
  78. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/other/PyScript.ico +0 -0
  79. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/other/copyright +0 -0
  80. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/other/credits +0 -0
  81. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/other/license +0 -0
  82. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/site-packages/this.pys +0 -0
  83. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/this.py +0 -0
  84. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
  85. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  86. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript_programming_language.egg-info/requires.txt +0 -0
  87. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  88. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/setup.cfg +0 -0
@@ -1,15 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.12.11
3
+ Version: 1.12.12
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://azzammuhyala.github.io/pyscript
6
6
  Author: azzammuhyala
7
7
  Author-email: azzammuhyala <azzammuhyala@gmail.com>
8
8
  License-Expression: MIT
9
9
  Project-URL: Homepage, https://azzammuhyala.github.io/pyscript
10
+ Project-URL: Documentation, https://azzammuhyala.github.io/pyscript
10
11
  Project-URL: Source, https://github.com/azzammuhyala/pyscript
11
- Project-URL: Bug Tracker, https://github.com/azzammuhyala/pyscript/issues
12
+ Project-URL: Releases, https://github.com/azzammuhyala/pyscript/releases
12
13
  Project-URL: Change Log, https://github.com/azzammuhyala/pyscript/blob/main/changelog.md
14
+ Project-URL: Bug Tracker, https://github.com/azzammuhyala/pyscript/issues
15
+ Project-URL: PyPi Stats, https://pepy.tech/projects/pyscript-programming-language
13
16
  Keywords: pyscript,pyslang,pys,programming,language,programming language
14
17
  Classifier: Programming Language :: Python
15
18
  Classifier: Programming Language :: Python :: 3
@@ -0,0 +1,10 @@
1
+ # Change Log
2
+
3
+ ## [1.12.12] - 29/04/2026
4
+
5
+ ### Added
6
+ - Saves screen geometry in gui editor.
7
+
8
+ ### Fixed
9
+ - Fixed some bugs.
10
+ - _etc._
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyscript-programming-language"
7
- version = "1.12.11"
7
+ version = "1.12.12"
8
8
  description = "PyScript Programming Language"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.10"
@@ -34,9 +34,12 @@ classifiers = [
34
34
 
35
35
  [project.urls]
36
36
  Homepage = "https://azzammuhyala.github.io/pyscript"
37
+ Documentation = "https://azzammuhyala.github.io/pyscript"
37
38
  Source = "https://github.com/azzammuhyala/pyscript"
38
- "Bug Tracker" = "https://github.com/azzammuhyala/pyscript/issues"
39
+ Releases = "https://github.com/azzammuhyala/pyscript/releases"
39
40
  "Change Log" = "https://github.com/azzammuhyala/pyscript/blob/main/changelog.md"
41
+ "Bug Tracker" = "https://github.com/azzammuhyala/pyscript/issues"
42
+ "PyPi Stats" = "https://pepy.tech/projects/pyscript-programming-language"
40
43
 
41
44
  [project.optional-dependencies]
42
45
  other = [
@@ -9,7 +9,7 @@ from .core.editor.terminal import PysTerminalEditor, TERMINAL_SUPPORT
9
9
  from .core.highlight import (
10
10
  PYGMENTS, HLFMT_HTML, HLFMT_ANSI, HLFMT_BBCODE, pys_highlight, PygmentsPyScriptStyle, PygmentsPyScriptLexer
11
11
  )
12
- from .core.runner import _normalize_namespace, pys_runner, pys_shell
12
+ from .core.runner import _namespace_to_symbol_table, pys_runner, pys_shell
13
13
  from .core.utils.debug import USE_NOTEBOOK
14
14
  from .core.utils.generic import is_environ
15
15
  from .core.utils.module import find_module_path, remove_python_path
@@ -43,7 +43,6 @@ FORMATER_HIGHLIGHT_MAP = {
43
43
  }
44
44
 
45
45
  EDITOR_MAP = {}
46
-
47
46
  for supported, name, class_editor in [
48
47
  (GUI_SUPPORT, 'gui', PysGUIEditor),
49
48
  (TERMINAL_SUPPORT, 'terminal', PysTerminalEditor)
@@ -51,6 +50,8 @@ for supported, name, class_editor in [
51
50
  if supported:
52
51
  EDITOR_MAP[name] = class_editor
53
52
 
53
+ arguments_requiring_value = {'-l', '--highlight', '-r', '--py-recursion'}
54
+
54
55
  parser = ArgumentParser(
55
56
  prog=f'{base(sys.executable)} -m pyscript',
56
57
  description=f'PyScript Launcher for Python Version {".".join(map(str, sys.version_info))}'
@@ -83,6 +84,7 @@ if EDITOR_MAP:
83
84
  default=None,
84
85
  help="open the editor panel from a 'file'",
85
86
  )
87
+ arguments_requiring_value.update({'-e', '--editor'})
86
88
 
87
89
  parser.add_argument(
88
90
  '-i', '--inspect',
@@ -174,21 +176,28 @@ def argument_error(argument, message):
174
176
  parser.exit(2, f"{parser.prog}: error: argument {argument}: {message}\n")
175
177
 
176
178
  argv = sys.argv[1:]
179
+ argc = len(argv)
180
+ index = 0
181
+ arg_index = -1
177
182
 
178
- file_idx = sum(1 for arg in argv if arg.startswith('-'))
179
- end_idx = argv.index('--', 0, file_idx) if '--' in argv[:file_idx] else -1
180
- end_com = file_idx if end_idx == -1 else end_idx
181
- arg_com = argv[:end_com]
183
+ while index < argc:
184
+ arg = argv[index]
185
+ if not arg.startswith('-') or arg == '--':
186
+ break
182
187
 
183
- com_idx = argv.index('-c', 0, end_com) if '-c' in arg_com else \
184
- (argv.index('--command', 0, end_com) if '--command' in arg_com else -1)
185
- mod_idx = argv.index('-m', 0, end_com) if '-m' in arg_com else \
186
- (argv.index('--module', 0, end_com) if '--module' in arg_com else -1)
188
+ if arg in ('-c', '--command'):
189
+ arg_index = index + 2
190
+ break
191
+ elif arg in ('-m', '--module'):
192
+ arg_index = index + 2
193
+ break
187
194
 
188
- ofs_idx = max(com_idx, mod_idx)
195
+ index += 1
196
+ if arg in arguments_requiring_value:
197
+ index += 1
189
198
 
190
- args = parser.parse_args(argv if ofs_idx == -1 else argv[:ofs_idx + 2])
191
- arg = args.arg if ofs_idx == -1 else argv[ofs_idx + 2:]
199
+ args = parser.parse_args(argv if arg_index == -1 else argv[:arg_index])
200
+ arg = args.arg if arg_index == -1 else argv[arg_index:]
192
201
 
193
202
  if args.terminal:
194
203
 
@@ -242,28 +251,27 @@ if args.P:
242
251
 
243
252
  pys_sys.argv = argv = ['', *arg]
244
253
 
245
- # clean up
246
- try:
247
- if PYGMENTS:
248
- del (
249
- BBCodeFormatter, HtmlFormatter, LatexFormatter, TerminalFormatter, TerminalTrueColorFormatter,
250
- Terminal256Formatter
251
- )
252
-
253
- del (
254
- ENV_PYSCRIPT_NO_COLOR_PROMPT, ENV_PYSCRIPT_CLASSIC_LINE_SHELL, DEFAULT, DEBUG, CLASSIC_LINE_SHELL,
255
- NO_COLOR_PROMPT, NOTEBOOK, GUI_SUPPORT, TERMINAL_SUPPORT, PYGMENTS, HLFMT_ANSI, HLFMT_HTML, HLFMT_BBCODE,
256
- USE_NOTEBOOK, OPTIONAL, REMAINDER, file_idx, end_idx, end_com, arg_com, com_idx, mod_idx, ofs_idx, arg, pys_sys,
257
- __version__, is_environ, remove_python_path, getcwd, base, PysGUIEditor, PysTerminalEditor, ArgumentParser
258
- )
259
-
260
- del (
261
- supported, name, class_editor, condition, flag, fd, kernel32, i
262
- )
263
- except:
264
- pass
254
+ def clean_up() -> None:
255
+ g = globals()
256
+
257
+ for name in {
258
+ 'ArgumentParser', 'BBCodeFormatter', 'CLASSIC_LINE_SHELL', 'DEBUG', 'DEFAULT', 'DONT_SHOW_BANNER_ON_SHELL',
259
+ 'EDITOR_MAP', 'ENV_PYSCRIPT_CLASSIC_LINE_SHELL', 'ENV_PYSCRIPT_NO_COLOR_PROMPT', 'FORMATER_HIGHLIGHT_MAP',
260
+ 'FORMATER_PYGMENTS_MAP', 'GUI_SUPPORT', 'HLFMT_ANSI', 'HLFMT_BBCODE', 'HLFMT_HTML', 'HtmlFormatter',
261
+ 'LatexFormatter', 'NOTEBOOK', 'NO_COLOR', 'NO_COLOR_PROMPT', 'OPTIONAL', 'PYGMENTS', 'PygmentsPyScriptLexer',
262
+ 'PygmentsPyScriptStyle', 'PysFileBuffer', 'PysGUIEditor', 'PysTerminalEditor', 'REMAINDER', 'TERMINAL_SUPPORT',
263
+ 'Terminal256Formatter', 'TerminalFormatter', 'TerminalTrueColorFormatter', 'USE_NOTEBOOK', '__version__',
264
+ '_namespace_to_symbol_table', 'arg', 'arg_index', 'argc', 'args', 'argument_error', 'arguments_requiring_value',
265
+ 'argv', 'base', 'class_editor', 'clean_up', 'condition', 'ctypes', 'execute', 'fd', 'file', 'find_module_path',
266
+ 'flag', 'getcwd', 'highlight', 'i', 'index', 'is_environ', 'kernel32', 'load_file', 'module_path', 'name',
267
+ 'normpath', 'parser', 'pys_highlight', 'pys_sys', 'remove_python_path', 'supported'
268
+ }:
269
+ try:
270
+ del g[name]
271
+ except:
272
+ continue
265
273
 
266
- def load_file(path):
274
+ def load_file(path) -> PysFileBuffer:
267
275
  file = PysFileBuffer('', path)
268
276
  try:
269
277
  with open(path, 'r', encoding='utf-8') as file:
@@ -285,31 +293,37 @@ def load_file(path):
285
293
  argument_error('file', f"file \"{path}\": Unexpected error: {e}")
286
294
  return file
287
295
 
288
- def execute(file):
296
+ def execute(file: PysFileBuffer) -> None:
297
+ global code
298
+
299
+ not_show_banner_flag = DONT_SHOW_BANNER_ON_SHELL
300
+ inspect = args.inspect
301
+ symtab = _namespace_to_symbol_table(undefined, file)
302
+
303
+ clean_up()
304
+
289
305
  result = pys_runner(
290
306
  file=file,
291
307
  mode='exec',
292
- symbol_table=_normalize_namespace(undefined, file),
308
+ symbol_table=symtab,
293
309
  flags=flags
294
310
  )
295
311
 
296
312
  code, _ = result.end_process()
297
313
 
298
- if args.inspect:
314
+ if inspect:
299
315
  if sys.stdout.closed or sys.stderr.closed:
300
- return 1
316
+ code = 1
301
317
  elif sys.stdin.closed:
302
318
  print("Can't run interactive shell: sys.stdin closed", file=sys.stderr)
303
- return 1
319
+ code = 1
304
320
  else:
305
- return pys_shell(
321
+ code = pys_shell(
306
322
  globals=result.context.symbol_table,
307
- flags=result.context.flags | DONT_SHOW_BANNER_ON_SHELL,
323
+ flags=result.context.flags | not_show_banner_flag,
308
324
  parser_flags=result.parser_flags
309
325
  )
310
326
 
311
- return code
312
-
313
327
  if args.file is not None:
314
328
  argv[0] = args.file
315
329
  file = load_file(normpath(args.file))
@@ -341,7 +355,7 @@ if args.file is not None:
341
355
  argument_error('-l/--highlight', e)
342
356
 
343
357
  else:
344
- code = execute(file)
358
+ execute(file)
345
359
 
346
360
  elif args.module is not None:
347
361
  _, module_path = find_module_path(None, args.module, '__main__')
@@ -350,13 +364,14 @@ elif args.module is not None:
350
364
 
351
365
  file = load_file(module_path)
352
366
  argv[0] = file.name
353
- code = execute(file)
367
+ execute(file)
354
368
 
355
369
  elif args.command is not None:
356
370
  argv[0] = '-c'
357
- code = execute(PysFileBuffer(args.command, '<arg-command>'))
371
+ execute(PysFileBuffer(args.command, '<arg-command>'))
358
372
 
359
373
  else:
374
+ clean_up()
360
375
  code = pys_shell(
361
376
  globals=undefined,
362
377
  flags=flags
@@ -2,6 +2,7 @@ from .bases import Pys
2
2
  from .constants import PYSCRIPT_PATH, CORE_PATH, LIBRARIES_PATH, SITE_PACKAGES_PATH, DEFAULT
3
3
  from .utils.debug import print_display, print_traceback, clear_shell
4
4
  from .utils.decorators import inheritable, singleton
5
+ from .utils.path import base
5
6
 
6
7
  from types import ModuleType
7
8
  from typing import Literal
@@ -17,7 +18,7 @@ pys_sys = ModuleType(
17
18
 
18
19
  pys_sys.__running_shell__ = False
19
20
  pys_sys.__running_breakpoint__ = False
20
- pys_sys.path = [SITE_PACKAGES_PATH, LIBRARIES_PATH]
21
+ pys_sys.path = [LIBRARIES_PATH, SITE_PACKAGES_PATH]
21
22
  pys_sys.loading_modules = set()
22
23
  pys_sys.modules = {}
23
24
  pys_sys.singletons = {}
@@ -30,7 +31,7 @@ pys_sys.pyscript_path = PYSCRIPT_PATH
30
31
  pys_sys.core_path = CORE_PATH
31
32
  pys_sys.libraries_path = LIBRARIES_PATH
32
33
  pys_sys.site_packages_path = SITE_PACKAGES_PATH
33
- pys_sys.executable = f'"{sys.executable}" -m pyscript'
34
+ pys_sys.executable = f'{base(sys.executable)} -m pyscript'
34
35
  pys_sys.ps1 = '>>> '
35
36
  pys_sys.ps2 = '... '
36
37
 
@@ -37,7 +37,8 @@ is_blacklist_python_builtin = frozenset([
37
37
  ]).__contains__
38
38
 
39
39
  is_python_extension = frozenset([
40
- '.py', '.ipy', '.pyc', '.pyd', '.pyi', '.pyo', '.pyp', '.pyw', '.pyz', '.rpy', '.xpy', '.pyproj'
40
+ '.cgi', '.fcgi', '.gyp', '.gypi', '.ipy', '.lmi', '.pxd', '.pxi', '.py', '.py3', '.pyc', '.pyd', '.pyde', '.pyi',
41
+ '.pyo', '.pyp', '.pyproj', '.pyt', '.pyw', '.pyx', '.pyz', '.rpy', '.spec', '.tac', '.wsgi', '.xpy'
41
42
  ]).__contains__
42
43
 
43
44
  is_left_bracket = frozenset(BRACKETS_MAP.keys()).__contains__
@@ -6,6 +6,8 @@ LIBRARIES_PATH = os.path.join(PYSCRIPT_PATH, 'lib')
6
6
  OTHER_PATH = os.path.join(PYSCRIPT_PATH, 'other')
7
7
  SITE_PACKAGES_PATH = os.path.join(PYSCRIPT_PATH, 'site-packages')
8
8
  ICON_PATH = os.path.join(OTHER_PATH, 'PyScript.ico')
9
+ GLOBAL_HISTORY_PATH = os.path.join(os.path.expanduser('~'), '.pyscript_history')
10
+ GUI_GEOMETRY_PATH = os.path.join(OTHER_PATH, 'gui_geometry.txt')
9
11
 
10
12
  ENV_PYSCRIPT_NO_EXCEPTHOOK = 'PYSCRIPT_NO_EXCEPTHOOK'
11
13
  ENV_PYSCRIPT_NO_GIL = 'PYSCRIPT_NO_GIL'
@@ -1,9 +1,11 @@
1
1
  from .bases import PysEditor
2
2
  from ..buffer import PysFileBuffer
3
- from ..constants import ICON_PATH
3
+ from ..constants import GUI_GEOMETRY_PATH, ICON_PATH
4
4
  from ..highlight import PygmentsPyScriptStyle, PygmentsPyScriptLexer
5
5
  from ..version import __version__
6
6
 
7
+ import re
8
+
7
9
  try:
8
10
  from tkinter import Tk, Scrollbar, Text, messagebox
9
11
  from tkinter.font import Font
@@ -15,7 +17,8 @@ try:
15
17
  Tk.__init__(self)
16
18
 
17
19
  def on_save(event=None):
18
- self.save(self.text.get('1.0', 'end'))
20
+ text = self.text.get('1.0', 'end')
21
+ self.save(text[:-1] if text.endswith(('\r\n', '\r', '\n')) else text)
19
22
  update()
20
23
  return 'break'
21
24
 
@@ -30,6 +33,10 @@ try:
30
33
  else:
31
34
  self.destroy()
32
35
 
36
+ def on_configure(event):
37
+ if event.widget == self:
38
+ save_geometry(event.x, event.y, event.width, event.height, self.wm_state() == 'zoomed')
39
+
33
40
  def on_modified(event=None):
34
41
  text = self.text
35
42
  if text.edit_modified():
@@ -69,10 +76,15 @@ try:
69
76
  text.insert('insert', '\n' + line[:len(line) - len(line.lstrip())])
70
77
  return 'break'
71
78
 
72
- try:
73
- self.wm_iconbitmap(ICON_PATH)
74
- except:
75
- pass
79
+ def save_geometry(left, top, width, height, zoom):
80
+ try:
81
+ with open(GUI_GEOMETRY_PATH, 'w') as f:
82
+ zoom = bool(zoom)
83
+ if not zoom:
84
+ self.last_geometry = f'{width}x{height}+{left}+{top}'
85
+ f.write(f'{self.last_geometry},{int(zoom)}')
86
+ except:
87
+ pass
76
88
 
77
89
  self.lexer = PygmentsPyScriptLexer()
78
90
  self.font = Font(family='Consolas', size=10)
@@ -102,6 +114,7 @@ try:
102
114
  self.text.bind('<Prior>', on_page_up)
103
115
  self.text.bind('<Next>', on_page_down)
104
116
 
117
+ self.bind('<Configure>', on_configure)
105
118
  self.bind_all('<Control-S>', on_save)
106
119
  self.bind_all('<Control-s>', on_save)
107
120
  self.bind_all('<Control-W>', on_toggle_wrap)
@@ -111,7 +124,29 @@ try:
111
124
  self.bind_all('<Control-equal>', on_change_font(1, lambda size : size < 128))
112
125
  self.bind_all('<Control-plus>', on_change_font(5, lambda size : size < 128))
113
126
 
114
- # self.wm_geometry('800x600')
127
+ try:
128
+ with open(GUI_GEOMETRY_PATH, 'r') as f:
129
+ width, height, left, top, zoom = map(
130
+ int,
131
+ re.match(r'(\d{1,7})x(\d{1,7})\+(-?\d{1,7})\+(-?\d{1,7}),(0|1)', f.read(64)).groups()
132
+ )
133
+ self.last_geometry = f'{width}x{height}+{left}+{top}'
134
+ except:
135
+ left = self.winfo_screenwidth() // 2 - 250
136
+ top = self.winfo_screenheight() // 2 - 250
137
+ zoom = False
138
+ self.last_geometry = f'500x500+{left}+{top}'
139
+ save_geometry(left, top, 500, 500, zoom)
140
+
141
+ try:
142
+ self.wm_iconbitmap(ICON_PATH)
143
+ except:
144
+ pass
145
+
146
+ if zoom:
147
+ self.wm_state('zoomed')
148
+
149
+ self.wm_geometry(self.last_geometry)
115
150
  self.wm_minsize(300, 250)
116
151
  self.wm_protocol('WM_DELETE_WINDOW', on_close)
117
152
 
@@ -27,16 +27,16 @@ class PysTraceback(Pys):
27
27
  # circular import problem solved
28
28
  from .cache import pys_sys
29
29
 
30
- pys_sys.last_type = type(exception) if isinstance(exception, BaseException) else exception
31
- pys_sys.last_value = exception if isinstance(exception, BaseException) else None
32
- pys_sys.last_traceback = self
33
-
34
30
  setimuattr(self, 'exception', exception)
35
31
  setimuattr(self, 'context', context)
36
32
  setimuattr(self, 'position', position)
37
33
  setimuattr(self, 'primary', primary)
38
34
  setimuattr(self, 'implicit', implicit)
39
35
 
36
+ pys_sys.last_type = type(exception) if isinstance(exception, BaseException) else exception
37
+ pys_sys.last_value = exception if isinstance(exception, BaseException) else None
38
+ pys_sys.last_traceback = self
39
+
40
40
  def __repr__(self) -> str:
41
41
  return f'<traceback of {self.exception!r}>'
42
42
 
@@ -272,7 +272,7 @@ try:
272
272
 
273
273
  'string-escapes': [
274
274
  (rf'\\([nrtbfav\'"\\]|{_newlines})', String.Escape),
275
- (r'\\[0-7]{1,3}}', String.Escape.Oct),
275
+ (r'\\[0-7]{1,3}', String.Escape.Oct),
276
276
  (r'\\x[0-9A-Fa-f]{2}', String.Escape.Hex),
277
277
  (r'\\u[0-9A-Fa-f]{4}', String.Escape.Uni),
278
278
  (r'\\U[0-9A-Fa-f]{8}', String.Escape.Uni),
@@ -485,47 +485,58 @@ def pys_highlight(
485
485
  last_index = 0
486
486
  brackets_stack = []
487
487
 
488
+ T_NULL = TOKENS['NULL']
489
+ T_KEYWORD = TOKENS['KEYWORD']
490
+ T_IDENTIFIER = TOKENS['IDENTIFIER']
491
+ T_NUMBER = TOKENS['NUMBER']
492
+ T_STRING = TOKENS['STRING']
493
+ T_NEWLINE = TOKENS['NEWLINE']
494
+ T_COMMENT = TOKENS['COMMENT']
495
+ T_LEFT_PARENTHESIS = TOKENS['LEFT_PARENTHESIS']
496
+ T_NONE = TOKENS['NONE']
497
+ T_WHITESPACES = frozenset([T_NEWLINE, T_COMMENT])
498
+
488
499
  for i, token in enumerate(tokens):
489
500
  ttype = token.type
490
501
  tvalue = token.value
491
502
 
492
- if ttype == TOKENS['NULL']:
503
+ if ttype == T_NULL:
493
504
  type_format = 'end'
494
505
 
495
- elif ttype == TOKENS['KEYWORD']:
506
+ elif ttype == T_KEYWORD:
496
507
  type_format = 'keyword-constant' if is_constant_keyword(tvalue) else 'keyword'
497
508
 
498
- elif ttype == TOKENS['IDENTIFIER']:
509
+ elif ttype == T_IDENTIFIER:
499
510
  if tvalue in BUILTIN_TYPES:
500
511
  type_format = 'identifier-type'
501
512
  elif tvalue in BUILTIN_FUNCTIONS:
502
513
  type_format = 'identifier-function'
503
514
  else:
504
515
  j = i - 1
505
- while j > 0 and tokens[j].type in (TOKENS['NEWLINE'], TOKENS['COMMENT']):
516
+ while j > 0 and tokens[j].type in T_WHITESPACES:
506
517
  j -= 1
507
- previous_token = tokens[j]
508
- if previous_token.match(TOKENS['KEYWORD'], 'class'):
518
+ last_is = tokens[j].match
519
+ if last_is(T_KEYWORD, 'class'):
509
520
  type_format = 'identifier-type'
510
- elif previous_token.match(TOKENS['KEYWORD'], 'func', 'function'):
521
+ elif last_is(T_KEYWORD, 'func', 'function'):
511
522
  type_format = 'identifier-function'
512
523
  else:
513
524
  j = i + 1
514
- if (j < len(tokens) and tokens[j].type == TOKENS['LEFT_PARENTHESIS']):
525
+ if (j < len(tokens) and tokens[j].type == T_LEFT_PARENTHESIS):
515
526
  type_format = 'identifier-function'
516
527
  else:
517
528
  type_format = 'identifier-constant' if tvalue.isupper() else 'identifier'
518
529
 
519
- elif ttype == TOKENS['NUMBER']:
530
+ elif ttype == T_NUMBER:
520
531
  type_format = 'number'
521
532
 
522
- elif ttype == TOKENS['STRING']:
533
+ elif ttype == T_STRING:
523
534
  type_format = 'string'
524
535
 
525
- elif ttype == TOKENS['NEWLINE']:
536
+ elif ttype == T_NEWLINE:
526
537
  type_format = 'newline'
527
538
 
528
- elif ttype == TOKENS['COMMENT']:
539
+ elif ttype == T_COMMENT:
529
540
  type_format = 'comment'
530
541
 
531
542
  elif is_bracket(ttype):
@@ -537,7 +548,7 @@ def pys_highlight(
537
548
  else:
538
549
  type_format = f'brackets-{len(brackets_stack) % max_bracket_level}'
539
550
 
540
- elif ttype == TOKENS['NONE']:
551
+ elif ttype == T_NONE:
541
552
  type_format = 'invalid'
542
553
 
543
554
  else:
@@ -547,7 +558,7 @@ def pys_highlight(
547
558
  result += formatter('default', PysPosition(file, last_index, token.position.start), space)
548
559
  result += formatter(type_format, token.position, text[token.position.start:token.position.end])
549
560
 
550
- if ttype == TOKENS['NULL']:
561
+ if ttype == T_NULL:
551
562
  break
552
563
 
553
564
  last_index = token.position.end
@@ -75,11 +75,7 @@ def visit_IdentifierNode(node: PysIdentifierNode, context: PysContext) -> PysRun
75
75
  PysTraceback(
76
76
  NameError(
77
77
  f"name {name!r} is not defined" +
78
- (
79
- ''
80
- if closest_symbol is None else
81
- f". Did you mean {closest_symbol!r}?"
82
- )
78
+ ('' if closest_symbol is None else f". Did you mean {closest_symbol!r}?")
83
79
  ),
84
80
  context,
85
81
  position
@@ -224,12 +220,13 @@ def visit_CallNode(node: PysCallNode, context: PysContext) -> PysRunTimeResult:
224
220
  args = []
225
221
  kwargs = {}
226
222
 
223
+ b_tuple = tuple
227
224
  add_arg = args.append
228
225
  add_kwarg = kwargs.__setitem__
229
226
 
230
227
  for nargument in node.arguments:
231
228
 
232
- if nargument.__class__ is tuple:
229
+ if nargument.__class__ is b_tuple:
233
230
  keyword, nvalue = nargument
234
231
  add_kwarg(keyword.value, register(get_visitor(nvalue.__class__)(nvalue, context)))
235
232
  if should_return():
@@ -254,6 +251,7 @@ def visit_ChainOperatorNode(node: PysChainOperatorNode, context: PysContext) ->
254
251
  register = result.register
255
252
  should_return = result.should_return
256
253
  get_expression = node.expressions.__getitem__
254
+
257
255
  first = get_expression(0)
258
256
 
259
257
  left = register(get_visitor(first.__class__)(first, context))
@@ -517,9 +515,13 @@ def visit_ImportNode(node: PysImportNode, context: PysContext) -> PysRunTimeResu
517
515
  exported_from = '__dir__()'
518
516
  exported_packages = filter(is_public_attribute, dir(module))
519
517
 
518
+ b_isinstance = isinstance
519
+ b_getattr = getattr
520
+ b_str = str
521
+
520
522
  for package in exported_packages:
521
523
 
522
- if not isinstance(package, str):
524
+ if not b_isinstance(package, b_str):
523
525
  return result.failure(
524
526
  PysTraceback(
525
527
  TypeError(
@@ -530,17 +532,18 @@ def visit_ImportNode(node: PysImportNode, context: PysContext) -> PysRunTimeResu
530
532
  )
531
533
  )
532
534
 
533
- set_symbol(package, getattr(module, package))
535
+ set_symbol(package, b_getattr(module, package))
534
536
 
535
537
  if should_return():
536
538
  return result
537
539
 
538
540
  elif npackages:
541
+ b_getattr = getattr
539
542
 
540
543
  for tpackage, tas_package in npackages:
541
544
  result._position = tpackage.position
542
545
  with result:
543
- set_symbol((tpackage if tas_package is None else tas_package).value, getattr(module, tpackage.value))
546
+ set_symbol((tpackage if tas_package is None else tas_package).value, b_getattr(module, tpackage.value))
544
547
  if should_return():
545
548
  return result
546
549
 
@@ -599,9 +602,11 @@ def visit_SwitchNode(node: PysSwitchNode, context: PysContext) -> PysRunTimeResu
599
602
  return result
600
603
 
601
604
  for ncondition, body in node.case_cases:
602
- case = register(get_visitor(ncondition.__class__)(ncondition, context))
603
- if should_return():
604
- return result
605
+
606
+ if not fall_through:
607
+ case = register(get_visitor(ncondition.__class__)(ncondition, context))
608
+ if should_return():
609
+ return result
605
610
 
606
611
  result._position = ncondition.position
607
612
  with result:
@@ -690,6 +695,12 @@ def visit_TryNode(node: PysTryNode, context: PysContext) -> PysRunTimeResult:
690
695
  if error:
691
696
  failure = result.failure
692
697
  exception = error.exception
698
+
699
+ b_isinstance = isinstance
700
+ b_issubclass = issubclass
701
+ b_type = type
702
+ b_BaseException = BaseException
703
+
693
704
  failure(None)
694
705
 
695
706
  for (targets, tparameter), body in node.catch_cases:
@@ -706,7 +717,7 @@ def visit_TryNode(node: PysTryNode, context: PysContext) -> PysRunTimeResult:
706
717
  stop = True
707
718
  break
708
719
 
709
- if not (isinstance(error_class, type) and issubclass(error_class, BaseException)):
720
+ if not (b_isinstance(error_class, b_type) and b_issubclass(error_class, b_BaseException)):
710
721
  failure(
711
722
  PysTraceback(
712
723
  TypeError("catching classes that do not inherit from BaseException is not allowed"),
@@ -870,13 +881,15 @@ def visit_ForNode(node: PysForNode, context: PysContext) -> PysRunTimeResult:
870
881
  if should_return():
871
882
  return result
872
883
 
884
+ b_StopIteration = StopIteration
885
+
873
886
  def condition():
874
887
  with result:
875
888
  handle_call(next, context, niteration_position)
876
889
  register(visit_declaration_from_AssignmentNode(ndeclaration, context, next()))
877
890
  if should_return():
878
891
  error = result.error
879
- if error and is_object_of(error.exception, StopIteration):
892
+ if error and is_object_of(error.exception, b_StopIteration):
880
893
  result.failure(None)
881
894
  return False
882
895
  return True
@@ -1163,9 +1176,11 @@ def visit_FunctionNode(node: PysFunctionNode, context: PysContext) -> PysRunTime
1163
1176
  should_return = result.should_return
1164
1177
  add_parameter = parameters.append
1165
1178
 
1179
+ b_tuple = tuple
1180
+
1166
1181
  for nparameter in node.parameters:
1167
1182
 
1168
- if nparameter.__class__ is tuple:
1183
+ if nparameter.__class__ is b_tuple:
1169
1184
  keyword, nvalue = nparameter
1170
1185
 
1171
1186
  value = register(get_visitor(nvalue.__class__)(nvalue, context))
@@ -1240,7 +1255,9 @@ def visit_ThrowNode(node: PysThrowNode, context: PysContext) -> PysRunTimeResult
1240
1255
  if should_return():
1241
1256
  return result
1242
1257
 
1243
- if not is_object_of(target, BaseException):
1258
+ b_BaseException = BaseException
1259
+
1260
+ if not is_object_of(target, b_BaseException):
1244
1261
  return result.failure(
1245
1262
  PysTraceback(
1246
1263
  TypeError("exceptions must derive from BaseException"),
@@ -1256,7 +1273,7 @@ def visit_ThrowNode(node: PysThrowNode, context: PysContext) -> PysRunTimeResult
1256
1273
  if should_return():
1257
1274
  return result
1258
1275
 
1259
- if not is_object_of(primary, BaseException):
1276
+ if not is_object_of(primary, b_BaseException):
1260
1277
  return result.failure(
1261
1278
  PysTraceback(
1262
1279
  TypeError("exceptions must derive from BaseException"),