pyscript-programming-language 1.12.11__tar.gz → 1.12.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/PKG-INFO +5 -2
- pyscript_programming_language-1.12.12/changelog.md +10 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyproject.toml +5 -2
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/__main__.py +61 -46
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/cache.py +3 -2
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/checks.py +2 -1
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/constants.py +2 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/editor/gui.py +42 -7
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/exceptions.py +4 -4
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/highlight.py +26 -15
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/interpreter.py +34 -17
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/lexer.py +2 -2
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/parser.py +4 -1
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/pysbuiltins.py +41 -38
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/pystypes.py +14 -10
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/results.py +6 -8
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/runner.py +12 -8
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/shell.py +2 -2
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/symtab.py +2 -2
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/decorators.py +1 -2
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/generic.py +6 -3
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/version.py +2 -2
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ast/ast_dump.py +4 -3
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/site.pys +3 -5
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/tokenize/tok_untokenize.py +2 -2
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript_programming_language.egg-info/PKG-INFO +5 -2
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/setup.py +5 -2
- pyscript_programming_language-1.12.11/changelog.md +0 -13
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/MANIFEST.in +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/README.md +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/__init__.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/__init__.pyi +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/__init__.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/analyzer.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/bases.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/buffer.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/context.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/editor/__init__.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/editor/bases.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/editor/terminal.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/handlers.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/mapping.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/nodes.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/position.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/token.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/__init__.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/ansi.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/debug.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/module.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/path.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/similarity.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/core/utils/string.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/__hello__.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ansi.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ast/__init__.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ast/ast_literal_eval.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ast/ast_unparse.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/ast/ast_walk.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/brainfuck.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/code.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/dis.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/explorer.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/fpstimer/__init__.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/fpstimer/py_fpstimer.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/getch/__init__.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/getch/py_getch.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/history.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/inspect.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/jsdict.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/keyword.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/opcode.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/parser.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/pdisplay.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/symtable.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/token.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/lib/tokenize/__init__.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/other/.nomedia +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/other/PyScript.ico +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/other/copyright +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/other/credits +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/other/license +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/site-packages/this.pys +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/this.py +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript_programming_language.egg-info/requires.txt +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript_programming_language.egg-info/top_level.txt +0 -0
- {pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/setup.cfg +0 -0
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyscript-programming-language
|
|
3
|
-
Version: 1.12.
|
|
3
|
+
Version: 1.12.12
|
|
4
4
|
Summary: PyScript Programming Language
|
|
5
5
|
Home-page: https://azzammuhyala.github.io/pyscript
|
|
6
6
|
Author: azzammuhyala
|
|
7
7
|
Author-email: azzammuhyala <azzammuhyala@gmail.com>
|
|
8
8
|
License-Expression: MIT
|
|
9
9
|
Project-URL: Homepage, https://azzammuhyala.github.io/pyscript
|
|
10
|
+
Project-URL: Documentation, https://azzammuhyala.github.io/pyscript
|
|
10
11
|
Project-URL: Source, https://github.com/azzammuhyala/pyscript
|
|
11
|
-
Project-URL:
|
|
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
|
{pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyproject.toml
RENAMED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyscript-programming-language"
|
|
7
|
-
version = "1.12.
|
|
7
|
+
version = "1.12.12"
|
|
8
8
|
description = "PyScript Programming Language"
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -34,9 +34,12 @@ classifiers = [
|
|
|
34
34
|
|
|
35
35
|
[project.urls]
|
|
36
36
|
Homepage = "https://azzammuhyala.github.io/pyscript"
|
|
37
|
+
Documentation = "https://azzammuhyala.github.io/pyscript"
|
|
37
38
|
Source = "https://github.com/azzammuhyala/pyscript"
|
|
38
|
-
|
|
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 = [
|
{pyscript_programming_language-1.12.11 → pyscript_programming_language-1.12.12}/pyscript/__main__.py
RENAMED
|
@@ -9,7 +9,7 @@ from .core.editor.terminal import PysTerminalEditor, TERMINAL_SUPPORT
|
|
|
9
9
|
from .core.highlight import (
|
|
10
10
|
PYGMENTS, HLFMT_HTML, HLFMT_ANSI, HLFMT_BBCODE, pys_highlight, PygmentsPyScriptStyle, PygmentsPyScriptLexer
|
|
11
11
|
)
|
|
12
|
-
from .core.runner import
|
|
12
|
+
from .core.runner import _namespace_to_symbol_table, pys_runner, pys_shell
|
|
13
13
|
from .core.utils.debug import USE_NOTEBOOK
|
|
14
14
|
from .core.utils.generic import is_environ
|
|
15
15
|
from .core.utils.module import find_module_path, remove_python_path
|
|
@@ -43,7 +43,6 @@ FORMATER_HIGHLIGHT_MAP = {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
EDITOR_MAP = {}
|
|
46
|
-
|
|
47
46
|
for supported, name, class_editor in [
|
|
48
47
|
(GUI_SUPPORT, 'gui', PysGUIEditor),
|
|
49
48
|
(TERMINAL_SUPPORT, 'terminal', PysTerminalEditor)
|
|
@@ -51,6 +50,8 @@ for supported, name, class_editor in [
|
|
|
51
50
|
if supported:
|
|
52
51
|
EDITOR_MAP[name] = class_editor
|
|
53
52
|
|
|
53
|
+
arguments_requiring_value = {'-l', '--highlight', '-r', '--py-recursion'}
|
|
54
|
+
|
|
54
55
|
parser = ArgumentParser(
|
|
55
56
|
prog=f'{base(sys.executable)} -m pyscript',
|
|
56
57
|
description=f'PyScript Launcher for Python Version {".".join(map(str, sys.version_info))}'
|
|
@@ -83,6 +84,7 @@ if EDITOR_MAP:
|
|
|
83
84
|
default=None,
|
|
84
85
|
help="open the editor panel from a 'file'",
|
|
85
86
|
)
|
|
87
|
+
arguments_requiring_value.update({'-e', '--editor'})
|
|
86
88
|
|
|
87
89
|
parser.add_argument(
|
|
88
90
|
'-i', '--inspect',
|
|
@@ -174,21 +176,28 @@ def argument_error(argument, message):
|
|
|
174
176
|
parser.exit(2, f"{parser.prog}: error: argument {argument}: {message}\n")
|
|
175
177
|
|
|
176
178
|
argv = sys.argv[1:]
|
|
179
|
+
argc = len(argv)
|
|
180
|
+
index = 0
|
|
181
|
+
arg_index = -1
|
|
177
182
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
183
|
+
while index < argc:
|
|
184
|
+
arg = argv[index]
|
|
185
|
+
if not arg.startswith('-') or arg == '--':
|
|
186
|
+
break
|
|
182
187
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
-
|
|
195
|
+
index += 1
|
|
196
|
+
if arg in arguments_requiring_value:
|
|
197
|
+
index += 1
|
|
189
198
|
|
|
190
|
-
args = parser.parse_args(argv if
|
|
191
|
-
arg = args.arg
|
|
199
|
+
args = parser.parse_args(argv if arg_index == -1 else argv[:arg_index])
|
|
200
|
+
arg = args.arg if arg_index == -1 else argv[arg_index:]
|
|
192
201
|
|
|
193
202
|
if args.terminal:
|
|
194
203
|
|
|
@@ -242,28 +251,27 @@ if args.P:
|
|
|
242
251
|
|
|
243
252
|
pys_sys.argv = argv = ['', *arg]
|
|
244
253
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
pass
|
|
254
|
+
def clean_up() -> None:
|
|
255
|
+
g = globals()
|
|
256
|
+
|
|
257
|
+
for name in {
|
|
258
|
+
'ArgumentParser', 'BBCodeFormatter', 'CLASSIC_LINE_SHELL', 'DEBUG', 'DEFAULT', 'DONT_SHOW_BANNER_ON_SHELL',
|
|
259
|
+
'EDITOR_MAP', 'ENV_PYSCRIPT_CLASSIC_LINE_SHELL', 'ENV_PYSCRIPT_NO_COLOR_PROMPT', 'FORMATER_HIGHLIGHT_MAP',
|
|
260
|
+
'FORMATER_PYGMENTS_MAP', 'GUI_SUPPORT', 'HLFMT_ANSI', 'HLFMT_BBCODE', 'HLFMT_HTML', 'HtmlFormatter',
|
|
261
|
+
'LatexFormatter', 'NOTEBOOK', 'NO_COLOR', 'NO_COLOR_PROMPT', 'OPTIONAL', 'PYGMENTS', 'PygmentsPyScriptLexer',
|
|
262
|
+
'PygmentsPyScriptStyle', 'PysFileBuffer', 'PysGUIEditor', 'PysTerminalEditor', 'REMAINDER', 'TERMINAL_SUPPORT',
|
|
263
|
+
'Terminal256Formatter', 'TerminalFormatter', 'TerminalTrueColorFormatter', 'USE_NOTEBOOK', '__version__',
|
|
264
|
+
'_namespace_to_symbol_table', 'arg', 'arg_index', 'argc', 'args', 'argument_error', 'arguments_requiring_value',
|
|
265
|
+
'argv', 'base', 'class_editor', 'clean_up', 'condition', 'ctypes', 'execute', 'fd', 'file', 'find_module_path',
|
|
266
|
+
'flag', 'getcwd', 'highlight', 'i', 'index', 'is_environ', 'kernel32', 'load_file', 'module_path', 'name',
|
|
267
|
+
'normpath', 'parser', 'pys_highlight', 'pys_sys', 'remove_python_path', 'supported'
|
|
268
|
+
}:
|
|
269
|
+
try:
|
|
270
|
+
del g[name]
|
|
271
|
+
except:
|
|
272
|
+
continue
|
|
265
273
|
|
|
266
|
-
def load_file(path):
|
|
274
|
+
def load_file(path) -> PysFileBuffer:
|
|
267
275
|
file = PysFileBuffer('', path)
|
|
268
276
|
try:
|
|
269
277
|
with open(path, 'r', encoding='utf-8') as file:
|
|
@@ -285,31 +293,37 @@ def load_file(path):
|
|
|
285
293
|
argument_error('file', f"file \"{path}\": Unexpected error: {e}")
|
|
286
294
|
return file
|
|
287
295
|
|
|
288
|
-
def execute(file):
|
|
296
|
+
def execute(file: PysFileBuffer) -> None:
|
|
297
|
+
global code
|
|
298
|
+
|
|
299
|
+
not_show_banner_flag = DONT_SHOW_BANNER_ON_SHELL
|
|
300
|
+
inspect = args.inspect
|
|
301
|
+
symtab = _namespace_to_symbol_table(undefined, file)
|
|
302
|
+
|
|
303
|
+
clean_up()
|
|
304
|
+
|
|
289
305
|
result = pys_runner(
|
|
290
306
|
file=file,
|
|
291
307
|
mode='exec',
|
|
292
|
-
symbol_table=
|
|
308
|
+
symbol_table=symtab,
|
|
293
309
|
flags=flags
|
|
294
310
|
)
|
|
295
311
|
|
|
296
312
|
code, _ = result.end_process()
|
|
297
313
|
|
|
298
|
-
if
|
|
314
|
+
if inspect:
|
|
299
315
|
if sys.stdout.closed or sys.stderr.closed:
|
|
300
|
-
|
|
316
|
+
code = 1
|
|
301
317
|
elif sys.stdin.closed:
|
|
302
318
|
print("Can't run interactive shell: sys.stdin closed", file=sys.stderr)
|
|
303
|
-
|
|
319
|
+
code = 1
|
|
304
320
|
else:
|
|
305
|
-
|
|
321
|
+
code = pys_shell(
|
|
306
322
|
globals=result.context.symbol_table,
|
|
307
|
-
flags=result.context.flags |
|
|
323
|
+
flags=result.context.flags | not_show_banner_flag,
|
|
308
324
|
parser_flags=result.parser_flags
|
|
309
325
|
)
|
|
310
326
|
|
|
311
|
-
return code
|
|
312
|
-
|
|
313
327
|
if args.file is not None:
|
|
314
328
|
argv[0] = args.file
|
|
315
329
|
file = load_file(normpath(args.file))
|
|
@@ -341,7 +355,7 @@ if args.file is not None:
|
|
|
341
355
|
argument_error('-l/--highlight', e)
|
|
342
356
|
|
|
343
357
|
else:
|
|
344
|
-
|
|
358
|
+
execute(file)
|
|
345
359
|
|
|
346
360
|
elif args.module is not None:
|
|
347
361
|
_, module_path = find_module_path(None, args.module, '__main__')
|
|
@@ -350,13 +364,14 @@ elif args.module is not None:
|
|
|
350
364
|
|
|
351
365
|
file = load_file(module_path)
|
|
352
366
|
argv[0] = file.name
|
|
353
|
-
|
|
367
|
+
execute(file)
|
|
354
368
|
|
|
355
369
|
elif args.command is not None:
|
|
356
370
|
argv[0] = '-c'
|
|
357
|
-
|
|
371
|
+
execute(PysFileBuffer(args.command, '<arg-command>'))
|
|
358
372
|
|
|
359
373
|
else:
|
|
374
|
+
clean_up()
|
|
360
375
|
code = pys_shell(
|
|
361
376
|
globals=undefined,
|
|
362
377
|
flags=flags
|
|
@@ -2,6 +2,7 @@ from .bases import Pys
|
|
|
2
2
|
from .constants import PYSCRIPT_PATH, CORE_PATH, LIBRARIES_PATH, SITE_PACKAGES_PATH, DEFAULT
|
|
3
3
|
from .utils.debug import print_display, print_traceback, clear_shell
|
|
4
4
|
from .utils.decorators import inheritable, singleton
|
|
5
|
+
from .utils.path import base
|
|
5
6
|
|
|
6
7
|
from types import ModuleType
|
|
7
8
|
from typing import Literal
|
|
@@ -17,7 +18,7 @@ pys_sys = ModuleType(
|
|
|
17
18
|
|
|
18
19
|
pys_sys.__running_shell__ = False
|
|
19
20
|
pys_sys.__running_breakpoint__ = False
|
|
20
|
-
pys_sys.path = [
|
|
21
|
+
pys_sys.path = [LIBRARIES_PATH, SITE_PACKAGES_PATH]
|
|
21
22
|
pys_sys.loading_modules = set()
|
|
22
23
|
pys_sys.modules = {}
|
|
23
24
|
pys_sys.singletons = {}
|
|
@@ -30,7 +31,7 @@ pys_sys.pyscript_path = PYSCRIPT_PATH
|
|
|
30
31
|
pys_sys.core_path = CORE_PATH
|
|
31
32
|
pys_sys.libraries_path = LIBRARIES_PATH
|
|
32
33
|
pys_sys.site_packages_path = SITE_PACKAGES_PATH
|
|
33
|
-
pys_sys.executable = f'
|
|
34
|
+
pys_sys.executable = f'{base(sys.executable)} -m pyscript'
|
|
34
35
|
pys_sys.ps1 = '>>> '
|
|
35
36
|
pys_sys.ps2 = '... '
|
|
36
37
|
|
|
@@ -37,7 +37,8 @@ is_blacklist_python_builtin = frozenset([
|
|
|
37
37
|
]).__contains__
|
|
38
38
|
|
|
39
39
|
is_python_extension = frozenset([
|
|
40
|
-
'.
|
|
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.
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
127
|
+
try:
|
|
128
|
+
with open(GUI_GEOMETRY_PATH, 'r') as f:
|
|
129
|
+
width, height, left, top, zoom = map(
|
|
130
|
+
int,
|
|
131
|
+
re.match(r'(\d{1,7})x(\d{1,7})\+(-?\d{1,7})\+(-?\d{1,7}),(0|1)', f.read(64)).groups()
|
|
132
|
+
)
|
|
133
|
+
self.last_geometry = f'{width}x{height}+{left}+{top}'
|
|
134
|
+
except:
|
|
135
|
+
left = self.winfo_screenwidth() // 2 - 250
|
|
136
|
+
top = self.winfo_screenheight() // 2 - 250
|
|
137
|
+
zoom = False
|
|
138
|
+
self.last_geometry = f'500x500+{left}+{top}'
|
|
139
|
+
save_geometry(left, top, 500, 500, zoom)
|
|
140
|
+
|
|
141
|
+
try:
|
|
142
|
+
self.wm_iconbitmap(ICON_PATH)
|
|
143
|
+
except:
|
|
144
|
+
pass
|
|
145
|
+
|
|
146
|
+
if zoom:
|
|
147
|
+
self.wm_state('zoomed')
|
|
148
|
+
|
|
149
|
+
self.wm_geometry(self.last_geometry)
|
|
115
150
|
self.wm_minsize(300, 250)
|
|
116
151
|
self.wm_protocol('WM_DELETE_WINDOW', on_close)
|
|
117
152
|
|
|
@@ -27,16 +27,16 @@ class PysTraceback(Pys):
|
|
|
27
27
|
# circular import problem solved
|
|
28
28
|
from .cache import pys_sys
|
|
29
29
|
|
|
30
|
-
pys_sys.last_type = type(exception) if isinstance(exception, BaseException) else exception
|
|
31
|
-
pys_sys.last_value = exception if isinstance(exception, BaseException) else None
|
|
32
|
-
pys_sys.last_traceback = self
|
|
33
|
-
|
|
34
30
|
setimuattr(self, 'exception', exception)
|
|
35
31
|
setimuattr(self, 'context', context)
|
|
36
32
|
setimuattr(self, 'position', position)
|
|
37
33
|
setimuattr(self, 'primary', primary)
|
|
38
34
|
setimuattr(self, 'implicit', implicit)
|
|
39
35
|
|
|
36
|
+
pys_sys.last_type = type(exception) if isinstance(exception, BaseException) else exception
|
|
37
|
+
pys_sys.last_value = exception if isinstance(exception, BaseException) else None
|
|
38
|
+
pys_sys.last_traceback = self
|
|
39
|
+
|
|
40
40
|
def __repr__(self) -> str:
|
|
41
41
|
return f'<traceback of {self.exception!r}>'
|
|
42
42
|
|
|
@@ -272,7 +272,7 @@ try:
|
|
|
272
272
|
|
|
273
273
|
'string-escapes': [
|
|
274
274
|
(rf'\\([nrtbfav\'"\\]|{_newlines})', String.Escape),
|
|
275
|
-
(r'\\[0-7]{1,3}
|
|
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 ==
|
|
503
|
+
if ttype == T_NULL:
|
|
493
504
|
type_format = 'end'
|
|
494
505
|
|
|
495
|
-
elif ttype ==
|
|
506
|
+
elif ttype == T_KEYWORD:
|
|
496
507
|
type_format = 'keyword-constant' if is_constant_keyword(tvalue) else 'keyword'
|
|
497
508
|
|
|
498
|
-
elif ttype ==
|
|
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
|
|
516
|
+
while j > 0 and tokens[j].type in T_WHITESPACES:
|
|
506
517
|
j -= 1
|
|
507
|
-
|
|
508
|
-
if
|
|
518
|
+
last_is = tokens[j].match
|
|
519
|
+
if last_is(T_KEYWORD, 'class'):
|
|
509
520
|
type_format = 'identifier-type'
|
|
510
|
-
elif
|
|
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 ==
|
|
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 ==
|
|
530
|
+
elif ttype == T_NUMBER:
|
|
520
531
|
type_format = 'number'
|
|
521
532
|
|
|
522
|
-
elif ttype ==
|
|
533
|
+
elif ttype == T_STRING:
|
|
523
534
|
type_format = 'string'
|
|
524
535
|
|
|
525
|
-
elif ttype ==
|
|
536
|
+
elif ttype == T_NEWLINE:
|
|
526
537
|
type_format = 'newline'
|
|
527
538
|
|
|
528
|
-
elif ttype ==
|
|
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 ==
|
|
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 ==
|
|
561
|
+
if ttype == T_NULL:
|
|
551
562
|
break
|
|
552
563
|
|
|
553
564
|
last_index = token.position.end
|
|
@@ -75,11 +75,7 @@ def visit_IdentifierNode(node: PysIdentifierNode, context: PysContext) -> PysRun
|
|
|
75
75
|
PysTraceback(
|
|
76
76
|
NameError(
|
|
77
77
|
f"name {name!r} is not defined" +
|
|
78
|
-
(
|
|
79
|
-
''
|
|
80
|
-
if closest_symbol is None else
|
|
81
|
-
f". Did you mean {closest_symbol!r}?"
|
|
82
|
-
)
|
|
78
|
+
('' if closest_symbol is None else f". Did you mean {closest_symbol!r}?")
|
|
83
79
|
),
|
|
84
80
|
context,
|
|
85
81
|
position
|
|
@@ -224,12 +220,13 @@ def visit_CallNode(node: PysCallNode, context: PysContext) -> PysRunTimeResult:
|
|
|
224
220
|
args = []
|
|
225
221
|
kwargs = {}
|
|
226
222
|
|
|
223
|
+
b_tuple = tuple
|
|
227
224
|
add_arg = args.append
|
|
228
225
|
add_kwarg = kwargs.__setitem__
|
|
229
226
|
|
|
230
227
|
for nargument in node.arguments:
|
|
231
228
|
|
|
232
|
-
if nargument.__class__ is
|
|
229
|
+
if nargument.__class__ is b_tuple:
|
|
233
230
|
keyword, nvalue = nargument
|
|
234
231
|
add_kwarg(keyword.value, register(get_visitor(nvalue.__class__)(nvalue, context)))
|
|
235
232
|
if should_return():
|
|
@@ -254,6 +251,7 @@ def visit_ChainOperatorNode(node: PysChainOperatorNode, context: PysContext) ->
|
|
|
254
251
|
register = result.register
|
|
255
252
|
should_return = result.should_return
|
|
256
253
|
get_expression = node.expressions.__getitem__
|
|
254
|
+
|
|
257
255
|
first = get_expression(0)
|
|
258
256
|
|
|
259
257
|
left = register(get_visitor(first.__class__)(first, context))
|
|
@@ -517,9 +515,13 @@ def visit_ImportNode(node: PysImportNode, context: PysContext) -> PysRunTimeResu
|
|
|
517
515
|
exported_from = '__dir__()'
|
|
518
516
|
exported_packages = filter(is_public_attribute, dir(module))
|
|
519
517
|
|
|
518
|
+
b_isinstance = isinstance
|
|
519
|
+
b_getattr = getattr
|
|
520
|
+
b_str = str
|
|
521
|
+
|
|
520
522
|
for package in exported_packages:
|
|
521
523
|
|
|
522
|
-
if not
|
|
524
|
+
if not b_isinstance(package, b_str):
|
|
523
525
|
return result.failure(
|
|
524
526
|
PysTraceback(
|
|
525
527
|
TypeError(
|
|
@@ -530,17 +532,18 @@ def visit_ImportNode(node: PysImportNode, context: PysContext) -> PysRunTimeResu
|
|
|
530
532
|
)
|
|
531
533
|
)
|
|
532
534
|
|
|
533
|
-
set_symbol(package,
|
|
535
|
+
set_symbol(package, b_getattr(module, package))
|
|
534
536
|
|
|
535
537
|
if should_return():
|
|
536
538
|
return result
|
|
537
539
|
|
|
538
540
|
elif npackages:
|
|
541
|
+
b_getattr = getattr
|
|
539
542
|
|
|
540
543
|
for tpackage, tas_package in npackages:
|
|
541
544
|
result._position = tpackage.position
|
|
542
545
|
with result:
|
|
543
|
-
set_symbol((tpackage if tas_package is None else tas_package).value,
|
|
546
|
+
set_symbol((tpackage if tas_package is None else tas_package).value, b_getattr(module, tpackage.value))
|
|
544
547
|
if should_return():
|
|
545
548
|
return result
|
|
546
549
|
|
|
@@ -599,9 +602,11 @@ def visit_SwitchNode(node: PysSwitchNode, context: PysContext) -> PysRunTimeResu
|
|
|
599
602
|
return result
|
|
600
603
|
|
|
601
604
|
for ncondition, body in node.case_cases:
|
|
602
|
-
|
|
603
|
-
if
|
|
604
|
-
|
|
605
|
+
|
|
606
|
+
if not fall_through:
|
|
607
|
+
case = register(get_visitor(ncondition.__class__)(ncondition, context))
|
|
608
|
+
if should_return():
|
|
609
|
+
return result
|
|
605
610
|
|
|
606
611
|
result._position = ncondition.position
|
|
607
612
|
with result:
|
|
@@ -690,6 +695,12 @@ def visit_TryNode(node: PysTryNode, context: PysContext) -> PysRunTimeResult:
|
|
|
690
695
|
if error:
|
|
691
696
|
failure = result.failure
|
|
692
697
|
exception = error.exception
|
|
698
|
+
|
|
699
|
+
b_isinstance = isinstance
|
|
700
|
+
b_issubclass = issubclass
|
|
701
|
+
b_type = type
|
|
702
|
+
b_BaseException = BaseException
|
|
703
|
+
|
|
693
704
|
failure(None)
|
|
694
705
|
|
|
695
706
|
for (targets, tparameter), body in node.catch_cases:
|
|
@@ -706,7 +717,7 @@ def visit_TryNode(node: PysTryNode, context: PysContext) -> PysRunTimeResult:
|
|
|
706
717
|
stop = True
|
|
707
718
|
break
|
|
708
719
|
|
|
709
|
-
if not (
|
|
720
|
+
if not (b_isinstance(error_class, b_type) and b_issubclass(error_class, b_BaseException)):
|
|
710
721
|
failure(
|
|
711
722
|
PysTraceback(
|
|
712
723
|
TypeError("catching classes that do not inherit from BaseException is not allowed"),
|
|
@@ -870,13 +881,15 @@ def visit_ForNode(node: PysForNode, context: PysContext) -> PysRunTimeResult:
|
|
|
870
881
|
if should_return():
|
|
871
882
|
return result
|
|
872
883
|
|
|
884
|
+
b_StopIteration = StopIteration
|
|
885
|
+
|
|
873
886
|
def condition():
|
|
874
887
|
with result:
|
|
875
888
|
handle_call(next, context, niteration_position)
|
|
876
889
|
register(visit_declaration_from_AssignmentNode(ndeclaration, context, next()))
|
|
877
890
|
if should_return():
|
|
878
891
|
error = result.error
|
|
879
|
-
if error and is_object_of(error.exception,
|
|
892
|
+
if error and is_object_of(error.exception, b_StopIteration):
|
|
880
893
|
result.failure(None)
|
|
881
894
|
return False
|
|
882
895
|
return True
|
|
@@ -1163,9 +1176,11 @@ def visit_FunctionNode(node: PysFunctionNode, context: PysContext) -> PysRunTime
|
|
|
1163
1176
|
should_return = result.should_return
|
|
1164
1177
|
add_parameter = parameters.append
|
|
1165
1178
|
|
|
1179
|
+
b_tuple = tuple
|
|
1180
|
+
|
|
1166
1181
|
for nparameter in node.parameters:
|
|
1167
1182
|
|
|
1168
|
-
if nparameter.__class__ is
|
|
1183
|
+
if nparameter.__class__ is b_tuple:
|
|
1169
1184
|
keyword, nvalue = nparameter
|
|
1170
1185
|
|
|
1171
1186
|
value = register(get_visitor(nvalue.__class__)(nvalue, context))
|
|
@@ -1240,7 +1255,9 @@ def visit_ThrowNode(node: PysThrowNode, context: PysContext) -> PysRunTimeResult
|
|
|
1240
1255
|
if should_return():
|
|
1241
1256
|
return result
|
|
1242
1257
|
|
|
1243
|
-
|
|
1258
|
+
b_BaseException = BaseException
|
|
1259
|
+
|
|
1260
|
+
if not is_object_of(target, b_BaseException):
|
|
1244
1261
|
return result.failure(
|
|
1245
1262
|
PysTraceback(
|
|
1246
1263
|
TypeError("exceptions must derive from BaseException"),
|
|
@@ -1256,7 +1273,7 @@ def visit_ThrowNode(node: PysThrowNode, context: PysContext) -> PysRunTimeResult
|
|
|
1256
1273
|
if should_return():
|
|
1257
1274
|
return result
|
|
1258
1275
|
|
|
1259
|
-
if not is_object_of(primary,
|
|
1276
|
+
if not is_object_of(primary, b_BaseException):
|
|
1260
1277
|
return result.failure(
|
|
1261
1278
|
PysTraceback(
|
|
1262
1279
|
TypeError("exceptions must derive from BaseException"),
|