pyscript-programming-language 1.12.11__tar.gz → 1.12.13__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.13}/PKG-INFO +16 -3
  2. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/README.md +11 -1
  3. pyscript_programming_language-1.12.13/changelog.md +11 -0
  4. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyproject.toml +5 -2
  5. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/__main__.py +75 -58
  6. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/cache.py +4 -2
  7. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/checks.py +2 -1
  8. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/constants.py +2 -0
  9. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/editor/gui.py +42 -7
  10. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/exceptions.py +4 -4
  11. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/handlers.py +28 -28
  12. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/highlight.py +26 -15
  13. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/interpreter.py +37 -21
  14. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/lexer.py +2 -2
  15. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/parser.py +4 -1
  16. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/pysbuiltins.py +133 -112
  17. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/pystypes.py +44 -30
  18. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/results.py +6 -8
  19. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/runner.py +12 -8
  20. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/shell.py +4 -7
  21. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/symtab.py +2 -2
  22. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/utils/debug.py +0 -2
  23. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/utils/decorators.py +1 -2
  24. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/utils/generic.py +6 -3
  25. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/version.py +2 -2
  26. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/ast/ast_dump.py +4 -3
  27. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/brainfuck.pys +5 -4
  28. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/site.pys +3 -5
  29. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/tokenize/tok_untokenize.py +17 -9
  30. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript_programming_language.egg-info/PKG-INFO +16 -3
  31. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/setup.py +5 -2
  32. pyscript_programming_language-1.12.11/changelog.md +0 -13
  33. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/MANIFEST.in +0 -0
  34. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/__init__.py +0 -0
  35. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/__init__.pyi +0 -0
  36. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/__init__.py +0 -0
  37. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/analyzer.py +0 -0
  38. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/bases.py +0 -0
  39. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/buffer.py +0 -0
  40. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/context.py +0 -0
  41. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/editor/__init__.py +0 -0
  42. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/editor/bases.py +0 -0
  43. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/editor/terminal.py +0 -0
  44. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/mapping.py +0 -0
  45. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/nodes.py +0 -0
  46. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/position.py +0 -0
  47. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/token.py +0 -0
  48. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/utils/__init__.py +0 -0
  49. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/utils/ansi.py +0 -0
  50. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/utils/module.py +0 -0
  51. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/utils/path.py +0 -0
  52. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/utils/similarity.py +0 -0
  53. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/core/utils/string.py +0 -0
  54. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/__hello__.pys +0 -0
  55. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/ansi.pys +0 -0
  56. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/ast/__init__.pys +0 -0
  57. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/ast/ast_literal_eval.py +0 -0
  58. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/ast/ast_unparse.py +0 -0
  59. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/ast/ast_walk.py +0 -0
  60. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/code.pys +0 -0
  61. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/dis.pys +0 -0
  62. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/explorer.pys +0 -0
  63. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/fpstimer/__init__.pys +0 -0
  64. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/fpstimer/py_fpstimer.py +0 -0
  65. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/getch/__init__.pys +0 -0
  66. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/getch/py_getch.py +0 -0
  67. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/history.pys +0 -0
  68. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/inspect.pys +0 -0
  69. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/jsdict.pys +0 -0
  70. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/keyword.pys +0 -0
  71. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/opcode.pys +0 -0
  72. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/parser.pys +0 -0
  73. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/pdisplay.pys +0 -0
  74. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/symtable.pys +0 -0
  75. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/token.pys +0 -0
  76. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/lib/tokenize/__init__.pys +0 -0
  77. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/other/.nomedia +0 -0
  78. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/other/PyScript.ico +0 -0
  79. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/other/copyright +0 -0
  80. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/other/credits +0 -0
  81. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/other/license +0 -0
  82. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/site-packages/this.pys +0 -0
  83. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript/this.py +0 -0
  84. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
  85. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  86. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript_programming_language.egg-info/requires.txt +0 -0
  87. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  88. {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.13}/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.13
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
@@ -27,10 +30,20 @@ Dynamic: author
27
30
  Dynamic: home-page
28
31
  Dynamic: requires-python
29
32
 
30
- # PyScript 🐍🟨🟦⬛
33
+ # PyScript
31
34
 
32
35
  <div align="center">
33
36
  <img src="https://github.com/azzammuhyala/pyscript/blob/main/PyScript.png?raw=true" alt="PyScript Logo" width="200">
37
+ <br>
38
+ <a href="https://pepy.tech/project/pyscript-programming-language">
39
+ <img src="https://static.pepy.tech/personalized-badge/pyscript-programming-language?period=total&units=NONE&left_color=GRAY&right_color=GREEN&left_text=downloads" alt="PyPI Downloads">
40
+ </a>
41
+ <a href="https://en.wikipedia.org/wiki/MIT_License">
42
+ <img src="https://img.shields.io/badge/license-MIT-orange" alt="License MIT">
43
+ </a>
44
+ <a href="https://www.python.org/">
45
+ <img src="https://img.shields.io/badge/python-3.10-yellow" alt="Python 3.10+">
46
+ </a>
34
47
  </div>
35
48
 
36
49
  PyScript is a programming language built on top of Python. It combines some syntax from Python and JavaScript, so if
@@ -1,7 +1,17 @@
1
- # PyScript 🐍🟨🟦⬛
1
+ # PyScript
2
2
 
3
3
  <div align="center">
4
4
  <img src="https://github.com/azzammuhyala/pyscript/blob/main/PyScript.png?raw=true" alt="PyScript Logo" width="200">
5
+ <br>
6
+ <a href="https://pepy.tech/project/pyscript-programming-language">
7
+ <img src="https://static.pepy.tech/personalized-badge/pyscript-programming-language?period=total&units=NONE&left_color=GRAY&right_color=GREEN&left_text=downloads" alt="PyPI Downloads">
8
+ </a>
9
+ <a href="https://en.wikipedia.org/wiki/MIT_License">
10
+ <img src="https://img.shields.io/badge/license-MIT-orange" alt="License MIT">
11
+ </a>
12
+ <a href="https://www.python.org/">
13
+ <img src="https://img.shields.io/badge/python-3.10-yellow" alt="Python 3.10+">
14
+ </a>
5
15
  </div>
6
16
 
7
17
  PyScript is a programming language built on top of Python. It combines some syntax from Python and JavaScript, so if
@@ -0,0 +1,11 @@
1
+ # Change Log
2
+
3
+ ## [1.12.13] - 03/05/2026
4
+
5
+ ### Added
6
+ - `PysPythonFunction` is immutable.
7
+ - _etc._
8
+
9
+ ### Fixed
10
+ - Fixed some bugs.
11
+ - _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.13"
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,11 +9,11 @@ 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
16
- from .core.utils.path import getcwd, base, normpath
16
+ from .core.utils.path import getcwd, base
17
17
  from .core.version import __version__
18
18
 
19
19
  if PYGMENTS:
@@ -42,14 +42,15 @@ FORMATER_HIGHLIGHT_MAP = {
42
42
  'bbcode': HLFMT_BBCODE
43
43
  }
44
44
 
45
- EDITOR_MAP = {}
45
+ EDITOR_MAP = {
46
+ name: cls
47
+ for support, name, cls in [
48
+ (GUI_SUPPORT, 'gui', PysGUIEditor),
49
+ (TERMINAL_SUPPORT, 'terminal', PysTerminalEditor)
50
+ ] if support
51
+ }
46
52
 
47
- for supported, name, class_editor in [
48
- (GUI_SUPPORT, 'gui', PysGUIEditor),
49
- (TERMINAL_SUPPORT, 'terminal', PysTerminalEditor)
50
- ]:
51
- if supported:
52
- EDITOR_MAP[name] = class_editor
53
+ arguments_requiring_value = {'-l', '--highlight', '-r', '--py-recursion'}
53
54
 
54
55
  parser = ArgumentParser(
55
56
  prog=f'{base(sys.executable)} -m pyscript',
@@ -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,32 +251,30 @@ 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', 'clean_up', 'condition', 'ctypes', 'execute', 'fd', 'file', 'find_module_path', 'flag',
266
+ 'getcwd', 'highlight', 'i', 'index', 'is_environ', 'kernel32', 'load_file', 'module_path', 'parser',
267
+ 'pys_highlight', 'pys_sys', 'remove_python_path'
268
+ }:
269
+ try:
270
+ del g[name]
271
+ except:
272
+ continue
265
273
 
266
- def load_file(path):
267
- file = PysFileBuffer('', path)
274
+ def load_file(path) -> PysFileBuffer:
268
275
  try:
269
276
  with open(path, 'r', encoding='utf-8') as file:
270
- file = PysFileBuffer(file, path)
277
+ return PysFileBuffer(file, path)
271
278
  except FileNotFoundError:
272
279
  if not (EDITOR_MAP and args.editor):
273
280
  argument_error('file', f"can't open file \"{path}\": No such file or directory")
@@ -283,36 +290,42 @@ def load_file(path):
283
290
  argument_error('file', f"can't read file \"{path}\": Bad file")
284
291
  except BaseException as e:
285
292
  argument_error('file', f"file \"{path}\": Unexpected error: {e}")
286
- return file
293
+ return PysFileBuffer('', path)
294
+
295
+ def execute(file: PysFileBuffer) -> None:
296
+ global code
297
+
298
+ not_show_banner_flag = DONT_SHOW_BANNER_ON_SHELL
299
+ inspect = args.inspect
300
+ symtab = _namespace_to_symbol_table(undefined, file)
301
+
302
+ clean_up()
287
303
 
288
- def execute(file):
289
304
  result = pys_runner(
290
305
  file=file,
291
306
  mode='exec',
292
- symbol_table=_normalize_namespace(undefined, file),
307
+ symbol_table=symtab,
293
308
  flags=flags
294
309
  )
295
310
 
296
311
  code, _ = result.end_process()
297
312
 
298
- if args.inspect:
313
+ if inspect:
299
314
  if sys.stdout.closed or sys.stderr.closed:
300
- return 1
315
+ code = 1
301
316
  elif sys.stdin.closed:
302
317
  print("Can't run interactive shell: sys.stdin closed", file=sys.stderr)
303
- return 1
318
+ code = 1
304
319
  else:
305
- return pys_shell(
320
+ code = pys_shell(
306
321
  globals=result.context.symbol_table,
307
- flags=result.context.flags | DONT_SHOW_BANNER_ON_SHELL,
322
+ flags=result.context.flags | not_show_banner_flag,
308
323
  parser_flags=result.parser_flags
309
324
  )
310
325
 
311
- return code
312
-
313
326
  if args.file is not None:
314
327
  argv[0] = args.file
315
- file = load_file(normpath(args.file))
328
+ file = load_file(args.file)
316
329
 
317
330
  if EDITOR_MAP and args.editor:
318
331
  try:
@@ -334,14 +347,17 @@ if args.file is not None:
334
347
  highlight(
335
348
  code=file.text,
336
349
  lexer=PygmentsPyScriptLexer(),
337
- formatter=FORMATER_PYGMENTS_MAP[args.highlight](style=PygmentsPyScriptStyle, full=True)
350
+ formatter=FORMATER_PYGMENTS_MAP[args.highlight](
351
+ style=PygmentsPyScriptStyle,
352
+ full=True
353
+ )
338
354
  )
339
355
  )
340
356
  except BaseException as e:
341
357
  argument_error('-l/--highlight', e)
342
358
 
343
359
  else:
344
- code = execute(file)
360
+ execute(file)
345
361
 
346
362
  elif args.module is not None:
347
363
  _, module_path = find_module_path(None, args.module, '__main__')
@@ -350,13 +366,14 @@ elif args.module is not None:
350
366
 
351
367
  file = load_file(module_path)
352
368
  argv[0] = file.name
353
- code = execute(file)
369
+ execute(file)
354
370
 
355
371
  elif args.command is not None:
356
372
  argv[0] = '-c'
357
- code = execute(PysFileBuffer(args.command, '<arg-command>'))
373
+ execute(PysFileBuffer(args.command, '<arg-command>'))
358
374
 
359
375
  else:
376
+ clean_up()
360
377
  code = pys_shell(
361
378
  globals=undefined,
362
379
  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,9 +31,10 @@ 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 = '... '
37
+ pys_sys._is_gil_enabled = lambda : pys_sys.gil
36
38
 
37
39
  for name in (
38
40
  'exit', 'float_info', 'float_repr_style', 'get_int_max_str_digits', 'getdefaultencoding',
@@ -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
 
@@ -10,9 +10,34 @@ from typing import Any
10
10
 
11
11
  wrapper_function = (MethodType, classmethod, staticmethod)
12
12
 
13
- if not is_environ(ENV_PYSCRIPT_NO_GIL):
14
- from threading import RLock
13
+ if is_environ(ENV_PYSCRIPT_NO_GIL):
14
+
15
+ def handle_call(object: Any, context: PysContext, position: PysPosition) -> None:
16
+ ins = isinstance
15
17
 
18
+ if ins(object, PysFunction):
19
+ code = object.__code__
20
+ code.context = context
21
+ code.position = position
22
+
23
+ elif ins(object, wrapper_function):
24
+ handle_call(object.__func__, context, position)
25
+
26
+ elif ins(object, type):
27
+ gt = getattr
28
+
29
+ method = gt(object, '__new__', None)
30
+ if method is not None:
31
+ handle_call(method, context, position)
32
+
33
+ method = gt(object, '__init__', None)
34
+ if method is not None:
35
+ handle_call(method, context, position)
36
+
37
+ GIL = pys_sys.gil = False
38
+
39
+ else:
40
+ from threading import RLock
16
41
  gil_lock = RLock()
17
42
 
18
43
  def handle_call(object: Any, context: PysContext, position: PysPosition) -> None:
@@ -38,29 +63,4 @@ if not is_environ(ENV_PYSCRIPT_NO_GIL):
38
63
  if method is not None:
39
64
  handle_call(method, context, position)
40
65
 
41
- GIL = pys_sys.gil = True
42
- else:
43
-
44
- def handle_call(object: Any, context: PysContext, position: PysPosition) -> None:
45
- ins = isinstance
46
-
47
- if ins(object, PysFunction):
48
- code = object.__code__
49
- code.context = context
50
- code.position = position
51
-
52
- elif ins(object, wrapper_function):
53
- handle_call(object.__func__, context, position)
54
-
55
- elif ins(object, type):
56
- gt = getattr
57
-
58
- method = gt(object, '__new__', None)
59
- if method is not None:
60
- handle_call(method, context, position)
61
-
62
- method = gt(object, '__init__', None)
63
- if method is not None:
64
- handle_call(method, context, position)
65
-
66
- GIL = pys_sys.gil = False
66
+ GIL = pys_sys.gil = True
@@ -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