pyscript-programming-language 1.13.0__tar.gz → 1.13.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 (90) hide show
  1. {pyscript_programming_language-1.13.0/pyscript_programming_language.egg-info → pyscript_programming_language-1.13.2}/PKG-INFO +5 -5
  2. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/README.md +4 -4
  3. pyscript_programming_language-1.13.2/changelog.md +7 -0
  4. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyproject.toml +1 -1
  5. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/__main__.py +3 -4
  6. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/cache.py +16 -5
  7. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/constants.py +1 -1
  8. pyscript_programming_language-1.13.2/pyscript/core/editor/bases.py +70 -0
  9. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/editor/gui.py +37 -44
  10. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/editor/terminal.py +7 -2
  11. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/exceptions.py +1 -0
  12. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/interpreter.py +3 -10
  13. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/mapping.py +3 -2
  14. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/nodes.py +1 -0
  15. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/parser.py +6 -6
  16. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/pysbuiltins.py +6 -2
  17. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/results.py +1 -0
  18. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/runner.py +1 -1
  19. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/shell.py +3 -2
  20. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/symtab.py +11 -5
  21. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/token.py +2 -1
  22. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/utils/debug.py +5 -5
  23. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/utils/generic.py +3 -0
  24. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/utils/module.py +3 -1
  25. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/version.py +2 -2
  26. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/ast/ast_literal_eval.py +16 -13
  27. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/brainfuck.pys +2 -2
  28. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/inspect.pys +5 -5
  29. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/parser.pys +18 -9
  30. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/pdisplay.pys +3 -3
  31. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/site.pys +1 -1
  32. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/tokenize/tok_untokenize.py +3 -3
  33. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/site-packages/this.pys +5 -10
  34. pyscript_programming_language-1.13.2/pyscript/this.py +11 -0
  35. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2/pyscript_programming_language.egg-info}/PKG-INFO +5 -5
  36. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/setup.py +1 -1
  37. pyscript_programming_language-1.13.0/changelog.md +0 -27
  38. pyscript_programming_language-1.13.0/pyscript/core/editor/bases.py +0 -38
  39. pyscript_programming_language-1.13.0/pyscript/this.py +0 -8
  40. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/MANIFEST.in +0 -0
  41. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/__init__.py +0 -0
  42. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/__init__.pyi +0 -0
  43. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/__init__.py +0 -0
  44. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/analyzer.py +0 -0
  45. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/bases.py +0 -0
  46. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/buffer.py +0 -0
  47. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/checks.py +0 -0
  48. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/context.py +0 -0
  49. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/editor/__init__.py +0 -0
  50. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/handlers.py +0 -0
  51. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/highlight.py +0 -0
  52. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/lexer.py +0 -0
  53. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/position.py +0 -0
  54. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/pystypes.py +0 -0
  55. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/utils/__init__.py +0 -0
  56. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/utils/ansi.py +0 -0
  57. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/utils/decorators.py +0 -0
  58. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/utils/path.py +0 -0
  59. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/utils/similarity.py +0 -0
  60. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/core/utils/string.py +0 -0
  61. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/__hello__.pys +0 -0
  62. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/ansi.pys +0 -0
  63. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/ast/__init__.pys +0 -0
  64. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/ast/ast_dump.py +0 -0
  65. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/ast/ast_unparse.py +0 -0
  66. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/ast/ast_walk.py +0 -0
  67. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/code.pys +0 -0
  68. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/dis.pys +0 -0
  69. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/explorer.pys +0 -0
  70. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/fpstimer/__init__.pys +0 -0
  71. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/fpstimer/py_fpstimer.py +0 -0
  72. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/getch/__init__.pys +0 -0
  73. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/getch/py_getch.py +0 -0
  74. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/history.pys +0 -0
  75. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/jsdict.pys +0 -0
  76. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/keyword.pys +0 -0
  77. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/opcode.pys +0 -0
  78. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/symtable.pys +0 -0
  79. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/token.pys +0 -0
  80. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/lib/tokenize/__init__.pys +0 -0
  81. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/other/.nomedia +0 -0
  82. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/other/PyScript.ico +0 -0
  83. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/other/copyright +0 -0
  84. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/other/credits +0 -0
  85. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript/other/license +0 -0
  86. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
  87. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  88. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript_programming_language.egg-info/requires.txt +0 -0
  89. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  90. {pyscript_programming_language-1.13.0 → pyscript_programming_language-1.13.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.13.0
3
+ Version: 1.13.2
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://azzammuhyala.github.io/pyscript
6
6
  Author: Azzam Muhyala
@@ -42,7 +42,7 @@ Dynamic: requires-python
42
42
  <img src="https://img.shields.io/badge/license-MIT-orange" alt="License MIT">
43
43
  </a>
44
44
  <a href="https://www.python.org/">
45
- <img src="https://img.shields.io/badge/python-3.10-yellow" alt="Python 3.10+">
45
+ <img src="https://img.shields.io/badge/python-3.10+-yellow" alt="Python 3.10+">
46
46
  </a>
47
47
  </div>
48
48
 
@@ -144,12 +144,12 @@ Familiar? There it is!
144
144
  import it.
145
145
  - **optional**: Not required, but if it is present, some features can be used without issue.
146
146
 
147
- ## Highlights
148
- - [PyScript plugin for Acode](https://acode.app/plugin/acode.plugin.pyscript)
147
+ ## Highlights 🎨
148
+ - [PyScript plugin for Acode (Ace Editor)](https://github.com/azzammuhyala/pyscript/releases/download/v1.13.1/plugin.zip)
149
149
  - [PyScript nano for Linux](https://github.com/azzammuhyala/pyscript/tree/main/highlight/nano)
150
150
  - [PyScript extension for VSCode](https://marketplace.visualstudio.com/items?itemName=azzammuhyala.pyslang)
151
151
 
152
- ## Behind it 🕰️
152
+ ## Behind It 🕰️
153
153
  This language created from based up on a
154
154
  [YouTube tutorial](https://www.youtube.com/playlist?list=PLZQftyCk7_SdoVexSmwy_tBgs7P0b97yD) (check more on GitHub
155
155
  [here](https://github.com/davidcallanan/py-myopl-code) by **@davidcallanan**). At least, it takes about 6 months to
@@ -10,7 +10,7 @@
10
10
  <img src="https://img.shields.io/badge/license-MIT-orange" alt="License MIT">
11
11
  </a>
12
12
  <a href="https://www.python.org/">
13
- <img src="https://img.shields.io/badge/python-3.10-yellow" alt="Python 3.10+">
13
+ <img src="https://img.shields.io/badge/python-3.10+-yellow" alt="Python 3.10+">
14
14
  </a>
15
15
  </div>
16
16
 
@@ -112,12 +112,12 @@ Familiar? There it is!
112
112
  import it.
113
113
  - **optional**: Not required, but if it is present, some features can be used without issue.
114
114
 
115
- ## Highlights
116
- - [PyScript plugin for Acode](https://acode.app/plugin/acode.plugin.pyscript)
115
+ ## Highlights 🎨
116
+ - [PyScript plugin for Acode (Ace Editor)](https://github.com/azzammuhyala/pyscript/releases/download/v1.13.1/plugin.zip)
117
117
  - [PyScript nano for Linux](https://github.com/azzammuhyala/pyscript/tree/main/highlight/nano)
118
118
  - [PyScript extension for VSCode](https://marketplace.visualstudio.com/items?itemName=azzammuhyala.pyslang)
119
119
 
120
- ## Behind it 🕰️
120
+ ## Behind It 🕰️
121
121
  This language created from based up on a
122
122
  [YouTube tutorial](https://www.youtube.com/playlist?list=PLZQftyCk7_SdoVexSmwy_tBgs7P0b97yD) (check more on GitHub
123
123
  [here](https://github.com/davidcallanan/py-myopl-code) by **@davidcallanan**). At least, it takes about 6 months to
@@ -0,0 +1,7 @@
1
+ # Change Logs
2
+
3
+ ## [1.13.2] - 27/05/2026
4
+
5
+ ### Fixed
6
+ - Fixed some bugs.
7
+ - _etc._
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyscript-programming-language"
7
- version = "1.13.0"
7
+ version = "1.13.2"
8
8
  description = "PyScript Programming Language"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.10"
@@ -255,8 +255,8 @@ def clean_up() -> None:
255
255
  g = globals()
256
256
 
257
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',
258
+ 'ArgumentParser', 'BBCodeFormatter', 'CLASSIC_LINE_SHELL', 'DEBUG', 'DEFAULT', 'EDITOR_MAP',
259
+ 'ENV_PYSCRIPT_CLASSIC_LINE_SHELL', 'ENV_PYSCRIPT_NO_COLOR_PROMPT', 'FORMATER_HIGHLIGHT_MAP',
260
260
  'FORMATER_PYGMENTS_MAP', 'GUI_SUPPORT', 'HLFMT_ANSI', 'HLFMT_BBCODE', 'HLFMT_HTML', 'HtmlFormatter',
261
261
  'LatexFormatter', 'NOTEBOOK', 'NO_COLOR', 'NO_COLOR_PROMPT', 'OPTIONAL', 'PYGMENTS', 'PygmentsPyScriptLexer',
262
262
  'PygmentsPyScriptStyle', 'PysFileBuffer', 'PysGUIEditor', 'PysTerminalEditor', 'REMAINDER', 'TERMINAL_SUPPORT',
@@ -295,7 +295,6 @@ def load_file(path) -> PysFileBuffer:
295
295
  def execute(file: PysFileBuffer) -> None:
296
296
  global code
297
297
 
298
- not_show_banner_flag = DONT_SHOW_BANNER_ON_SHELL
299
298
  inspect = args.inspect
300
299
  symtab = _namespace_to_symbol_table(undefined, file)
301
300
 
@@ -319,7 +318,7 @@ def execute(file: PysFileBuffer) -> None:
319
318
  else:
320
319
  code = pys_shell(
321
320
  globals=result.context.symbol_table,
322
- flags=result.context.flags | not_show_banner_flag,
321
+ flags=result.context.flags | DONT_SHOW_BANNER_ON_SHELL,
323
322
  parser_flags=result.parser_flags
324
323
  )
325
324
 
@@ -1,13 +1,15 @@
1
1
  from .bases import Pys
2
- from .constants import PYSCRIPT_PATH, CORE_PATH, LIBRARIES_PATH, SITE_PACKAGES_PATH, DEFAULT
2
+ from .constants import PYSCRIPT_PATH, CORE_PATH, LIBRARIES_PATH, SITE_PACKAGES_PATH, CONFIGURATIONS_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.module import get_module_candidate
5
6
  from .utils.path import base
6
7
 
7
8
  from types import ModuleType
8
9
  from typing import Literal
9
10
 
10
11
  import sys
12
+ import os
11
13
 
12
14
  pys_sys = ModuleType(
13
15
  'sys',
@@ -18,6 +20,11 @@ pys_sys = ModuleType(
18
20
 
19
21
  pys_sys.__running_shell__ = False
20
22
  pys_sys.__running_breakpoint__ = False
23
+ pys_sys.builtin_module_names = tuple(
24
+ os.path.splitext(module)[0]
25
+ for module in os.listdir(LIBRARIES_PATH)
26
+ if get_module_candidate(os.path.join(LIBRARIES_PATH, module)) is not None
27
+ )
21
28
  pys_sys.path = [LIBRARIES_PATH, SITE_PACKAGES_PATH]
22
29
  pys_sys.loading_modules = set()
23
30
  pys_sys.modules = {}
@@ -31,16 +38,20 @@ pys_sys.pyscript_path = PYSCRIPT_PATH
31
38
  pys_sys.core_path = CORE_PATH
32
39
  pys_sys.libraries_path = LIBRARIES_PATH
33
40
  pys_sys.site_packages_path = SITE_PACKAGES_PATH
41
+ pys_sys.configurations_path = CONFIGURATIONS_PATH
42
+ pys_sys.platlibdir = base(LIBRARIES_PATH)
34
43
  pys_sys.executable = f'{base(sys.executable)} -m pyscript'
35
44
  pys_sys.ps1 = '>>> '
36
45
  pys_sys.ps2 = '... '
37
46
  pys_sys._is_gil_enabled = lambda : pys_sys.gil
38
47
 
39
48
  for name in (
40
- 'exit', 'float_info', 'float_repr_style', 'get_int_max_str_digits', 'getdefaultencoding',
41
- 'getfilesystemencodeerrors', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getsizeof',
42
- 'gettotalrefcount', 'hash_info', 'hexversion', 'int_info', 'intern', 'maxsize', 'maxunicode', 'platform',
43
- 'set_int_max_str_digits', 'setrecursionlimit', 'stderr', 'stdin', 'stdout', 'thread_info'
49
+ '_clear_internal_caches', '_is_immortal', '_is_interned', 'byteorder', 'exit', 'float_info', 'float_repr_style',
50
+ 'get_int_max_str_digits', 'getallocatedblocks', 'getdefaultencoding', 'getfilesystemencodeerrors',
51
+ 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
52
+ 'getunicodeinternedsize', 'hash_info', 'hexversion', 'int_info', 'intern', 'is_finalizing', 'maxsize', 'maxunicode',
53
+ 'platform', 'set_int_max_str_digits', 'setrecursionlimit', 'setswitchinterval', 'stderr', 'stdin', 'stdout',
54
+ 'thread_info'
44
55
  ):
45
56
  if hasattr(sys, name):
46
57
  setattr(pys_sys, name, getattr(sys, name))
@@ -7,7 +7,7 @@ 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
9
  GLOBAL_HISTORY_PATH = os.path.join(os.path.expanduser('~'), '.pyscript_history')
10
- GUI_GEOMETRY_PATH = os.path.join(OTHER_PATH, 'gui_geometry.txt')
10
+ CONFIGURATIONS_PATH = os.path.join(OTHER_PATH, 'configurations.json')
11
11
 
12
12
  ENV_PYSCRIPT_NO_EXCEPTHOOK = 'PYSCRIPT_NO_EXCEPTHOOK'
13
13
  ENV_PYSCRIPT_NO_GIL = 'PYSCRIPT_NO_GIL'
@@ -0,0 +1,70 @@
1
+ from ..bases import Pys
2
+ from ..buffer import PysFileBuffer
3
+ from ..constants import CONFIGURATIONS_PATH
4
+ from ..utils.decorators import typecheck, inheritable
5
+ from ..utils.generic import setimuattr
6
+ from ..utils.string import normstr
7
+
8
+ from json import dump, load
9
+ from typing import Any
10
+
11
+ import os
12
+
13
+ class PysEditor(Pys):
14
+
15
+ @typecheck
16
+ def __init__(self, file: PysFileBuffer, colored: bool = True) -> None:
17
+ self.file = file
18
+ self.colored = bool(colored)
19
+ self.basename = os.path.basename(self.file.name)
20
+ self.used = False
21
+ self.modified = False
22
+
23
+ def __init_subclass__(cls, **kwargs) -> None:
24
+ super().__init_subclass__(**kwargs)
25
+ inheritable(cls)
26
+
27
+ def load_configuration(self) -> None:
28
+ try:
29
+ with open(CONFIGURATIONS_PATH, 'r', encoding='utf-8') as file:
30
+ result = load(file)
31
+ if not isinstance(result, dict):
32
+ raise ValueError
33
+ for key in result:
34
+ if not isinstance(key, str):
35
+ raise ValueError
36
+ self.configurations = result
37
+ except:
38
+ self.configurations = {}
39
+
40
+ def get_configuration(self, configuration: str, default: Any) -> Any:
41
+ if configuration in self.configurations:
42
+ return self.configurations[configuration]
43
+ self.configurations[configuration] = default
44
+ return default
45
+
46
+ def set_configuration(self, configuration: str, value: Any) -> None:
47
+ self.configurations[configuration] = value
48
+
49
+ def save_configuration(self) -> None:
50
+ try:
51
+ with open(CONFIGURATIONS_PATH, 'w', encoding='utf-8') as file:
52
+ dump(self.configurations, file, separators=(',', ':'))
53
+ except:
54
+ pass
55
+
56
+ def save(self, text) -> None:
57
+ try:
58
+ text = normstr(text)
59
+ with open(self.file.name, 'w', encoding='utf-8') as file:
60
+ file.write(text)
61
+ setimuattr(self.file, 'text', text)
62
+ except:
63
+ pass
64
+ else:
65
+ self.modified = False
66
+
67
+ def run(self) -> None:
68
+ if self.used:
69
+ raise RuntimeError("one application object can only be used once")
70
+ self.used = True
@@ -1,11 +1,10 @@
1
1
  from .bases import PysEditor
2
2
  from ..buffer import PysFileBuffer
3
- from ..constants import GUI_GEOMETRY_PATH, ICON_PATH
3
+ from ..constants import ICON_PATH
4
4
  from ..highlight import PygmentsPyScriptStyle, PygmentsPyScriptLexer
5
+ from ..utils.generic import boundary
5
6
  from ..version import __version__
6
7
 
7
- import re
8
-
9
8
  try:
10
9
  from tkinter import Tk, Scrollbar, Text, messagebox
11
10
  from tkinter.font import Font
@@ -16,6 +15,8 @@ try:
16
15
  PysEditor.__init__(self, file, colored)
17
16
  Tk.__init__(self)
18
17
 
18
+ self.load_configuration()
19
+
19
20
  def on_save(event=None):
20
21
  text = self.text.get('1.0', 'end')
21
22
  self.save(text[:-1] if text.endswith(('\r\n', '\r', '\n')) else text)
@@ -27,15 +28,24 @@ try:
27
28
  answer = messagebox.askyesnocancel('Unsaved changes', 'File has been modified. Save before exit?')
28
29
  if answer is True:
29
30
  on_save()
31
+ self.save_configuration()
30
32
  self.destroy()
31
33
  elif answer is False:
34
+ self.save_configuration()
32
35
  self.destroy()
33
36
  else:
37
+ self.save_configuration()
34
38
  self.destroy()
35
39
 
36
40
  def on_configure(event):
37
41
  if event.widget == self:
38
- save_geometry(event.x, event.y, event.width, event.height, self.wm_state() == 'zoomed')
42
+ zoom = self.wm_state() == 'zoomed'
43
+ self.set_configuration('zoom', zoom)
44
+ if not zoom:
45
+ self.set_configuration(
46
+ 'gui-geometry',
47
+ f'{event.width}x{event.height}+{event.x}+{event.y}'
48
+ )
39
49
 
40
50
  def on_modified(event=None):
41
51
  text = self.text
@@ -44,18 +54,19 @@ try:
44
54
  update()
45
55
  text.edit_modified(False)
46
56
 
47
- def on_change_font(value, limit):
57
+ def on_change_font(value):
48
58
  def wrapper(event=None):
49
59
  font = self.font
50
- size = font.cget('size')
51
- if limit(size):
52
- font.config(size=size + value)
60
+ size = boundary(font.cget('size') + value, 1, 127)
61
+ font.config(size=size)
62
+ self.set_configuration('gui-size-font', size)
53
63
  return 'break'
54
64
  return wrapper
55
65
 
56
66
  def on_toggle_wrap(event=None):
57
- self.wrapped = not self.wrapped
58
- self.text.configure(wrap='char' if self.wrapped else 'none')
67
+ wrap = self.text.cget('wrap') != 'char'
68
+ self.text.configure(wrap='char' if wrap else 'none')
69
+ self.set_configuration('wrap', wrap)
59
70
  return 'break'
60
71
 
61
72
  def on_page_up(event=None):
@@ -76,27 +87,17 @@ try:
76
87
  text.insert('insert', '\n' + line[:len(line) - len(line.lstrip())])
77
88
  return 'break'
78
89
 
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
88
-
89
90
  self.lexer = PygmentsPyScriptLexer()
90
- self.font = Font(family='Consolas', size=10)
91
+ self.font = Font(family='Consolas', size=boundary(self.get_configuration('gui-size-font', 10), 1, 127))
91
92
  self.scrollbar = Scrollbar(self)
92
93
  self.text = Text(
93
94
  self,
94
95
  undo=True,
95
96
  width=120,
96
97
  font=self.font,
97
- wrap='char',
98
- bg='#171717',
99
- fg='#f1f1f1',
98
+ wrap='char' if self.get_configuration('wrap', True) else 'none',
99
+ bg='#000000',
100
+ fg='#ffffff',
100
101
  insertbackground='white',
101
102
  yscrollcommand=self.scrollbar.set
102
103
  )
@@ -119,34 +120,26 @@ try:
119
120
  self.bind_all('<Control-s>', on_save)
120
121
  self.bind_all('<Control-W>', on_toggle_wrap)
121
122
  self.bind_all('<Control-w>', on_toggle_wrap)
122
- self.bind_all('<Control-minus>', on_change_font(-1, lambda size : size > 1))
123
- self.bind_all('<Control-underscore>', on_change_font(-5, lambda size : size > 1))
124
- self.bind_all('<Control-equal>', on_change_font(1, lambda size : size < 128))
125
- self.bind_all('<Control-plus>', on_change_font(5, lambda size : size < 128))
126
-
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)
123
+ self.bind_all('<Control-minus>', on_change_font(-1))
124
+ self.bind_all('<Control-underscore>', on_change_font(-5))
125
+ self.bind_all('<Control-equal>', on_change_font(1))
126
+ self.bind_all('<Control-plus>', on_change_font(5))
140
127
 
141
128
  try:
142
129
  self.wm_iconbitmap(ICON_PATH)
143
130
  except:
144
131
  pass
145
132
 
146
- if zoom:
133
+ if self.get_configuration('zoom', False):
147
134
  self.wm_state('zoomed')
148
135
 
149
- self.wm_geometry(self.last_geometry)
136
+ self.wm_geometry(
137
+ self.get_configuration(
138
+ 'gui-geometry',
139
+ f'500x500+{self.winfo_screenwidth() // 2 - 250}+{self.winfo_screenheight() // 2 - 250}'
140
+ )
141
+ )
142
+
150
143
  self.wm_minsize(300, 250)
151
144
  self.wm_protocol('WM_DELETE_WINDOW', on_close)
152
145
 
@@ -22,11 +22,13 @@ try:
22
22
  def __init__(self, file: PysFileBuffer, colored: bool = True) -> None:
23
23
  PysEditor.__init__(self, file, colored)
24
24
 
25
+ self.load_configuration()
26
+
25
27
  self.show_exit_window = False
26
28
 
27
29
  on_edit = Condition(lambda: not self.show_exit_window)
28
30
  on_exit = Condition(lambda: self.show_exit_window)
29
- on_wrap = Condition(lambda: self.wrapped)
31
+ on_wrap = Condition(lambda: self.get_configuration('wrap', True))
30
32
 
31
33
  def on_change(buffer):
32
34
  self.modified = True
@@ -125,7 +127,7 @@ try:
125
127
 
126
128
  @key_bindings.add('c-w', filter=on_edit, eager=True)
127
129
  def _(event):
128
- self.wrapped = not self.wrapped
130
+ self.set_configuration('wrap', not self.get_configuration('wrap', False))
129
131
 
130
132
  @key_bindings.add('c-y', filter=on_edit, eager=True)
131
133
  def _(event):
@@ -147,17 +149,20 @@ try:
147
149
  self.output.hide_cursor()
148
150
  self.layout.focus(self.close_window)
149
151
  else:
152
+ self.save_configuration()
150
153
  self.exit()
151
154
 
152
155
  @key_bindings.add('y', filter=on_exit)
153
156
  def _(event):
154
157
  self.save(self.text.buffer.text)
155
158
  self.show_exit_window = False
159
+ self.save_configuration()
156
160
  self.exit()
157
161
 
158
162
  @key_bindings.add('n', filter=on_exit)
159
163
  def _(event):
160
164
  self.show_exit_window = False
165
+ self.save_configuration()
161
166
  self.exit()
162
167
 
163
168
  @key_bindings.add('c', filter=on_exit)
@@ -7,6 +7,7 @@ from .utils.string import indent
7
7
  from typing import TYPE_CHECKING, Optional
8
8
 
9
9
  if TYPE_CHECKING:
10
+ # circular import problem solved
10
11
  from .context import PysContext
11
12
  from .position import PysPosition
12
13
  from .results import PysRunTimeResult
@@ -22,16 +22,12 @@ from typing import Any, Callable
22
22
 
23
23
  T_STRING = TOKENS['STRING']
24
24
  T_AND = TOKENS['DOUBLE_AMPERSAND']
25
+ T_INCREMENT = TOKENS['DOUBLE_PLUS']
25
26
  T_NULLISH = TOKENS['DOUBLE_QUESTION']
26
27
  T_OR = TOKENS['DOUBLE_PIPE']
27
28
  T_CE = TOKENS['EQUAL_TILDE']
28
29
  T_NCE = TOKENS['EXCLAMATION_TILDE']
29
30
 
30
- get_incremental_function = {
31
- TOKENS['DOUBLE_PLUS']: increment,
32
- TOKENS['DOUBLE_MINUS']: decrement
33
- }.__getitem__
34
-
35
31
  get_value_from_keyword = {
36
32
  'True': True,
37
33
  'False': False,
@@ -381,18 +377,15 @@ def visit_IncrementalNode(node: PysIncrementalNode, context: PysContext) -> PysR
381
377
  result._context = context
382
378
  result._position = nposition = node.position
383
379
  with result:
384
- function = get_incremental_function(node.operand.type)
380
+ function = increment if node.operand.type == T_INCREMENT else decrement
385
381
  handle_call(function, context, nposition)
386
382
  increast_value = function(value)
387
383
 
388
- if node.operand_position == 'left':
389
- value = increast_value
390
-
391
384
  register(visit_declaration_from_AssignmentNode(ntarget, context, increast_value))
392
385
  if should_return():
393
386
  return result
394
387
 
395
- return result.success(value)
388
+ return result.success(increast_value if node.operand_position == 'left' else value)
396
389
 
397
390
  return result
398
391
 
@@ -2,8 +2,9 @@ from .token import TOKENS
2
2
  from .utils.ansi import BOLD, acolor
3
3
 
4
4
  from operator import (
5
- not_, is_, is_not, eq, ne, lt, gt, le, ge, add, sub, mul, truediv, floordiv, pow, matmul, mod, and_, or_, xor, lshift,
6
- rshift, iadd, isub, imul, itruediv, ifloordiv, ipow, imatmul, imod, iand, ior, ixor, ilshift, irshift, pos, neg, inv
5
+ not_, is_, is_not, eq, ne, lt, gt, le, ge, add, sub, mul, truediv, floordiv, pow, matmul, mod, and_, or_, xor,
6
+ lshift, rshift, iadd, isub, imul, itruediv, ifloordiv, ipow, imatmul, imod, iand, ior, ixor, ilshift, irshift, pos,
7
+ neg, inv
7
8
  )
8
9
  from types import MappingProxyType
9
10
 
@@ -7,6 +7,7 @@ from .utils.generic import setimuattr
7
7
  from typing import TYPE_CHECKING, Literal
8
8
 
9
9
  if TYPE_CHECKING:
10
+ # circular import problem solved
10
11
  from .pystypes import jsdict
11
12
 
12
13
  @immutable
@@ -405,12 +405,15 @@ class PysParser(Pys):
405
405
  )
406
406
 
407
407
  return self.chain_operator(
408
- self.bitwise,
408
+ self.instanceof,
409
409
  TOKENS['DOUBLE_EQUAL'], TOKENS['EQUAL_EXCLAMATION'], TOKENS['EQUAL_TILDE'], TOKENS['EXCLAMATION_TILDE'],
410
410
  TOKENS['LESS_THAN'], TOKENS['GREATER_THAN'], TOKENS['EQUAL_LESS_THAN'], TOKENS['EQUAL_GREATER_THAN'],
411
411
  TOKENS['LESS_THAN_GREATER_THAN']
412
412
  )
413
413
 
414
+ def instanceof(self) -> PysParserResult:
415
+ return self.binary_operator(self.bitwise, (TOKENS['KEYWORD'], 'instanceof'), instanceof=True)
416
+
414
417
  def bitwise(self) -> PysParserResult:
415
418
  return self.binary_operator(
416
419
  self.arithmetic,
@@ -481,7 +484,7 @@ class PysParser(Pys):
481
484
  self.advance()
482
485
  self.skip_expression(result)
483
486
 
484
- node = result.register(self.instanceof())
487
+ node = result.register(self.primary())
485
488
  if result.error:
486
489
  return result
487
490
 
@@ -493,7 +496,7 @@ class PysParser(Pys):
493
496
  )
494
497
  )
495
498
 
496
- node = result.register(self.instanceof())
499
+ node = result.register(self.primary())
497
500
  if result.error:
498
501
  return result
499
502
 
@@ -512,9 +515,6 @@ class PysParser(Pys):
512
515
 
513
516
  return result.success(node)
514
517
 
515
- def instanceof(self) -> PysParserResult:
516
- return self.binary_operator(self.primary, (TOKENS['KEYWORD'], 'instanceof'), instanceof=True)
517
-
518
518
  def primary(self) -> PysParserResult:
519
519
  result = PysParserResult()
520
520
  start = self.current_token.position.start
@@ -115,7 +115,7 @@ class PysHelper(PysPrinter):
115
115
  if not (args or kwargs):
116
116
  print(
117
117
  "Welcome to the PyScript programming language! "
118
- "This is the help utility directly to the Python help.\n\n"
118
+ "This is the help utility directly to the Python's help.\n\n"
119
119
  "To get help on a specific object, type 'help(object)'.\n"
120
120
  "To get the list of builtin functions, types, exceptions, and other objects, type 'help(\"builtins\")'."
121
121
  )
@@ -195,6 +195,7 @@ def require(context, position, name):
195
195
  except BaseException as e:
196
196
  raise ImportError(f"Cannot import module named {name!r}: {e}") from e
197
197
 
198
+ # circular import problem solved
198
199
  from .runner import pys_runner
199
200
 
200
201
  symbol_table, module = new_module_namespace(file=module_path, name=base(path))
@@ -256,6 +257,7 @@ def breakpoint(context, position):
256
257
  if getattr(pys_sys, '__running_breakpoint__', False):
257
258
  raise RuntimeError("another breakpoint is still running")
258
259
 
260
+ # circular import problem solved
259
261
  from .runner import pys_runner
260
262
 
261
263
  flags = context.flags
@@ -373,7 +375,7 @@ def globals(context, position):
373
375
  result = {}
374
376
 
375
377
  while symbol_table:
376
- result |= symbol_table.symbols
378
+ result = symbol_table.symbols | result
377
379
  symbol_table = symbol_table.parent
378
380
 
379
381
  return result
@@ -431,6 +433,7 @@ def exec(context, position, source, globals=None):
431
433
  if not isinstance(globals, optional_mapping):
432
434
  raise TypeError("exec(): globals must be dict")
433
435
 
436
+ # circular import problem solved
434
437
  from .runner import pys_runner
435
438
 
436
439
  result = pys_runner(
@@ -460,6 +463,7 @@ def eval(context, position, source, globals=None):
460
463
  if not isinstance(globals, optional_mapping):
461
464
  raise TypeError("eval(): globals must be dict")
462
465
 
466
+ # circular import problem solved
463
467
  from .runner import pys_runner
464
468
 
465
469
  result = pys_runner(
@@ -175,6 +175,7 @@ class PysExecuteResult(PysResult):
175
175
  elif type(self.error.exception) is SystemExit:
176
176
  return self.error.exception.code, True
177
177
  elif (excepthook := pys_sys.excepthook) is not None:
178
+ # circular import problem solved
178
179
  from .handlers import handle_call
179
180
  handle_call(excepthook, context, position)
180
181
  excepthook(*get_traceback_info(self.error))
@@ -85,7 +85,7 @@ def pys_runner(
85
85
  error, and the context after execution.
86
86
  """
87
87
 
88
- if (context_parent is None) != (context_parent_entry_position is None):
88
+ if TYPECHECK_STACK > 0 and (context_parent is None) != (context_parent_entry_position is None):
89
89
  raise TypeError("context_parent and context_parent_entry_position both must be filled in")
90
90
 
91
91
  context = PysContext(
@@ -255,6 +255,8 @@ try:
255
255
  if os.path.isfile(HISTORY_PATH):
256
256
 
257
257
  def add_to_string():
258
+ if not lines:
259
+ return
258
260
  strings.append('\n'.join(lines))
259
261
  lines.clear()
260
262
 
@@ -267,8 +269,7 @@ try:
267
269
  line = line[1:]
268
270
  lines.append(line)
269
271
 
270
- if lines:
271
- add_to_string()
272
+ add_to_string()
272
273
 
273
274
  else:
274
275
  update_history = True