pyscript-programming-language 1.13.4__tar.gz → 1.14.0__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 (92) hide show
  1. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/PKG-INFO +27 -25
  2. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/README.md +26 -24
  3. pyscript_programming_language-1.14.0/changelog.md +21 -0
  4. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyproject.toml +1 -1
  5. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/__init__.py +2 -1
  6. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/__init__.pyi +1 -0
  7. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/__main__.py +87 -48
  8. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/constants.py +1 -1
  9. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/context.py +7 -10
  10. pyscript_programming_language-1.14.0/pyscript/core/editor/__init__.py +31 -0
  11. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/editor/bases.py +16 -16
  12. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/editor/gui.py +23 -22
  13. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/editor/terminal.py +3 -3
  14. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/exceptions.py +8 -13
  15. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/handlers.py +34 -32
  16. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/interpreter.py +21 -18
  17. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/lexer.py +5 -8
  18. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/mapping.py +8 -8
  19. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/parser.py +99 -45
  20. pyscript_programming_language-1.14.0/pyscript/core/position.py +120 -0
  21. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/pysbuiltins.py +39 -46
  22. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/pystypes.py +16 -5
  23. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/runner.py +5 -5
  24. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/shell.py +10 -12
  25. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/symtab.py +14 -15
  26. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/token.py +3 -4
  27. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/utils/ansi.py +70 -45
  28. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/utils/debug.py +18 -5
  29. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/utils/generic.py +22 -3
  30. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/utils/similarity.py +8 -6
  31. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/utils/string.py +6 -11
  32. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/version.py +2 -2
  33. pyscript_programming_language-1.14.0/pyscript/lib/ansi.pys +1 -0
  34. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/brainfuck.pys +3 -6
  35. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/parser.pys +6 -4
  36. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript_programming_language.egg-info/PKG-INFO +27 -25
  37. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript_programming_language.egg-info/SOURCES.txt +0 -1
  38. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/setup.py +1 -1
  39. pyscript_programming_language-1.13.4/changelog.md +0 -20
  40. pyscript_programming_language-1.13.4/pyscript/core/editor/__init__.py +0 -15
  41. pyscript_programming_language-1.13.4/pyscript/core/position.py +0 -115
  42. pyscript_programming_language-1.13.4/pyscript/lib/ansi.pys +0 -14
  43. pyscript_programming_language-1.13.4/pyscript/site-packages/anniversary.pys +0 -4
  44. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/MANIFEST.in +0 -0
  45. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/__init__.py +0 -0
  46. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/analyzer.py +0 -0
  47. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/bases.py +0 -0
  48. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/buffer.py +0 -0
  49. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/cache.py +0 -0
  50. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/checks.py +0 -0
  51. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/highlight.py +0 -0
  52. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/nodes.py +0 -0
  53. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/results.py +0 -0
  54. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/utils/__init__.py +0 -0
  55. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/utils/decorators.py +0 -0
  56. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/utils/module.py +0 -0
  57. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/core/utils/path.py +0 -0
  58. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/__hello__.pys +0 -0
  59. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/ast/__init__.pys +0 -0
  60. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/ast/ast_dump.py +0 -0
  61. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/ast/ast_literal_eval.py +0 -0
  62. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/ast/ast_unparse.py +0 -0
  63. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/ast/ast_walk.py +0 -0
  64. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/code.pys +0 -0
  65. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/dis.pys +0 -0
  66. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/explorer.pys +0 -0
  67. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/fpstimer/__init__.pys +0 -0
  68. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/fpstimer/py_fpstimer.py +0 -0
  69. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/getch/__init__.pys +0 -0
  70. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/getch/py_getch.py +0 -0
  71. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/history.pys +0 -0
  72. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/inspect.pys +0 -0
  73. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/jsdict.pys +0 -0
  74. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/keyword.pys +0 -0
  75. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/opcode.pys +0 -0
  76. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/pdisplay.pys +0 -0
  77. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/site.pys +0 -0
  78. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/symtable.pys +0 -0
  79. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/token.pys +0 -0
  80. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/tokenize/__init__.pys +0 -0
  81. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/lib/tokenize/tok_untokenize.py +0 -0
  82. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/other/.nomedia +0 -0
  83. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/other/PyScript.ico +0 -0
  84. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/other/copyright +0 -0
  85. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/other/credits +0 -0
  86. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/other/license +0 -0
  87. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/site-packages/this.pys +0 -0
  88. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript/this.py +0 -0
  89. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  90. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript_programming_language.egg-info/requires.txt +0 -0
  91. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  92. {pyscript_programming_language-1.13.4 → pyscript_programming_language-1.14.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.13.4
3
+ Version: 1.14.0
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://azzammuhyala.github.io/pyscript
6
6
  Author: AzzamMuhyala
@@ -107,22 +107,23 @@ Familiar? There it is!
107
107
  | 2 | `builtins` | **required** |
108
108
  | 3 | `cmath` | **required** |
109
109
  | 4 | `collections.abc` | **required** |
110
- | 5 | `functools` | **required** |
111
- | 6 | `html` | **required** |
112
- | 7 | `importlib` | **required** |
113
- | 8 | `inspect` | **required** |
114
- | 9 | `io` | **required** |
115
- | 10 | `itertools` | **required** |
116
- | 11 | `json` | **required** |
117
- | 12 | `operator` | **required** |
118
- | 13 | `os` | **required** |
119
- | 14 | `re` | **required** |
120
- | 15 | `subprocess` | **required** |
121
- | 16 | `sys` | **required** |
122
- | 17 | `threading` | **required** |
123
- | 18 | `types` | **required** |
124
- | 19 | `typing` | **required** |
125
- | 20 | `unicodedata` | **required** |
110
+ | 5 | `difflib` | **required** |
111
+ | 6 | `functools` | **required** |
112
+ | 7 | `html` | **required** |
113
+ | 8 | `importlib` | **required** |
114
+ | 9 | `inspect` | **required** |
115
+ | 10 | `io` | **required** |
116
+ | 11 | `itertools` | **required** |
117
+ | 12 | `json` | **required** |
118
+ | 13 | `operator` | **required** |
119
+ | 14 | `os` | **required** |
120
+ | 15 | `pkgutil` | **required** |
121
+ | 16 | `re` | **required** |
122
+ | 17 | `subprocess` | **required** |
123
+ | 18 | `sys` | **required** |
124
+ | 19 | `types` | **required** |
125
+ | 20 | `typing` | **required** |
126
+ | 21 | `unicodedata` | **required** |
126
127
  | 1 | `ast` | **required (library)** |
127
128
  | 2 | `msvcrt` | **required (library)** |
128
129
  | 3 | `pprint` | **required (library)** |
@@ -131,17 +132,18 @@ Familiar? There it is!
131
132
  | 6 | `termios` | **required (library)** |
132
133
  | 7 | `time` | **required (library)** |
133
134
  | 8 | `tty` | **required (library)** |
134
- | 1 | `beartype` | **optional** |
135
- | 2 | `prompt_toolkit` | **optional** |
136
- | 3 | `pygments` | **optional** |
137
- | 4 | `readline` | **optional** |
138
- | 5 | `tkinter` | **optional** |
139
- | 6 | `IPython` | **optional** |
135
+ | 1 | `_colorize` | **optional** |
136
+ | 2 | `beartype` | **optional** |
137
+ | 3 | `prompt_toolkit` | **optional** |
138
+ | 4 | `pygments` | **optional** |
139
+ | 5 | `readline` | **optional** |
140
+ | 6 | `threading` | **optional** |
141
+ | 7 | `tkinter` | **optional** |
142
+ | 8 | `IPython` | **optional** |
140
143
 
141
144
  ### Status Explanation
142
145
  - **required**: Required by PyScript entirely.
143
- - **required (library)**: Required PyScript library (located in `pyscript/lib`). PyScript is not affected unless you
144
- import it.
146
+ - **required (library)**: Required by PyScript optional library. PyScript is not affected, unless you import it.
145
147
  - **optional**: Not required, but if it is present, some features can be used without issue.
146
148
 
147
149
  ## Highlights 🎨
@@ -75,22 +75,23 @@ Familiar? There it is!
75
75
  | 2 | `builtins` | **required** |
76
76
  | 3 | `cmath` | **required** |
77
77
  | 4 | `collections.abc` | **required** |
78
- | 5 | `functools` | **required** |
79
- | 6 | `html` | **required** |
80
- | 7 | `importlib` | **required** |
81
- | 8 | `inspect` | **required** |
82
- | 9 | `io` | **required** |
83
- | 10 | `itertools` | **required** |
84
- | 11 | `json` | **required** |
85
- | 12 | `operator` | **required** |
86
- | 13 | `os` | **required** |
87
- | 14 | `re` | **required** |
88
- | 15 | `subprocess` | **required** |
89
- | 16 | `sys` | **required** |
90
- | 17 | `threading` | **required** |
91
- | 18 | `types` | **required** |
92
- | 19 | `typing` | **required** |
93
- | 20 | `unicodedata` | **required** |
78
+ | 5 | `difflib` | **required** |
79
+ | 6 | `functools` | **required** |
80
+ | 7 | `html` | **required** |
81
+ | 8 | `importlib` | **required** |
82
+ | 9 | `inspect` | **required** |
83
+ | 10 | `io` | **required** |
84
+ | 11 | `itertools` | **required** |
85
+ | 12 | `json` | **required** |
86
+ | 13 | `operator` | **required** |
87
+ | 14 | `os` | **required** |
88
+ | 15 | `pkgutil` | **required** |
89
+ | 16 | `re` | **required** |
90
+ | 17 | `subprocess` | **required** |
91
+ | 18 | `sys` | **required** |
92
+ | 19 | `types` | **required** |
93
+ | 20 | `typing` | **required** |
94
+ | 21 | `unicodedata` | **required** |
94
95
  | 1 | `ast` | **required (library)** |
95
96
  | 2 | `msvcrt` | **required (library)** |
96
97
  | 3 | `pprint` | **required (library)** |
@@ -99,17 +100,18 @@ Familiar? There it is!
99
100
  | 6 | `termios` | **required (library)** |
100
101
  | 7 | `time` | **required (library)** |
101
102
  | 8 | `tty` | **required (library)** |
102
- | 1 | `beartype` | **optional** |
103
- | 2 | `prompt_toolkit` | **optional** |
104
- | 3 | `pygments` | **optional** |
105
- | 4 | `readline` | **optional** |
106
- | 5 | `tkinter` | **optional** |
107
- | 6 | `IPython` | **optional** |
103
+ | 1 | `_colorize` | **optional** |
104
+ | 2 | `beartype` | **optional** |
105
+ | 3 | `prompt_toolkit` | **optional** |
106
+ | 4 | `pygments` | **optional** |
107
+ | 5 | `readline` | **optional** |
108
+ | 6 | `threading` | **optional** |
109
+ | 7 | `tkinter` | **optional** |
110
+ | 8 | `IPython` | **optional** |
108
111
 
109
112
  ### Status Explanation
110
113
  - **required**: Required by PyScript entirely.
111
- - **required (library)**: Required PyScript library (located in `pyscript/lib`). PyScript is not affected unless you
112
- import it.
114
+ - **required (library)**: Required by PyScript optional library. PyScript is not affected, unless you import it.
113
115
  - **optional**: Not required, but if it is present, some features can be used without issue.
114
116
 
115
117
  ## Highlights 🎨
@@ -0,0 +1,21 @@
1
+ # Change Logs
2
+
3
+ ## [1.14.0] - 05/10/2026
4
+
5
+ ### Added
6
+ - All editors are not loaded when PyScript is loaded.
7
+ - `pys_sys` is available in the main `__init__`.
8
+ - The `import` statement can import several modules at once with a comma (`,`) as separator.
9
+ - Display of help, error, etc. arguments in argparser can be colored and not from `-n` / `--no-color` arguments.
10
+ - _etc._
11
+
12
+ ### Fixed
13
+ - Fixed some bugs.
14
+ - `PysContext`, `PysSymbolTable`, and `PysTraceback` are now mutable for performance.
15
+ - Environ `PYSCRIPT_NO_GIL` changed to `PYSCRIPT_WITH_GIL` (default without GIL).
16
+ - _etc._
17
+
18
+ ### Removed
19
+ - The `NotImplementedError` exception is not catch by the builtin function as a sign that the object does not support an
20
+ operation.
21
+ - _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.4"
7
+ version = "1.14.0"
8
8
  description = "PyScript Programming Language"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.10"
@@ -12,7 +12,7 @@ from .core.constants import (
12
12
  DEFAULT, NO_COLOR, NO_WARNING, SILENT, DEBUG, RETURN_RESULT, DONT_SHOW_BANNER_ON_SHELL, CLASSIC_LINE_SHELL,
13
13
  NO_COLOR_PROMPT, NOTEBOOK, LEXER_HIGHLIGHT, DICT_TO_JSDICT
14
14
  )
15
- from .core.cache import undefined
15
+ from .core.cache import pys_sys, undefined
16
16
  from .core.highlight import (
17
17
  HLFMT_HTML, HLFMT_ANSI, HLFMT_BBCODE, pys_highlight, PygmentsPyScriptStyle, PygmentsPyScriptLexer,
18
18
  PygmentsPyScriptShellLexer
@@ -38,6 +38,7 @@ __all__ = (
38
38
  'HLFMT_ANSI',
39
39
  'HLFMT_BBCODE',
40
40
  'undefined',
41
+ 'pys_sys',
41
42
  'version',
42
43
  'version_info',
43
44
  'pys_highlight',
@@ -37,6 +37,7 @@ HLFMT_HTML: PysHighlightFormatter
37
37
  HLFMT_ANSI: PysHighlightFormatter
38
38
  HLFMT_BBCODE: PysHighlightFormatter
39
39
 
40
+ pys_sys: ModuleType
40
41
  undefined: PysUndefined
41
42
  version: str
42
43
  version_info: PysVersionInfo
@@ -4,8 +4,7 @@ from .core.constants import (
4
4
  ENV_PYSCRIPT_NO_COLOR_PROMPT, ENV_PYSCRIPT_CLASSIC_LINE_SHELL, DEFAULT, NO_COLOR, NO_WARNING, DEBUG,
5
5
  DONT_SHOW_BANNER_ON_SHELL, CLASSIC_LINE_SHELL, NO_COLOR_PROMPT, NOTEBOOK
6
6
  )
7
- from .core.editor.gui import PysGUIEditor, GUI_SUPPORT
8
- from .core.editor.terminal import PysTerminalEditor, TERMINAL_SUPPORT
7
+ from .core import editor
9
8
  from .core.highlight import (
10
9
  PYGMENTS, HLFMT_HTML, HLFMT_ANSI, HLFMT_BBCODE, pys_highlight, PygmentsPyScriptStyle, PygmentsPyScriptLexer
11
10
  )
@@ -33,24 +32,29 @@ if PYGMENTS:
33
32
  }
34
33
 
35
34
  from argparse import OPTIONAL, REMAINDER, ArgumentParser
35
+ from re import compile as compile_regex
36
36
 
37
37
  import sys
38
38
 
39
+ if sys.version_info >= (3, 13):
40
+ try:
41
+ from _colorize import can_colorize
42
+ COLORIZE = can_colorize()
43
+ except:
44
+ # respect for NO_COLOR, see more here: https://no-color.org
45
+ COLORIZE = not is_environ('NO_COLOR')
46
+ else:
47
+ COLORIZE = True
48
+
39
49
  FORMATER_HIGHLIGHT_MAP = {
40
50
  'html': HLFMT_HTML,
41
51
  'ansi': HLFMT_ANSI,
42
52
  'bbcode': HLFMT_BBCODE
43
53
  }
44
54
 
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
- }
52
-
53
- arguments_requiring_value = {'-l', '--highlight', '-r', '--py-recursion'}
55
+ editors = tuple(editor for editor in editor.__all__ if editor != 'bases')
56
+ arguments_requiring_argv = {'-c', '--command', '-m', '--module'}
57
+ arguments_requiring_value = {'-e', '--editor', '-l', '--highlight', '-r', '--py-recursion'}
54
58
 
55
59
  parser = ArgumentParser(
56
60
  prog=f'{base(sys.executable)} -m pyscript',
@@ -77,14 +81,12 @@ parser.add_argument(
77
81
  help="set a debug flag, this will ignore assert statement. Check the flag is active with the __debug__ keyword"
78
82
  )
79
83
 
80
- if EDITOR_MAP:
81
- parser.add_argument(
82
- '-e', '--editor',
83
- choices=tuple(EDITOR_MAP.keys()),
84
- default=None,
85
- help="open the editor panel from a 'file'",
86
- )
87
- arguments_requiring_value.update({'-e', '--editor'})
84
+ parser.add_argument(
85
+ '-e', '--editor',
86
+ choices=editors,
87
+ default=None,
88
+ help="open the editor panel from a 'file'",
89
+ )
88
90
 
89
91
  parser.add_argument(
90
92
  '-i', '--inspect',
@@ -185,23 +187,27 @@ argv = sys.argv[1:]
185
187
  argc = len(argv)
186
188
  index = 0
187
189
  arg_index = -1
190
+ parser_color = COLORIZE
188
191
 
189
192
  while index < argc:
190
193
  arg = argv[index]
191
- if not arg.startswith('-') or arg == '--':
192
- break
193
194
 
194
- if arg in ('-c', '--command'):
195
- arg_index = index + 2
195
+ if not arg.startswith('-') or arg == '--':
196
196
  break
197
- elif arg in ('-m', '--module'):
197
+ elif arg in arguments_requiring_argv:
198
198
  arg_index = index + 2
199
199
  break
200
+ elif arg in ('-n', '--no-color'):
201
+ parser_color = False
200
202
 
201
203
  index += 1
202
204
  if arg in arguments_requiring_value:
203
205
  index += 1
204
206
 
207
+ if sys.version_info >= (3, 14):
208
+ parser.color = parser_color
209
+ parser.suggest_on_error = True
210
+
205
211
  args = parser.parse_args(argv if arg_index == -1 else argv[:arg_index])
206
212
  arg = args.arg if arg_index == -1 else argv[arg_index:]
207
213
 
@@ -226,7 +232,7 @@ if args.terminal:
226
232
  pass
227
233
 
228
234
  if args.file is None:
229
- if EDITOR_MAP and args.editor:
235
+ if args.editor:
230
236
  argument_error('-e/--editor', "argument 'file' is required")
231
237
  elif args.highlight:
232
238
  argument_error('-l/--highlight', "argument 'file' is required")
@@ -237,13 +243,17 @@ if args.py_recursion is not None:
237
243
  except BaseException as e:
238
244
  argument_error('-r/--py-recursion', e)
239
245
 
246
+ if args.P:
247
+ for cwd in {'', '.', getcwd()}:
248
+ remove_python_path(cwd)
249
+
240
250
  code = 0
241
251
  flags = DEFAULT
242
252
 
243
253
  for condition, flag in [
244
254
  (args.notebook or USE_NOTEBOOK, NOTEBOOK),
245
255
  (args.classic_line_shell or is_environ(ENV_PYSCRIPT_CLASSIC_LINE_SHELL), CLASSIC_LINE_SHELL),
246
- (args.no_color or is_environ('NO_COLOR'), NO_COLOR),
256
+ (args.no_color or not COLORIZE, NO_COLOR),
247
257
  (args.no_color_prompt or is_environ(ENV_PYSCRIPT_NO_COLOR_PROMPT), NO_COLOR_PROMPT),
248
258
  (args.debug, DEBUG),
249
259
  (args.no_warning, NO_WARNING),
@@ -252,52 +262,78 @@ for condition, flag in [
252
262
  if condition:
253
263
  flags |= flag
254
264
 
255
- if args.P:
256
- for cwd in {'', '.', getcwd()}:
257
- remove_python_path(cwd)
258
-
259
265
  pys_sys.argv = argv = ['', *arg]
260
266
 
261
267
  def clean_up() -> None:
262
268
  g = globals()
263
269
 
264
270
  for name in {
265
- 'ArgumentParser', 'BBCodeFormatter', 'CLASSIC_LINE_SHELL', 'DEBUG', 'DEFAULT', 'EDITOR_MAP',
266
- 'ENV_PYSCRIPT_CLASSIC_LINE_SHELL', 'ENV_PYSCRIPT_NO_COLOR_PROMPT', 'FORMATER_HIGHLIGHT_MAP',
267
- 'FORMATER_PYGMENTS_MAP', 'GUI_SUPPORT', 'HLFMT_ANSI', 'HLFMT_BBCODE', 'HLFMT_HTML', 'HtmlFormatter',
268
- 'LatexFormatter', 'NOTEBOOK', 'NO_COLOR', 'NO_WARNING', 'NO_COLOR_PROMPT', 'OPTIONAL', 'PYGMENTS',
269
- 'PygmentsPyScriptLexer', 'PygmentsPyScriptStyle', 'PysFileBuffer', 'PysGUIEditor', 'PysTerminalEditor',
270
- 'REMAINDER', 'TERMINAL_SUPPORT', 'Terminal256Formatter', 'TerminalFormatter', 'TerminalTrueColorFormatter',
271
- 'USE_NOTEBOOK', '__version__', '_namespace_to_symbol_table', 'arg', 'arg_index', 'argc', 'args',
271
+ 'ArgumentParser', 'BBCodeFormatter', 'CLASSIC_LINE_SHELL', 'DEBUG', 'DEFAULT', 'i', 'index', 'is_environ', 'fd',
272
+ 'kernel32', 'ENV_PYSCRIPT_CLASSIC_LINE_SHELL', 'ENV_PYSCRIPT_NO_COLOR_PROMPT', 'FORMATER_HIGHLIGHT_MAP', 'arg',
273
+ 'FORMATER_PYGMENTS_MAP', 'HLFMT_ANSI', 'HLFMT_BBCODE', 'HLFMT_HTML', 'HtmlFormatter', 'OPTIONAL', 'PYGMENTS',
274
+ 'LatexFormatter', 'NOTEBOOK', 'NO_COLOR', 'NO_WARNING', 'NO_COLOR_PROMPT', 'PygmentsPyScriptLexer', 'args',
275
+ 'PygmentsPyScriptStyle', 'PysFileBuffer', 'REMAINDER', 'Terminal256Formatter', 'TerminalFormatter', 'flag',
276
+ 'TerminalTrueColorFormatter', 'USE_NOTEBOOK', '__version__', '_namespace_to_symbol_table', 'arg_index', 'argc',
272
277
  'argument_error', 'arguments_requiring_value', 'argv', 'base', 'clean_up', 'condition', 'ctypes', 'execute',
273
- 'fd', 'file', 'find_module_path', 'flag', 'getcwd', 'highlight', 'i', 'index', 'is_environ', 'kernel32',
274
- 'load_file', 'module_path', 'parser', 'pys_highlight', 'pys_sys', 'remove_python_path'
278
+ 'file', 'find_module_path', 'getcwd', 'highlight', 'load_editor_module', 'load_file', 'module_path', 'parser',
279
+ 'pys_highlight', 'pys_sys', 'remove_python_path', 'editors', 'editor', 'compile_regex', 'can_colorize',
280
+ 'arguments_requiring_argv', 'COLORIZE', 'parser_color'
275
281
  }:
276
282
  try:
277
283
  del g[name]
278
284
  except:
279
285
  continue
280
286
 
287
+ def load_editor_module(name: str) -> tuple[type | None, bool]:
288
+ if name not in editors:
289
+ return None, False
290
+
291
+ module = getattr(editor, name, None)
292
+ if module is None:
293
+ return None, False
294
+
295
+ class_name = compile_regex(r'Pys[A-Za-z0-9_]+Editor').fullmatch
296
+ support_name = compile_regex(r'[A-Z0-9_]+_SUPPORT').fullmatch
297
+
298
+ cls = None
299
+ support = None
300
+ for name in dir(module):
301
+ if not (cls is None or support is None):
302
+ break
303
+ elif class_name(name) and cls is None:
304
+ cls = getattr(module, name)
305
+ elif support_name(name) and support is None:
306
+ support = getattr(module, name)
307
+ else:
308
+ return None, False
309
+
310
+ return cls, support
311
+
281
312
  def load_file(path) -> PysFileBuffer:
282
313
  normalized = normpath(path)
314
+
315
+ def open_error(message: str) -> None:
316
+ argument_error('file', f"can't open file \"{normalized}\": {message}")
317
+
283
318
  try:
284
319
  with open(normalized, 'r', encoding=pys_sys.encoding) as file:
285
320
  return PysFileBuffer(file, normalized)
286
321
  except FileNotFoundError:
287
- if not (EDITOR_MAP and args.editor):
288
- argument_error('file', f"can't open file \"{normalized}\": No such file or directory")
322
+ if not args.editor:
323
+ open_error("No such file or directory")
289
324
  except PermissionError:
290
- argument_error('file', f"can't open file \"{normalized}\": Permission denied")
325
+ open_error("Permission denied")
291
326
  except IsADirectoryError:
292
- argument_error('file', f"can't open file \"{normalized}\": Path is not a file")
327
+ open_error("Path is not a file")
293
328
  except NotADirectoryError:
294
- argument_error('file', f"can't open file \"{normalized}\": Attempting to access directory from file")
329
+ open_error("Attempting to access directory from file")
295
330
  except (OSError, IOError):
296
- argument_error('file', f"can't open file \"{normalized}\": Attempting to access a system directory or file")
331
+ open_error("Attempting to access a system directory or file")
297
332
  except UnicodeDecodeError:
298
- argument_error('file', f"can't read file \"{normalized}\": Bad file")
333
+ open_error("Bad file")
299
334
  except BaseException as e:
300
335
  argument_error('file', f"file \"{normalized}\": Unexpected error: {e}")
336
+
301
337
  return PysFileBuffer('', path)
302
338
 
303
339
  def execute(file: PysFileBuffer) -> None:
@@ -334,9 +370,12 @@ if args.file is not None:
334
370
  argv[0] = args.file
335
371
  file = load_file(args.file)
336
372
 
337
- if EDITOR_MAP and args.editor:
373
+ if args.editor:
374
+ cls, supported = load_editor_module(args.editor)
375
+ if not supported:
376
+ argument_error('-e/--editor', f"'{args.editor}' mode not supported")
338
377
  try:
339
- EDITOR_MAP[args.editor](file=file, colored=not (flags & NO_COLOR)).run()
378
+ cls(file, colored=not (flags & NO_COLOR)).run()
340
379
  except BaseException as e:
341
380
  argument_error('-e/--editor', e)
342
381
 
@@ -10,7 +10,7 @@ GLOBAL_HISTORY_PATH = os.path.join(os.path.expanduser('~'), '.pyscript_history')
10
10
  CONFIGURATIONS_PATH = os.path.join(OTHER_PATH, 'configurations.json')
11
11
 
12
12
  ENV_PYSCRIPT_NO_EXCEPTHOOK = 'PYSCRIPT_NO_EXCEPTHOOK'
13
- ENV_PYSCRIPT_NO_GIL = 'PYSCRIPT_NO_GIL'
13
+ ENV_PYSCRIPT_WITH_GIL = 'PYSCRIPT_WITH_GIL'
14
14
  ENV_PYSCRIPT_NO_READLINE = 'PYSCRIPT_NO_READLINE'
15
15
  ENV_PYSCRIPT_NO_TYPECHECK = 'PYSCRIPT_NO_TYPECHECK'
16
16
  ENV_PYSCRIPT_NO_COLOR_PROMPT = 'PYSCRIPT_NO_COLOR_PROMPT'
@@ -3,12 +3,9 @@ from .buffer import PysFileBuffer
3
3
  from .constants import DEFAULT
4
4
  from .position import PysPosition
5
5
  from .symtab import PysSymbolTable, PysClassSymbolTable
6
- from .utils.decorators import immutable
7
- from .utils.generic import setimuattr
8
6
 
9
7
  from typing import Optional
10
8
 
11
- @immutable
12
9
  class PysContext(Pys):
13
10
 
14
11
  __slots__ = ('file', 'name', 'qualname', 'flags', 'symbol_table', 'parent', 'parent_entry_position')
@@ -28,13 +25,13 @@ class PysContext(Pys):
28
25
  if flags is None and parent:
29
26
  flags = parent.flags
30
27
 
31
- setimuattr(self, 'file', file)
32
- setimuattr(self, 'name', name)
33
- setimuattr(self, 'qualname', qualname)
34
- setimuattr(self, 'flags', DEFAULT if flags is None else flags)
35
- setimuattr(self, 'symbol_table', symbol_table)
36
- setimuattr(self, 'parent', parent)
37
- setimuattr(self, 'parent_entry_position', parent_entry_position)
28
+ self.file = file
29
+ self.name = name
30
+ self.qualname = qualname
31
+ self.flags = DEFAULT if flags is None else flags
32
+ self.symbol_table = symbol_table
33
+ self.parent = parent
34
+ self.parent_entry_position = parent_entry_position
38
35
 
39
36
  class PysClassContext(PysContext):
40
37
 
@@ -0,0 +1,31 @@
1
+ """
2
+ All Editor Application Implementations for PyScript.
3
+
4
+ Not all editors are loaded (lazy import).
5
+ """
6
+
7
+ from ..utils.path import normpath
8
+
9
+ from importlib import import_module as _import
10
+ from os.path import dirname
11
+ from pkgutil import iter_modules
12
+
13
+ __all__ = tuple(frozenset(
14
+ name for _, name, _ in
15
+ iter_modules((dirname(normpath(__file__)),))
16
+ ))
17
+
18
+ def __getattr__(name: str):
19
+ g = globals()
20
+ if name in g:
21
+ return g[name]
22
+ elif name in __all__:
23
+ module = _import(f'{__name__}.{name}')
24
+ g[name] = module
25
+ return module
26
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
27
+
28
+ def __dir__() -> list[str]:
29
+ return sorted(tuple(globals().keys()) + __all__)
30
+
31
+ del normpath, iter_modules, dirname
@@ -3,24 +3,25 @@ from ..buffer import PysFileBuffer
3
3
  from ..cache import pys_sys
4
4
  from ..constants import CONFIGURATIONS_PATH
5
5
  from ..utils.decorators import typecheck, inheritable
6
- from ..utils.generic import setimuattr
6
+ from ..utils.generic import delimuattr
7
7
  from ..utils.string import normstr
8
8
 
9
9
  from json import dump, load
10
+ from os.path import basename
10
11
  from typing import Any
11
12
 
12
- import os
13
-
14
13
  class PysEditor(Pys):
15
14
 
16
15
  @typecheck
17
16
  def __init__(self, file: PysFileBuffer, colored: bool = True) -> None:
18
17
  self.file = file
19
18
  self.colored = bool(colored)
20
- self.basename = os.path.basename(self.file.name)
19
+ self.basename = basename(self.file.name)
21
20
  self.used = False
22
21
  self.modified = False
23
22
 
23
+ self.load_configuration()
24
+
24
25
  def __init_subclass__(cls, **kwargs) -> None:
25
26
  super().__init_subclass__(**kwargs)
26
27
  inheritable(cls)
@@ -29,20 +30,17 @@ class PysEditor(Pys):
29
30
  try:
30
31
  with open(CONFIGURATIONS_PATH, 'r', encoding=pys_sys.encoding) as file:
31
32
  result = load(file)
32
- if not isinstance(result, dict):
33
+ if not isinstance(result, dict):
34
+ raise ValueError
35
+ for key in result:
36
+ if not isinstance(key, str):
33
37
  raise ValueError
34
- for key in result:
35
- if not isinstance(key, str):
36
- raise ValueError
37
- self.configurations = result
38
+ self.configurations = result
38
39
  except:
39
40
  self.configurations = {}
40
41
 
41
42
  def get_configuration(self, configuration: str, default: Any) -> Any:
42
- if configuration in self.configurations:
43
- return self.configurations[configuration]
44
- self.configurations[configuration] = default
45
- return default
43
+ return self.configurations.setdefault(configuration, default)
46
44
 
47
45
  def set_configuration(self, configuration: str, value: Any) -> None:
48
46
  self.configurations[configuration] = value
@@ -55,11 +53,12 @@ class PysEditor(Pys):
55
53
  pass
56
54
 
57
55
  def save(self, text) -> None:
56
+ if not self.modified:
57
+ return
58
+
58
59
  try:
59
- text = normstr(text)
60
60
  with open(self.file.name, 'w', encoding=pys_sys.encoding) as file:
61
- file.write(text)
62
- setimuattr(self.file, 'text', text)
61
+ file.write(normstr(text))
63
62
  except:
64
63
  pass
65
64
  else:
@@ -68,4 +67,5 @@ class PysEditor(Pys):
68
67
  def run(self) -> None:
69
68
  if self.used:
70
69
  raise RuntimeError("one application object can only be used once")
70
+ delimuattr(self.file, 'text')
71
71
  self.used = True