pyscript-programming-language 1.15.0.dev1__py3-none-any.whl → 1.15.1__py3-none-any.whl
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/__main__.py +9 -7
- pyscript/core/editor/gui.py +16 -8
- pyscript/core/highlight.py +0 -1
- pyscript/core/interpreter.py +6 -21
- pyscript/core/mapping.py +8 -5
- pyscript/core/nodes.py +14 -5
- pyscript/core/parser.py +45 -19
- pyscript/core/pysbuiltins.py +28 -27
- pyscript/core/pystypes.py +1 -1
- pyscript/core/runner.py +4 -3
- pyscript/core/token.py +1 -0
- pyscript/core/utils/debug.py +2 -2
- pyscript/core/utils/decorators.py +3 -2
- pyscript/core/utils/generic.py +3 -2
- pyscript/core/utils/module.py +3 -0
- pyscript/core/utils/string.py +3 -1
- pyscript/core/version.py +13 -2
- pyscript/lib/brainfuck.pys +17 -23
- pyscript/lib/dual/__init__.pys +5 -3
- pyscript/lib/dual/py_dual.py +94 -49
- pyscript/lib/getch/py_getch.py +2 -2
- pyscript/other/message.txt +62 -0
- {pyscript_programming_language-1.15.0.dev1.dist-info → pyscript_programming_language-1.15.1.dist-info}/METADATA +20 -17
- {pyscript_programming_language-1.15.0.dev1.dist-info → pyscript_programming_language-1.15.1.dist-info}/RECORD +26 -25
- {pyscript_programming_language-1.15.0.dev1.dist-info → pyscript_programming_language-1.15.1.dist-info}/WHEEL +1 -1
- {pyscript_programming_language-1.15.0.dev1.dist-info → pyscript_programming_language-1.15.1.dist-info}/top_level.txt +0 -0
pyscript/__main__.py
CHANGED
|
@@ -9,10 +9,11 @@ from .core.highlight import (
|
|
|
9
9
|
PYGMENTS, HLFMT_HTML, HLFMT_ANSI, HLFMT_BBCODE, pys_highlight, PygmentsPyScriptStyle, PygmentsPyScriptLexer
|
|
10
10
|
)
|
|
11
11
|
from .core.runner import _namespace_to_symbol_table, pys_runner, pys_shell
|
|
12
|
-
from .core.utils.debug import USE_NOTEBOOK
|
|
12
|
+
from .core.utils.debug import USE_NOTEBOOK, custom_print
|
|
13
13
|
from .core.utils.generic import is_environ
|
|
14
14
|
from .core.utils.module import find_module_path, remove_python_path
|
|
15
15
|
from .core.utils.path import getcwd, base, normpath
|
|
16
|
+
from .core.utils.string import join
|
|
16
17
|
from .core.version import __version__
|
|
17
18
|
|
|
18
19
|
if PYGMENTS:
|
|
@@ -41,7 +42,7 @@ if sys.version_info >= (3, 13):
|
|
|
41
42
|
from _colorize import can_colorize
|
|
42
43
|
COLORIZE = can_colorize()
|
|
43
44
|
except:
|
|
44
|
-
#
|
|
45
|
+
# rule NO_COLOR, see more here: https://no-color.org
|
|
45
46
|
COLORIZE = not is_environ('NO_COLOR')
|
|
46
47
|
else:
|
|
47
48
|
COLORIZE = True
|
|
@@ -354,10 +355,11 @@ def execute(file: PysFileBuffer) -> None:
|
|
|
354
355
|
code, _ = result.end_process()
|
|
355
356
|
|
|
356
357
|
if inspect:
|
|
357
|
-
if sys.
|
|
358
|
+
if sys.stderr.closed:
|
|
358
359
|
code = 1
|
|
359
|
-
elif sys.stdin.closed:
|
|
360
|
-
|
|
360
|
+
elif sys.stdout.closed or sys.stdin.closed:
|
|
361
|
+
io_closed = join([f'sys.{std}' for std in ('stdout', 'stdin') if getattr(sys, std).closed])
|
|
362
|
+
custom_print(f"Cannot run interactive shell: {io_closed} closed", file=sys.stderr)
|
|
361
363
|
code = 1
|
|
362
364
|
else:
|
|
363
365
|
code = pys_shell(
|
|
@@ -382,14 +384,14 @@ if args.file is not None:
|
|
|
382
384
|
elif args.highlight:
|
|
383
385
|
try:
|
|
384
386
|
if args.highlight in FORMATER_HIGHLIGHT_MAP:
|
|
385
|
-
|
|
387
|
+
custom_print(
|
|
386
388
|
pys_highlight(
|
|
387
389
|
source=file,
|
|
388
390
|
formatter=FORMATER_HIGHLIGHT_MAP[args.highlight]
|
|
389
391
|
)
|
|
390
392
|
)
|
|
391
393
|
else:
|
|
392
|
-
|
|
394
|
+
custom_print(
|
|
393
395
|
highlight(
|
|
394
396
|
code=file.text,
|
|
395
397
|
lexer=PygmentsPyScriptLexer(),
|
pyscript/core/editor/gui.py
CHANGED
|
@@ -151,11 +151,18 @@ try:
|
|
|
151
151
|
else:
|
|
152
152
|
font_name = 'monospace'
|
|
153
153
|
|
|
154
|
-
self.lexer = PygmentsPyScriptLexer()
|
|
155
|
-
self.font = Font(family=font_name, size=boundary(self.get_configuration('gui-size-font', 10), 1, 127))
|
|
156
154
|
self.line_job = None
|
|
155
|
+
self.font = Font(
|
|
156
|
+
family=font_name,
|
|
157
|
+
size=boundary(self.get_configuration('gui-size-font', 10), 1, 127)
|
|
158
|
+
)
|
|
157
159
|
self.scrollbar = Scrollbar(self)
|
|
158
|
-
self.line_numbers = Canvas(
|
|
160
|
+
self.line_numbers = Canvas(
|
|
161
|
+
self,
|
|
162
|
+
width=0,
|
|
163
|
+
highlightthickness=0,
|
|
164
|
+
bd=0
|
|
165
|
+
)
|
|
159
166
|
self.text = Text(
|
|
160
167
|
self,
|
|
161
168
|
undo=True,
|
|
@@ -217,7 +224,8 @@ try:
|
|
|
217
224
|
self.wm_protocol('WM_DELETE_WINDOW', on_close)
|
|
218
225
|
|
|
219
226
|
if PYGMENTS and colored:
|
|
220
|
-
self.
|
|
227
|
+
self.lexer = PygmentsPyScriptLexer()
|
|
228
|
+
self.refresh_job = None
|
|
221
229
|
|
|
222
230
|
tag_configure = self.text.tag_configure
|
|
223
231
|
for token, style in PygmentsPyScriptStyle.list_styles():
|
|
@@ -226,7 +234,7 @@ try:
|
|
|
226
234
|
tag_configure(str(token), foreground=f'#{color}')
|
|
227
235
|
|
|
228
236
|
def refresh_highlight():
|
|
229
|
-
self.
|
|
237
|
+
self.refresh_job = None
|
|
230
238
|
|
|
231
239
|
index = '1.0'
|
|
232
240
|
|
|
@@ -248,9 +256,9 @@ try:
|
|
|
248
256
|
|
|
249
257
|
def update():
|
|
250
258
|
self.title(f'PyScript {__version__} - {self.basename}{"*" if self.modified else ""}')
|
|
251
|
-
if self.
|
|
252
|
-
self.after_cancel(self.
|
|
253
|
-
self.
|
|
259
|
+
if self.refresh_job is not None:
|
|
260
|
+
self.after_cancel(self.refresh_job)
|
|
261
|
+
self.refresh_job = self.after(1000, refresh_highlight)
|
|
254
262
|
|
|
255
263
|
else:
|
|
256
264
|
def update():
|
pyscript/core/highlight.py
CHANGED
|
@@ -114,7 +114,6 @@ try:
|
|
|
114
114
|
Comment.Single: HIGHLIGHT_MAP['comment'],
|
|
115
115
|
Error: HIGHLIGHT_MAP['invalid'],
|
|
116
116
|
Generic.Prompt: HIGHLIGHT_MAP['keyword-other'],
|
|
117
|
-
|
|
118
117
|
Punctuation.Brackets0: HIGHLIGHT_MAP['brackets-0'],
|
|
119
118
|
Punctuation.Brackets1: HIGHLIGHT_MAP['brackets-1'],
|
|
120
119
|
Punctuation.Brackets2: HIGHLIGHT_MAP['brackets-2']
|
pyscript/core/interpreter.py
CHANGED
|
@@ -582,11 +582,8 @@ def visit_SwitchNode(node: PysSwitchNode, context: PysContext) -> PysRunTimeResu
|
|
|
582
582
|
|
|
583
583
|
if (fall_through or no_match_found) and (ndefault := node.default):
|
|
584
584
|
register(get_visitor(ndefault.__class__)(ndefault, context))
|
|
585
|
-
if should_return():
|
|
586
|
-
|
|
587
|
-
result.should_break = False
|
|
588
|
-
else:
|
|
589
|
-
return result
|
|
585
|
+
if should_return() and not result.should_break:
|
|
586
|
+
return result
|
|
590
587
|
|
|
591
588
|
return result.success(None)
|
|
592
589
|
|
|
@@ -902,10 +899,7 @@ def visit_ForNode(node: PysForNode, context: PysContext) -> PysRunTimeResult:
|
|
|
902
899
|
if should_return():
|
|
903
900
|
return result
|
|
904
901
|
|
|
905
|
-
if result.should_break:
|
|
906
|
-
result.should_break = False
|
|
907
|
-
|
|
908
|
-
elif nelse := node.else_:
|
|
902
|
+
if not result.should_break and (nelse := node.else_):
|
|
909
903
|
register(get_visitor(nelse.__class__)(nelse, context))
|
|
910
904
|
if should_return():
|
|
911
905
|
return result
|
|
@@ -945,10 +939,7 @@ def visit_WhileNode(node: PysWhileNode, context: PysContext) -> PysRunTimeResult
|
|
|
945
939
|
else:
|
|
946
940
|
return result
|
|
947
941
|
|
|
948
|
-
if result.should_break:
|
|
949
|
-
result.should_break = False
|
|
950
|
-
|
|
951
|
-
elif nelse := node.else_:
|
|
942
|
+
if not result.should_break and (nelse := node.else_):
|
|
952
943
|
register(get_visitor(nelse.__class__)(nelse, context))
|
|
953
944
|
if should_return():
|
|
954
945
|
return result
|
|
@@ -988,10 +979,7 @@ def visit_DoWhileNode(node: PysDoWhileNode, context: PysContext) -> PysRunTimeRe
|
|
|
988
979
|
if should_return():
|
|
989
980
|
return result
|
|
990
981
|
|
|
991
|
-
if result.should_break:
|
|
992
|
-
result.should_break = False
|
|
993
|
-
|
|
994
|
-
elif nelse := node.else_:
|
|
982
|
+
if not result.should_break and (nelse := node.else_):
|
|
995
983
|
register(get_visitor(nelse.__class__)(nelse, context))
|
|
996
984
|
if should_return():
|
|
997
985
|
return result
|
|
@@ -1033,10 +1021,7 @@ def visit_RepeatNode(node: PysRepeatNode, context: PysContext) -> PysRunTimeResu
|
|
|
1033
1021
|
if should_return():
|
|
1034
1022
|
return result
|
|
1035
1023
|
|
|
1036
|
-
if result.should_break:
|
|
1037
|
-
result.should_break = False
|
|
1038
|
-
|
|
1039
|
-
elif nelse := node.else_:
|
|
1024
|
+
if not result.should_break and (nelse := node.else_):
|
|
1040
1025
|
register(get_visitor(nelse.__class__)(nelse, context))
|
|
1041
1026
|
if should_return():
|
|
1042
1027
|
return result
|
pyscript/core/mapping.py
CHANGED
|
@@ -9,16 +9,18 @@ from operator import (
|
|
|
9
9
|
neg, inv
|
|
10
10
|
)
|
|
11
11
|
|
|
12
|
-
contains
|
|
13
|
-
not_contains
|
|
14
|
-
and_op
|
|
15
|
-
or_op
|
|
16
|
-
|
|
12
|
+
contains = lambda a, b : a in b
|
|
13
|
+
not_contains = lambda a, b : a not in b
|
|
14
|
+
and_op = lambda a, b : a and b
|
|
15
|
+
or_op = lambda a, b : a or b
|
|
16
|
+
not_isinstance = lambda a, b : not isinstance(a, b)
|
|
17
|
+
typeof = lambda a : type(a).__name__
|
|
17
18
|
|
|
18
19
|
GET_BINARY_FUNCTION = {
|
|
19
20
|
TOKENS['IS']: is_,
|
|
20
21
|
TOKENS['IS_NOT']: is_not,
|
|
21
22
|
TOKENS['INSTANCEOF']: isinstance,
|
|
23
|
+
TOKENS['NOT_INSTANCEOF']: not_isinstance,
|
|
22
24
|
TOKENS['PERCENT']: mod,
|
|
23
25
|
TOKENS['AMPERSAND']: and_,
|
|
24
26
|
TOKENS['STAR']: mul,
|
|
@@ -150,6 +152,7 @@ SYMBOLS_TOKEN_MAP = dfrozen({
|
|
|
150
152
|
TOKENS['IS_NOT']: 'is not',
|
|
151
153
|
TOKENS['TYPEOF']: 'typeof',
|
|
152
154
|
TOKENS['INSTANCEOF']: 'instanceof',
|
|
155
|
+
TOKENS['NOT_INSTANCEOF']: 'not instanceof',
|
|
153
156
|
TOKENS['NEWLINE']: '\n',
|
|
154
157
|
TOKENS['EXCLAMATION']: '!',
|
|
155
158
|
TOKENS['COMMENT']: '#',
|
pyscript/core/nodes.py
CHANGED
|
@@ -398,8 +398,8 @@ class PysStatementsNode(PysNode):
|
|
|
398
398
|
return elements[0]
|
|
399
399
|
|
|
400
400
|
new = []
|
|
401
|
-
constant_nodes =
|
|
402
|
-
interrupt_nodes =
|
|
401
|
+
constant_nodes = {PysConstantNode, PysDebugNode, PysEllipsisNode}
|
|
402
|
+
interrupt_nodes = {PysReturnNode, PysThrowNode, PysContinueNode, PysBreakNode}
|
|
403
403
|
|
|
404
404
|
for node in elements:
|
|
405
405
|
if node.__class__ in constant_nodes:
|
|
@@ -478,9 +478,9 @@ class PysIfNode(PysNode):
|
|
|
478
478
|
if not new_cases:
|
|
479
479
|
return else_ if else_ else PysStatementsNode(position, [])
|
|
480
480
|
|
|
481
|
-
elif len(new_cases) == 1:
|
|
481
|
+
elif not else_ and len(new_cases) == 1:
|
|
482
482
|
condition, body = new_cases[0]
|
|
483
|
-
if body.__class__ is PysIfNode and len(body.cases) == 1 and body.else_:
|
|
483
|
+
if body.__class__ is PysIfNode and len(body.cases) == 1 and not body.else_:
|
|
484
484
|
inner_condition, inner_body = body.cases[0]
|
|
485
485
|
new_cases = [(
|
|
486
486
|
PysBinaryOperatorNode(
|
|
@@ -747,8 +747,17 @@ class PysGlobalNode(PysNode):
|
|
|
747
747
|
|
|
748
748
|
@typecheck
|
|
749
749
|
def __new__(cls, position: PysPosition, identifiers: list[PysToken]) -> 'PysGlobalNode':
|
|
750
|
+
registered = set()
|
|
751
|
+
new = []
|
|
752
|
+
|
|
753
|
+
for identifier in identifiers:
|
|
754
|
+
if identifier.value in registered:
|
|
755
|
+
continue
|
|
756
|
+
registered.add(identifier.value)
|
|
757
|
+
new.append(identifier)
|
|
758
|
+
|
|
750
759
|
self = super().__new__(cls, position)
|
|
751
|
-
setimuattr(self, 'identifiers', tuple(
|
|
760
|
+
setimuattr(self, 'identifiers', tuple(new))
|
|
752
761
|
return self
|
|
753
762
|
|
|
754
763
|
def __repr__(self) -> str:
|
pyscript/core/parser.py
CHANGED
|
@@ -401,7 +401,22 @@ class PysParser(Pys):
|
|
|
401
401
|
)
|
|
402
402
|
|
|
403
403
|
def instanceof(self) -> PysParserResult:
|
|
404
|
-
|
|
404
|
+
result = PysParserResult()
|
|
405
|
+
|
|
406
|
+
node = result.try_register(self.binary_operator(
|
|
407
|
+
self.bitwise,
|
|
408
|
+
(TOKENS['KEYWORD'], 'instanceof'),
|
|
409
|
+
(TOKENS['KEYWORD'], 'not'),
|
|
410
|
+
instanceof=True
|
|
411
|
+
))
|
|
412
|
+
|
|
413
|
+
if result.error:
|
|
414
|
+
return result
|
|
415
|
+
elif node:
|
|
416
|
+
return result.success(node)
|
|
417
|
+
|
|
418
|
+
self.reverse(result.to_reverse_count)
|
|
419
|
+
return self.bitwise()
|
|
405
420
|
|
|
406
421
|
def bitwise(self) -> PysParserResult:
|
|
407
422
|
return self.binary_operator(
|
|
@@ -2325,15 +2340,12 @@ class PysParser(Pys):
|
|
|
2325
2340
|
if result.error:
|
|
2326
2341
|
return result
|
|
2327
2342
|
|
|
2328
|
-
if body.__class__
|
|
2329
|
-
setimuattr(
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
end
|
|
2335
|
-
)
|
|
2336
|
-
)
|
|
2343
|
+
if body.__class__ is PysStatementsNode:
|
|
2344
|
+
setimuattr(body, 'position', PysPosition(
|
|
2345
|
+
self.current_token.position.file,
|
|
2346
|
+
left_bracket_token.position.start,
|
|
2347
|
+
end
|
|
2348
|
+
))
|
|
2337
2349
|
|
|
2338
2350
|
return result.success(body)
|
|
2339
2351
|
|
|
@@ -2350,10 +2362,7 @@ class PysParser(Pys):
|
|
|
2350
2362
|
|
|
2351
2363
|
body = result.register(self.statement())
|
|
2352
2364
|
if result.error:
|
|
2353
|
-
return result.failure(
|
|
2354
|
-
self.new_error("expected statement, expression, '{', or ';'"),
|
|
2355
|
-
fatal=False
|
|
2356
|
-
)
|
|
2365
|
+
return result.failure(self.new_error("expected statement, expression, '{', or ';'"), fatal=False)
|
|
2357
2366
|
|
|
2358
2367
|
return result.success(body)
|
|
2359
2368
|
|
|
@@ -2393,7 +2402,7 @@ class PysParser(Pys):
|
|
|
2393
2402
|
self.skip_expression(result)
|
|
2394
2403
|
|
|
2395
2404
|
if not self.current_token.match(TOKENS['KEYWORD'], 'in'):
|
|
2396
|
-
return result.failure(self.new_error("expected 'in'"))
|
|
2405
|
+
return result.failure(self.new_error("expected 'in' or 'instanceof'"))
|
|
2397
2406
|
|
|
2398
2407
|
operations[-1] = PysToken(
|
|
2399
2408
|
TOKENS['EXCLAMATION_GREATER_THAN'],
|
|
@@ -2483,11 +2492,28 @@ class PysParser(Pys):
|
|
|
2483
2492
|
TOKENS['DOUBLE_AMPERSAND' if token.value == 'and' else 'DOUBLE_PIPE'],
|
|
2484
2493
|
token.position
|
|
2485
2494
|
)
|
|
2495
|
+
|
|
2486
2496
|
elif instanceof:
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2497
|
+
|
|
2498
|
+
if token.match(TOKENS['KEYWORD'], 'not'):
|
|
2499
|
+
result.register_advancement()
|
|
2500
|
+
self.advance()
|
|
2501
|
+
self.skip_expression(result)
|
|
2502
|
+
|
|
2503
|
+
if not self.current_token.match(TOKENS['KEYWORD'], 'instanceof'):
|
|
2504
|
+
return result.failure(self.new_error("expected 'instanceof'"), fatal=False)
|
|
2505
|
+
|
|
2506
|
+
operand = PysToken(
|
|
2507
|
+
TOKENS['NOT_INSTANCEOF'],
|
|
2508
|
+
token.position
|
|
2509
|
+
)
|
|
2510
|
+
|
|
2511
|
+
else:
|
|
2512
|
+
operand = PysToken(
|
|
2513
|
+
TOKENS['INSTANCEOF'],
|
|
2514
|
+
token.position
|
|
2515
|
+
)
|
|
2516
|
+
|
|
2491
2517
|
else:
|
|
2492
2518
|
operand = token
|
|
2493
2519
|
|
pyscript/core/pysbuiltins.py
CHANGED
|
@@ -37,6 +37,7 @@ static_wrapper_function = (staticmethod,)
|
|
|
37
37
|
wrapper_function = (MethodType, PysPythonFunction, classmethod)
|
|
38
38
|
python_function = (BuiltinFunctionType, BuiltinMethodType, FunctionType)
|
|
39
39
|
|
|
40
|
+
pynewobject = object.__new__
|
|
40
41
|
pyvars = builtins.vars
|
|
41
42
|
pydir = builtins.dir
|
|
42
43
|
|
|
@@ -55,34 +56,36 @@ def _magic_method(
|
|
|
55
56
|
return NotImplemented
|
|
56
57
|
|
|
57
58
|
def _unpack_comprehension_function(context: PysContext, position: PysPosition, function: Callable) -> Callable:
|
|
58
|
-
check = function
|
|
59
|
-
|
|
60
|
-
offset = 0
|
|
59
|
+
check = final = function
|
|
60
|
+
length = offset = 0
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
b_isinstance = isinstance
|
|
63
|
+
|
|
64
|
+
if b_isinstance(function, wrapper_function):
|
|
63
65
|
check = function.__func__
|
|
64
|
-
offset += 2 if
|
|
65
|
-
elif
|
|
66
|
+
offset += 2 if b_isinstance(function, PysPythonFunction) else 1
|
|
67
|
+
elif b_isinstance(function, static_wrapper_function):
|
|
66
68
|
check = function.__func__
|
|
69
|
+
elif b_isinstance(function, type):
|
|
70
|
+
offset += 1
|
|
71
|
+
check = function.__new__
|
|
72
|
+
if check is pynewobject:
|
|
73
|
+
check = function.__init__
|
|
67
74
|
|
|
68
|
-
if
|
|
75
|
+
if b_isinstance(check, PysFunction):
|
|
69
76
|
length = max(check.__code__.parameters_length - offset, 0)
|
|
70
|
-
|
|
71
|
-
def final(item):
|
|
72
|
-
return function()
|
|
73
|
-
elif length > 1:
|
|
74
|
-
def final(item):
|
|
75
|
-
return function(*item)
|
|
76
|
-
|
|
77
|
-
elif isinstance(check, python_function):
|
|
77
|
+
elif b_isinstance(check, python_function):
|
|
78
78
|
parameters = signature(check).parameters
|
|
79
79
|
length = max(len(parameters) - offset, 0)
|
|
80
|
-
if length ==
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
80
|
+
if length == 1 and any(p.kind == p.VAR_POSITIONAL for p in parameters.values()):
|
|
81
|
+
length = 2
|
|
82
|
+
|
|
83
|
+
if length == 0:
|
|
84
|
+
def final(item):
|
|
85
|
+
return function()
|
|
86
|
+
elif length > 1:
|
|
87
|
+
def final(item):
|
|
88
|
+
return function(*item)
|
|
86
89
|
|
|
87
90
|
handle_call(function, context, position)
|
|
88
91
|
return final
|
|
@@ -116,8 +119,7 @@ def require(context, position, name):
|
|
|
116
119
|
name: A name or path of the module to be imported.
|
|
117
120
|
"""
|
|
118
121
|
|
|
119
|
-
name, *
|
|
120
|
-
|
|
122
|
+
name, *components = normstr(name).split('>')
|
|
121
123
|
filename = context.file.name
|
|
122
124
|
path, module_path = find_module_path(filename, name)
|
|
123
125
|
|
|
@@ -189,9 +191,8 @@ def require(context, position, name):
|
|
|
189
191
|
finally:
|
|
190
192
|
loading_modules.discard(module_path)
|
|
191
193
|
|
|
192
|
-
for component in
|
|
194
|
+
for component in components:
|
|
193
195
|
module = getattr(module, component)
|
|
194
|
-
|
|
195
196
|
return module
|
|
196
197
|
|
|
197
198
|
@PysBuiltinFunction
|
|
@@ -386,7 +387,7 @@ def dir(context, position, *args):
|
|
|
386
387
|
def exec(context, position, source, globals=None):
|
|
387
388
|
|
|
388
389
|
"""
|
|
389
|
-
exec(source: str | bytes, globals: Optional[dict]) -> None
|
|
390
|
+
exec(source: str | bytes | bytearray | Iterable | IOBase, globals: Optional[dict] = None) -> None
|
|
390
391
|
|
|
391
392
|
Executes PyScript code statements from the given source.
|
|
392
393
|
|
|
@@ -416,7 +417,7 @@ def exec(context, position, source, globals=None):
|
|
|
416
417
|
def eval(context, position, source, globals=None):
|
|
417
418
|
|
|
418
419
|
"""
|
|
419
|
-
eval(source: str | bytes, globals: Optional[dict]) -> None
|
|
420
|
+
eval(source: str | bytes | bytearray | Iterable | IOBase, globals: Optional[dict] = None) -> None
|
|
420
421
|
|
|
421
422
|
Executes a PyScript code expression from the given source.
|
|
422
423
|
|
pyscript/core/pystypes.py
CHANGED
|
@@ -203,7 +203,7 @@ class PysFunction(PysObject):
|
|
|
203
203
|
PysTraceback(
|
|
204
204
|
TypeError(
|
|
205
205
|
f"{self.__qualname__}() missing {total_missing} required positional argument"
|
|
206
|
-
f"{'' if total_missing == 1 else 's'}: {join(missing_arguments
|
|
206
|
+
f"{'' if total_missing == 1 else 's'}: {join(missing_arguments)}"
|
|
207
207
|
),
|
|
208
208
|
context,
|
|
209
209
|
position
|
pyscript/core/runner.py
CHANGED
|
@@ -153,13 +153,14 @@ def pys_runner(
|
|
|
153
153
|
pys_sys.flags = context.flags
|
|
154
154
|
|
|
155
155
|
try:
|
|
156
|
-
del
|
|
157
|
-
lexer, tokens, error, parser,
|
|
156
|
+
del (
|
|
157
|
+
file, flags, symbol_table, context_parent, context_parent_entry_position, lexer, tokens, error, parser,
|
|
158
|
+
analyzer
|
|
159
|
+
)
|
|
158
160
|
except:
|
|
159
161
|
pass
|
|
160
162
|
|
|
161
163
|
visitor_result = get_visitor(node.__class__)(node, context)
|
|
162
|
-
|
|
163
164
|
if visitor_result.error:
|
|
164
165
|
return result.failure(visitor_result.error)
|
|
165
166
|
|
pyscript/core/token.py
CHANGED
pyscript/core/utils/debug.py
CHANGED
|
@@ -40,13 +40,13 @@ def import_readline() -> Literal[False]:
|
|
|
40
40
|
USE_NOTEBOOK = False
|
|
41
41
|
|
|
42
42
|
try:
|
|
43
|
-
from IPython import get_ipython
|
|
43
|
+
from IPython import get_ipython # type: ignore
|
|
44
44
|
if type(get_ipython()).__name__ in (
|
|
45
45
|
'ZMQInteractiveShell', # Jupyter Notebook / Lab
|
|
46
46
|
'Shell', # Google Colab
|
|
47
47
|
'TerminalInteractiveShell' # IPython Terminal
|
|
48
48
|
):
|
|
49
|
-
from IPython.display import clear_output
|
|
49
|
+
from IPython.display import clear_output # type: ignore
|
|
50
50
|
def clear_shell() -> None:
|
|
51
51
|
clear_output()
|
|
52
52
|
USE_NOTEBOOK = True
|
|
@@ -34,10 +34,11 @@ def typecheck(func, *args, **kwargs):
|
|
|
34
34
|
if not is_environ(ENV_PYSCRIPT_NO_TYPECHECK):
|
|
35
35
|
try:
|
|
36
36
|
from beartype import beartype as typecheck
|
|
37
|
-
TYPECHECK_STACK += 1
|
|
38
|
-
BEARTYPE = True
|
|
39
37
|
except:
|
|
40
38
|
pass
|
|
39
|
+
else:
|
|
40
|
+
TYPECHECK_STACK += 1
|
|
41
|
+
BEARTYPE = True
|
|
41
42
|
|
|
42
43
|
def immutable(cls):
|
|
43
44
|
cls.__setattr__ = _PysUtilities.readonly_attribute
|
pyscript/core/utils/generic.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from inspect import currentframe
|
|
2
|
-
from types import FrameType,
|
|
2
|
+
from types import FrameType, UnionType
|
|
3
3
|
from typing import Any, Optional, Sequence
|
|
4
4
|
|
|
5
5
|
import os
|
|
@@ -21,10 +21,11 @@ dclear = dict.clear
|
|
|
21
21
|
dget = dict.get
|
|
22
22
|
dkeys = dict.keys
|
|
23
23
|
ditems = dict.items
|
|
24
|
-
dfrozen = MappingProxyType
|
|
25
24
|
|
|
26
25
|
if sys.version_info >= (3, 15):
|
|
27
26
|
dfrozen = frozendict
|
|
27
|
+
else:
|
|
28
|
+
from types import MappingProxyType as dfrozen
|
|
28
29
|
|
|
29
30
|
def get_frame(deep: int = 0) -> FrameType | None:
|
|
30
31
|
deep += 1
|
pyscript/core/utils/module.py
CHANGED
|
@@ -22,6 +22,9 @@ def get_module_candidate(path: str, entry: str = '__init__') -> str | None:
|
|
|
22
22
|
return candidate
|
|
23
23
|
|
|
24
24
|
def find_module_path(filename: str | None, name: str, entry: str = '__init__') -> tuple[str | None, str | None]:
|
|
25
|
+
if name in ('_pyscript', 'builtins', 'sys'):
|
|
26
|
+
return None, None
|
|
27
|
+
|
|
25
28
|
# circular import problem solved
|
|
26
29
|
from ..cache import pys_sys
|
|
27
30
|
|
pyscript/core/utils/string.py
CHANGED
|
@@ -38,7 +38,9 @@ def normstr(obj) -> str:
|
|
|
38
38
|
|
|
39
39
|
def join(sequence: Sequence[str], conjunction: str = 'and') -> str:
|
|
40
40
|
length = len(sequence)
|
|
41
|
-
if length ==
|
|
41
|
+
if length == 0:
|
|
42
|
+
return ''
|
|
43
|
+
elif length == 1:
|
|
42
44
|
return sequence[0]
|
|
43
45
|
elif length == 2:
|
|
44
46
|
return f'{sequence[0]} {conjunction} {sequence[1]}'
|
pyscript/core/version.py
CHANGED
|
@@ -4,9 +4,11 @@ from .mapping import TAG_VERSION_MAP
|
|
|
4
4
|
from .utils.decorators import immutable, inheritable, singleton
|
|
5
5
|
|
|
6
6
|
from re import match as match_regex
|
|
7
|
+
from types import NotImplementedType
|
|
8
|
+
from typing import Any
|
|
7
9
|
|
|
8
|
-
__version__ = '1.15.
|
|
9
|
-
__date__ = '
|
|
10
|
+
__version__ = '1.15.1'
|
|
11
|
+
__date__ = '30 October 2026, 19:40 UTC+7'
|
|
10
12
|
__author__ = ('AzzamMuhyala',)
|
|
11
13
|
|
|
12
14
|
version = pys_sys.version = f'{__version__} ({__date__})'
|
|
@@ -72,6 +74,15 @@ class PysVersionInfo(Pys, tuple):
|
|
|
72
74
|
def release(self) -> tuple[int, int, int]:
|
|
73
75
|
return self[0:3]
|
|
74
76
|
|
|
77
|
+
def __add__(self, other: Any) -> NotImplementedType:
|
|
78
|
+
return NotImplemented
|
|
79
|
+
|
|
80
|
+
def __mul__(self, other: Any) -> NotImplementedType:
|
|
81
|
+
return NotImplemented
|
|
82
|
+
|
|
83
|
+
def __rmul__(self, other: Any) -> NotImplementedType:
|
|
84
|
+
return NotImplemented
|
|
85
|
+
|
|
75
86
|
def __lt__(self, other: tuple) -> bool:
|
|
76
87
|
return self.release < other
|
|
77
88
|
|
pyscript/lib/brainfuck.pys
CHANGED
|
@@ -30,7 +30,7 @@ class BFInterpreter {
|
|
|
30
30
|
fin = fin ?? default_input
|
|
31
31
|
fout = fout ?? default_output
|
|
32
32
|
|
|
33
|
-
if (
|
|
33
|
+
if (cells not instanceof (int, type(none)))
|
|
34
34
|
throw TypeError("BFInterpreter() cells must be integer or none")
|
|
35
35
|
if (!callable(fin))
|
|
36
36
|
throw TypeError("BFInterpreter() fin must be callable")
|
|
@@ -94,8 +94,7 @@ class BFInterpreter {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
func __next__(self) {
|
|
97
|
-
result
|
|
98
|
-
if (result is none) {
|
|
97
|
+
if ((result := self.step()) is none) {
|
|
99
98
|
self.stop()
|
|
100
99
|
throw StopIteration
|
|
101
100
|
}
|
|
@@ -111,7 +110,6 @@ class BFInterpreter {
|
|
|
111
110
|
|
|
112
111
|
if (pointer >= (length := len(memory)))
|
|
113
112
|
memory.extend([0] * (pointer - length + 1))
|
|
114
|
-
|
|
115
113
|
else {
|
|
116
114
|
removeIndex = 0
|
|
117
115
|
for (i, cell of enumerate(reversed(memory))) {
|
|
@@ -142,13 +140,9 @@ class BFInterpreter {
|
|
|
142
140
|
return
|
|
143
141
|
|
|
144
142
|
self._tokenCursor += amount
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (tokenCursor >= len(tokens := self._tokens) || tokenCursor < 0)
|
|
143
|
+
if (!(0 <= self._tokenCursor < len(self._tokens)))
|
|
148
144
|
return
|
|
149
|
-
|
|
150
|
-
position, character = tokens[tokenCursor]
|
|
151
|
-
cell = (memory := self.memory)[pointer := self.pointer]
|
|
145
|
+
position, character = self._tokens[self._tokenCursor]
|
|
152
146
|
|
|
153
147
|
switch (character) {
|
|
154
148
|
|
|
@@ -160,39 +154,39 @@ class BFInterpreter {
|
|
|
160
154
|
break
|
|
161
155
|
|
|
162
156
|
case '<':
|
|
163
|
-
if (pointer == 0)
|
|
164
|
-
self.pointer = len(memory)
|
|
157
|
+
if (self.pointer == 0)
|
|
158
|
+
self.pointer = len(self.memory)
|
|
165
159
|
self.pointer -= 1
|
|
166
160
|
self._garbageCollection()
|
|
167
161
|
break
|
|
168
162
|
|
|
169
163
|
case '+':
|
|
170
|
-
memory[pointer] = (
|
|
164
|
+
self.memory[self.pointer] = (self.memory[self.pointer] + 1) % 256
|
|
171
165
|
break
|
|
172
166
|
|
|
173
167
|
case '-':
|
|
174
|
-
memory[pointer] = (
|
|
168
|
+
self.memory[self.pointer] = (self.memory[self.pointer] - 1) % 256
|
|
175
169
|
break
|
|
176
170
|
|
|
177
171
|
case ',':
|
|
178
172
|
new = self.fin()
|
|
179
173
|
if (!(new instanceof int && 0 <= new <= 255))
|
|
180
174
|
throw TypeError("BFInterpreter() fin must be returns unsigned 8-bit integer")
|
|
181
|
-
memory[pointer] = new
|
|
175
|
+
self.memory[self.pointer] = new
|
|
182
176
|
break
|
|
183
177
|
|
|
184
178
|
case '.':
|
|
185
|
-
self.fout(
|
|
179
|
+
self.fout(self.memory[self.pointer])
|
|
186
180
|
break
|
|
187
181
|
|
|
188
182
|
case '[':
|
|
189
|
-
if (
|
|
190
|
-
self._tokenCursor = self._bracketMap[
|
|
183
|
+
if (self.memory[self.pointer] == 0)
|
|
184
|
+
self._tokenCursor = self._bracketMap[self._tokenCursor]
|
|
191
185
|
break
|
|
192
186
|
|
|
193
187
|
case ']':
|
|
194
|
-
if (
|
|
195
|
-
self._tokenCursor = self._bracketMap[
|
|
188
|
+
if (self.memory[self.pointer] != 0)
|
|
189
|
+
self._tokenCursor = self._bracketMap[self._tokenCursor]
|
|
196
190
|
break
|
|
197
191
|
|
|
198
192
|
}
|
|
@@ -203,11 +197,11 @@ class BFInterpreter {
|
|
|
203
197
|
func stop(self, cleanUp=true) {
|
|
204
198
|
if (!self.running)
|
|
205
199
|
return
|
|
206
|
-
|
|
207
200
|
self.running = false
|
|
208
|
-
|
|
209
201
|
if (cleanUp)
|
|
210
|
-
|
|
202
|
+
try
|
|
203
|
+
del self.memory, self.pointer, self._tokenCursor
|
|
204
|
+
except;
|
|
211
205
|
}
|
|
212
206
|
|
|
213
207
|
}
|
pyscript/lib/dual/__init__.pys
CHANGED
|
@@ -3,6 +3,10 @@ import py_dual
|
|
|
3
3
|
dual = py_dual.dual
|
|
4
4
|
eps = dual(0, 1)
|
|
5
5
|
|
|
6
|
+
func get_consthash() => py_dual.HASH_DUAL
|
|
7
|
+
func get_ln() => py_dual._ln
|
|
8
|
+
func get_epssym() => py_dual.EPSILON_SYMBOL
|
|
9
|
+
|
|
6
10
|
func set_ln(fn)
|
|
7
11
|
py_dual._ln = fn
|
|
8
12
|
|
|
@@ -11,7 +15,5 @@ func set_epssym(value)
|
|
|
11
15
|
|
|
12
16
|
__all__ = (
|
|
13
17
|
'dual',
|
|
14
|
-
'eps'
|
|
15
|
-
'set_ln',
|
|
16
|
-
'set_epssym'
|
|
18
|
+
'eps'
|
|
17
19
|
)
|
pyscript/lib/dual/py_dual.py
CHANGED
|
@@ -3,17 +3,29 @@
|
|
|
3
3
|
|
|
4
4
|
from pyscript.core.pysbuiltins import ce, nce
|
|
5
5
|
from pyscript.core.utils.decorators import immutable
|
|
6
|
-
from pyscript.core.utils.generic import setimuattr
|
|
6
|
+
from pyscript.core.utils.generic import setimuattr, is_environ
|
|
7
7
|
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import Any, Optional, SupportsIndex
|
|
9
9
|
|
|
10
10
|
import cmath
|
|
11
|
+
import math
|
|
12
|
+
|
|
13
|
+
np = None
|
|
14
|
+
if not is_environ('DUAL_DONT_USE_NUMPY'):
|
|
15
|
+
try:
|
|
16
|
+
import numpy as np
|
|
17
|
+
except:
|
|
18
|
+
pass
|
|
11
19
|
|
|
12
20
|
EPSILON_SYMBOL = True
|
|
21
|
+
HASH_DUAL = 10**6 + 33
|
|
13
22
|
|
|
14
23
|
def _ln(x) -> float | complex:
|
|
15
24
|
result = cmath.log(x)
|
|
16
|
-
return result.real if
|
|
25
|
+
return result.real if result.imag == 0 else result
|
|
26
|
+
|
|
27
|
+
def _parts(x: 'Any | dual') -> tuple[Any, Any]:
|
|
28
|
+
return (x.real, x.epsilon) if isinstance(x, dual) else (x, 0)
|
|
17
29
|
|
|
18
30
|
@immutable
|
|
19
31
|
class dual:
|
|
@@ -31,39 +43,15 @@ class dual:
|
|
|
31
43
|
epsilon = 0
|
|
32
44
|
case _:
|
|
33
45
|
real, epsilon = args
|
|
46
|
+
a, b = _parts(real)
|
|
47
|
+
c, _ = _parts(epsilon)
|
|
48
|
+
real, epsilon = a, b + c
|
|
34
49
|
|
|
35
50
|
self = super().__new__(cls)
|
|
36
51
|
setimuattr(self, 'real', real)
|
|
37
52
|
setimuattr(self, 'epsilon', epsilon)
|
|
38
53
|
return self
|
|
39
54
|
|
|
40
|
-
def __repr__(self) -> str:
|
|
41
|
-
return f'{type(self).__name__}({self.real!r}, {self.epsilon!r})'
|
|
42
|
-
|
|
43
|
-
def __str__(self) -> str:
|
|
44
|
-
string = ''
|
|
45
|
-
parenthesis = False
|
|
46
|
-
inner_parenthesis = False
|
|
47
|
-
|
|
48
|
-
if self.real != 0:
|
|
49
|
-
parenthesis = True
|
|
50
|
-
try:
|
|
51
|
-
sign = '+' if self.epsilon >= 0 else '-'
|
|
52
|
-
except Exception:
|
|
53
|
-
inner_parenthesis = True
|
|
54
|
-
string += f'({self.real!r})+'
|
|
55
|
-
else:
|
|
56
|
-
string += repr(self.real)
|
|
57
|
-
string += sign
|
|
58
|
-
|
|
59
|
-
if inner_parenthesis:
|
|
60
|
-
string += f'({self.epsilon!r})'
|
|
61
|
-
elif self.epsilon != 1 and self.epsilon != -1:
|
|
62
|
-
string += repr(abs(self.epsilon))
|
|
63
|
-
|
|
64
|
-
string += '\u03b5' if EPSILON_SYMBOL else 'eps'
|
|
65
|
-
return f'({string})' if parenthesis else string
|
|
66
|
-
|
|
67
55
|
def __add__(self, other: 'dual | Any') -> 'dual':
|
|
68
56
|
return dual(
|
|
69
57
|
self.real + other.real,
|
|
@@ -164,15 +152,20 @@ class dual:
|
|
|
164
152
|
)
|
|
165
153
|
|
|
166
154
|
def __pow__(self, other: 'dual | Any') -> 'dual':
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
self.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
155
|
+
if isinstance(other, dual):
|
|
156
|
+
c, d = other.as_tuple()
|
|
157
|
+
if c == 0 and d == 0:
|
|
158
|
+
return dual(1, 0)
|
|
159
|
+
a, b = self.as_tuple()
|
|
160
|
+
real = a ** c
|
|
161
|
+
return dual(
|
|
162
|
+
real,
|
|
163
|
+
(0 if b == 0 or c == 0 else (b * c * a**(c - 1))) +
|
|
164
|
+
(0 if d == 0 else d * real * _ln(a))
|
|
165
|
+
)
|
|
166
|
+
return dual(1, 0) if other == 0 else dual(self.real**other, self.epsilon * other * self.real**(other - 1))
|
|
167
|
+
|
|
168
|
+
def __rpow__(self, other: 'dual | Any') -> 'dual':
|
|
176
169
|
return other**self if isinstance(other, dual) else dual(
|
|
177
170
|
real := other ** self.real,
|
|
178
171
|
self.epsilon * real * _ln(other)
|
|
@@ -189,10 +182,10 @@ class dual:
|
|
|
189
182
|
|
|
190
183
|
def __ne__(self, other: 'dual | Any') -> bool | Any:
|
|
191
184
|
return (
|
|
192
|
-
self.real != other.real
|
|
185
|
+
self.real != other.real or
|
|
193
186
|
self.epsilon != other.epsilon
|
|
194
187
|
) if isinstance(other, dual) else (
|
|
195
|
-
self.real != other
|
|
188
|
+
self.real != other or
|
|
196
189
|
self.epsilon != 0
|
|
197
190
|
)
|
|
198
191
|
|
|
@@ -207,13 +200,19 @@ class dual:
|
|
|
207
200
|
|
|
208
201
|
def __nce__(self, other: 'dual | Any', **kwargs) -> bool | Any:
|
|
209
202
|
return (
|
|
210
|
-
nce(self.real, other.real, **kwargs)
|
|
203
|
+
nce(self.real, other.real, **kwargs) or
|
|
211
204
|
nce(self.epsilon, other.epsilon, **kwargs)
|
|
212
205
|
) if isinstance(other, dual) else (
|
|
213
|
-
nce(self.real, other, **kwargs)
|
|
206
|
+
nce(self.real, other, **kwargs) or
|
|
214
207
|
nce(self.epsilon, 0, **kwargs)
|
|
215
208
|
)
|
|
216
209
|
|
|
210
|
+
def __hash__(self) -> int:
|
|
211
|
+
return hash(self.real) + hash(self.epsilon) * HASH_DUAL
|
|
212
|
+
|
|
213
|
+
def __reduce__(self) -> tuple[type['dual'], tuple[Any, Any]]:
|
|
214
|
+
return type(self), self.as_tuple()
|
|
215
|
+
|
|
217
216
|
def __neg__(self) -> 'dual':
|
|
218
217
|
return dual(-self.real, -self.epsilon)
|
|
219
218
|
|
|
@@ -221,7 +220,7 @@ class dual:
|
|
|
221
220
|
return dual(+self.real, +self.epsilon)
|
|
222
221
|
|
|
223
222
|
def __bool__(self) -> bool:
|
|
224
|
-
return bool(self.real != 0
|
|
223
|
+
return bool(self.real != 0 or self.epsilon != 0)
|
|
225
224
|
|
|
226
225
|
def __int__(self) -> int:
|
|
227
226
|
return int(self.real)
|
|
@@ -229,18 +228,64 @@ class dual:
|
|
|
229
228
|
def __float__(self) -> float:
|
|
230
229
|
return float(self.real)
|
|
231
230
|
|
|
232
|
-
def
|
|
233
|
-
return
|
|
231
|
+
def __floor__(self) -> 'dual':
|
|
232
|
+
return dual(math.floor(self.real), 0)
|
|
233
|
+
|
|
234
|
+
def __ceil__(self) -> 'dual':
|
|
235
|
+
return dual(math.ceil(self.real), 0)
|
|
236
|
+
|
|
237
|
+
def __trunc__(self) -> 'dual':
|
|
238
|
+
return dual(math.trunc(self.real), 0)
|
|
234
239
|
|
|
235
|
-
def __round__(self, ndigits=None) -> 'dual':
|
|
240
|
+
def __round__(self, ndigits: Optional[SupportsIndex] = None) -> 'dual':
|
|
236
241
|
return dual(round(self.real, ndigits), 0)
|
|
237
242
|
|
|
238
243
|
def __abs__(self) -> 'dual':
|
|
239
|
-
return dual(abs(self.real), 0)
|
|
244
|
+
return dual(abs(self.real), self.epsilon if self.real >= 0 else -self.epsilon)
|
|
245
|
+
|
|
246
|
+
def __repr__(self) -> str:
|
|
247
|
+
return f'{type(self).__name__}({self.real!r}, {self.epsilon!r})'
|
|
248
|
+
|
|
249
|
+
def __str__(self) -> str:
|
|
250
|
+
return format(self, '!r')
|
|
251
|
+
|
|
252
|
+
def __format__(self, format_spec: str = '') -> str:
|
|
253
|
+
is_repr = format_spec == '!r'
|
|
254
|
+
is_formated = not is_repr and format_spec != ''
|
|
255
|
+
|
|
256
|
+
string = ''
|
|
257
|
+
parenthesis = False
|
|
258
|
+
inner_parenthesis = False
|
|
259
|
+
|
|
260
|
+
if is_formated or self.real != 0:
|
|
261
|
+
parenthesis = True
|
|
262
|
+
real = repr(self.real) if is_repr else format(self.real, format_spec)
|
|
263
|
+
try:
|
|
264
|
+
sign = ' + ' if self.epsilon >= 0 else ' - '
|
|
265
|
+
except Exception:
|
|
266
|
+
inner_parenthesis = True
|
|
267
|
+
string += f'({real}) + '
|
|
268
|
+
else:
|
|
269
|
+
string += real + sign
|
|
270
|
+
|
|
271
|
+
if inner_parenthesis:
|
|
272
|
+
string += f'({repr(self.epsilon) if is_repr else format(self.epsilon, format_spec)})'
|
|
273
|
+
elif is_formated or self.epsilon not in (-1, 1):
|
|
274
|
+
string += repr(abs(self.epsilon)) if is_repr else format(abs(self.epsilon), format_spec)
|
|
275
|
+
|
|
276
|
+
string += '\u03b5' if EPSILON_SYMBOL else 'eps'
|
|
277
|
+
return f'({string})' if parenthesis else string
|
|
278
|
+
|
|
279
|
+
if np is not None:
|
|
280
|
+
def __array__(self, *args, **kwargs):
|
|
281
|
+
return np.array(self.as_lmatrix(), *args, **kwargs)
|
|
240
282
|
|
|
241
283
|
def as_tuple(self) -> tuple[Any, Any]:
|
|
242
284
|
return self.real, self.epsilon
|
|
243
285
|
|
|
286
|
+
def as_lmatrix(self, n: int = 2) -> list[list[Any]]:
|
|
287
|
+
return [[self.real if i == j else self.epsilon if (i, j) == (0, 1) else 0 for j in range(n)] for i in range(n)]
|
|
288
|
+
|
|
244
289
|
@classmethod
|
|
245
|
-
def from_number(cls, number) -> 'dual':
|
|
290
|
+
def from_number(cls, number: Any) -> 'dual':
|
|
246
291
|
return cls(0, number)
|
pyscript/lib/getch/py_getch.py
CHANGED
|
@@ -9,7 +9,7 @@ if sys.platform == 'win32':
|
|
|
9
9
|
OLD_INTERRUPT_HANDLER = None
|
|
10
10
|
INTERRUPT = False
|
|
11
11
|
|
|
12
|
-
def
|
|
12
|
+
def _getch_interrupt_handler(signum, frame):
|
|
13
13
|
global INTERRUPT
|
|
14
14
|
INTERRUPT = True
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@ if sys.platform == 'win32':
|
|
|
19
19
|
return
|
|
20
20
|
|
|
21
21
|
INITIALIZED = True
|
|
22
|
-
OLD_INTERRUPT_HANDLER = signal.signal(signal.SIGINT,
|
|
22
|
+
OLD_INTERRUPT_HANDLER = signal.signal(signal.SIGINT, _getch_interrupt_handler)
|
|
23
23
|
|
|
24
24
|
def quit() -> None:
|
|
25
25
|
global INITIALIZED, OLD_INTERRUPT_HANDLER
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
i love cartman's farts
|
|
2
|
+
you what?
|
|
3
|
+
yummy yummy yummy i want cartman's farts in my tummy
|
|
4
|
+
dude what the hell are you talking about?
|
|
5
|
+
yummy yummy yummy can i please have cartman's farts in my tummy!
|
|
6
|
+
ok ok jesus uh, lay down on your back kyle
|
|
7
|
+
[yummy yummy yummy yummy yummy yummy yummy yummy yummy yummy]
|
|
8
|
+
see what i can muster up here let's see
|
|
9
|
+
oh oh
|
|
10
|
+
[intense farts]
|
|
11
|
+
yummy yummy thank you cartman.
|
|
12
|
+
|
|
13
|
+
mr mackey is gay
|
|
14
|
+
[laughter]
|
|
15
|
+
m'kay kids that's not funny, m'kay..
|
|
16
|
+
this box is supposed to be used for serious questions,
|
|
17
|
+
about--about serious issues, m'kay,
|
|
18
|
+
let's stop the tomfoolery.
|
|
19
|
+
m'kay let's look at a real one here
|
|
20
|
+
dear mr mackey, you are gay
|
|
21
|
+
[laughter]
|
|
22
|
+
all right, all right that's enough kids!
|
|
23
|
+
let's quiet down and try to be mature m'kay!
|
|
24
|
+
here we go, m'kay
|
|
25
|
+
mr mackey, sometimes my parents hit me
|
|
26
|
+
and you are gay
|
|
27
|
+
[laughter]
|
|
28
|
+
damn it is there not one serious question in here?!
|
|
29
|
+
mr mackey is gay
|
|
30
|
+
mr mackey is gay
|
|
31
|
+
m'kay here
|
|
32
|
+
[clears throat]
|
|
33
|
+
i'am a boy at south park elementary
|
|
34
|
+
sometimes when i'am sitting in class
|
|
35
|
+
my penis becomes so hard for no reason
|
|
36
|
+
what should i do?
|
|
37
|
+
[looking around]
|
|
38
|
+
[laughter]
|
|
39
|
+
all right kids, all right kids that's enough!
|
|
40
|
+
[bell jingles]
|
|
41
|
+
if you all can't be serious about the question box
|
|
42
|
+
then we'll just do drug identification exercises m'kay!
|
|
43
|
+
[ahh..]
|
|
44
|
+
m'kay jimmy why don't you come up here and write down the name of two narcotics?
|
|
45
|
+
uh no, t-that's okay, mr mackey
|
|
46
|
+
jimmy i'm not asking you, i'm telling you
|
|
47
|
+
uh, just, uh, not right this second mr mackey
|
|
48
|
+
well why the hell no?!
|
|
49
|
+
uh..
|
|
50
|
+
[comming closely]
|
|
51
|
+
[whispering]
|
|
52
|
+
it's what?
|
|
53
|
+
oh you do?
|
|
54
|
+
r-right now right now it is?
|
|
55
|
+
m'kay, m'kay
|
|
56
|
+
dont worry jim!
|
|
57
|
+
m'kay, uh let's pick someone else uh
|
|
58
|
+
eric why don't you come up here?
|
|
59
|
+
hey that's bullcrap! how come jimmy doesn't have to do it?
|
|
60
|
+
well, because jimmy's pitching a tent right now
|
|
61
|
+
[shock]
|
|
62
|
+
he's what?
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyscript-programming-language
|
|
3
|
-
Version: 1.15.
|
|
3
|
+
Version: 1.15.1
|
|
4
4
|
Summary: PyScript Programming Language
|
|
5
5
|
Home-page: https://azzammuhyala.github.io/pyscript
|
|
6
6
|
Author: AzzamMuhyala
|
|
@@ -125,22 +125,25 @@ Familiar? There it is!
|
|
|
125
125
|
| 20 | `typing` | **required** |
|
|
126
126
|
| 21 | `unicodedata` | **required** |
|
|
127
127
|
| 1 | `ast` | **required (library)** |
|
|
128
|
-
| 2 | `
|
|
129
|
-
| 3 | `
|
|
130
|
-
| 4 | `
|
|
131
|
-
| 5 | `
|
|
132
|
-
| 6 | `
|
|
133
|
-
| 7 | `
|
|
134
|
-
| 8 | `
|
|
135
|
-
| 9 | `
|
|
128
|
+
| 2 | `math` | **required (library)** |
|
|
129
|
+
| 3 | `msvcrt` | **required (library)** |
|
|
130
|
+
| 4 | `pprint` | **required (library)** |
|
|
131
|
+
| 5 | `shutil` | **required (library)** |
|
|
132
|
+
| 6 | `signal` | **required (library)** |
|
|
133
|
+
| 7 | `stat` | **required (library)** |
|
|
134
|
+
| 8 | `termios` | **required (library)** |
|
|
135
|
+
| 9 | `time` | **required (library)** |
|
|
136
|
+
| 10 | `tty` | **required (library)** |
|
|
136
137
|
| 1 | `_colorize` | **optional** |
|
|
137
138
|
| 2 | `beartype` | **optional** |
|
|
138
|
-
| 3 | `
|
|
139
|
-
| 4 | `
|
|
140
|
-
| 5 | `
|
|
141
|
-
| 6 | `
|
|
142
|
-
| 7 | `
|
|
143
|
-
| 8 | `
|
|
139
|
+
| 3 | `ctypes` | **optional** |
|
|
140
|
+
| 4 | `numpy` | **optional** |
|
|
141
|
+
| 5 | `prompt_toolkit` | **optional** |
|
|
142
|
+
| 6 | `pygments` | **optional** |
|
|
143
|
+
| 7 | `readline` | **optional** |
|
|
144
|
+
| 8 | `threading` | **optional** |
|
|
145
|
+
| 9 | `tkinter` | **optional** |
|
|
146
|
+
| 10 | `IPython` | **optional** |
|
|
144
147
|
|
|
145
148
|
### Status Explanation
|
|
146
149
|
- **required**: Required by PyScript entirely.
|
|
@@ -148,9 +151,9 @@ Familiar? There it is!
|
|
|
148
151
|
- **optional**: Not required, but if it is present, some features can be used without issue.
|
|
149
152
|
|
|
150
153
|
## Highlights 🎨
|
|
151
|
-
- [PyScript plugin for Acode
|
|
154
|
+
- [PyScript plugin for Acode](https://github.com/azzammuhyala/pyscript/tree/main/highlight/acode)
|
|
152
155
|
- [PyScript nano for Linux](https://github.com/azzammuhyala/pyscript/tree/main/highlight/nano)
|
|
153
|
-
- [PyScript extension for VSCode](https://
|
|
156
|
+
- [PyScript extension for VSCode](https://github.com/azzammuhyala/pyscript/tree/main/highlight/vscode)
|
|
154
157
|
|
|
155
158
|
## Behind It 🕰️
|
|
156
159
|
This language created from based up on a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
pyscript/__init__.py,sha256=XCCxbC21OByJLmd-MzjURWlCZlX5p3nvjGRfle_510o,1542
|
|
2
2
|
pyscript/__init__.pyi,sha256=szsE8t_GIAPz9Wx_DFdEumH6eRrF_MxpDsRFUHTDKXA,3096
|
|
3
|
-
pyscript/__main__.py,sha256=
|
|
3
|
+
pyscript/__main__.py,sha256=0e4qVVChOENKuTxsfS8-Rsbon4xChI8lIwWVI9zmuIQ,13462
|
|
4
4
|
pyscript/this.py,sha256=aV4HAoWibKhe34uPowyANZRLGCniHamPvnnt8KX0aEA,290
|
|
5
5
|
pyscript/core/__init__.py,sha256=1sqE-oQXVak9zrWYrTrLOzthSQuLFFip3wAnRm76YE0,863
|
|
6
6
|
pyscript/core/analyzer.py,sha256=FXYXmMaqM6Ld95_g0aIwlarZt18mLbD5q5S_j5iHYgo,15586
|
|
@@ -12,37 +12,37 @@ pyscript/core/constants.py,sha256=sTQJU6sT1raKAkyMVcru1dSNirtjU1CU3a-Hu4GBWbc,20
|
|
|
12
12
|
pyscript/core/context.py,sha256=WbGamnSy7QoNR2XiG20WM62Lqdf6T3K8OxLT4VALids,1664
|
|
13
13
|
pyscript/core/exceptions.py,sha256=aJhBQGTzbofNrt66GZcgd71W69kyW59_RQvGrFZugwo,4099
|
|
14
14
|
pyscript/core/handlers.py,sha256=3G4EnrDEByB1aBbq-AKAiKKb7C9Rh9hKuAu2jgCl-9g,2093
|
|
15
|
-
pyscript/core/highlight.py,sha256=
|
|
16
|
-
pyscript/core/interpreter.py,sha256=
|
|
15
|
+
pyscript/core/highlight.py,sha256=ybPcQfZc6vZtWxWTUnSuRb_1Lw2vWHwUsAHqYV_fBc4,20975
|
|
16
|
+
pyscript/core/interpreter.py,sha256=3NlU0VLlfahDjJMv839CWc-M9XTeIJ09QLxip2sNsts,48306
|
|
17
17
|
pyscript/core/lexer.py,sha256=HxS7fevqCNYCz1Q5pCUP9Znr5NCB2BKzDQtpwpcPT0k,28258
|
|
18
|
-
pyscript/core/mapping.py,sha256=
|
|
19
|
-
pyscript/core/nodes.py,sha256=
|
|
20
|
-
pyscript/core/parser.py,sha256=
|
|
18
|
+
pyscript/core/mapping.py,sha256=5ZlMa-n_0sC0r8ivaLGj1-Onxyz2PZFQzn5kmvTjx6c,6474
|
|
19
|
+
pyscript/core/nodes.py,sha256=hKZxjCJNbV2FaXtiRQNb4ueHojG9bJx6zG9zXvJL40M,27703
|
|
20
|
+
pyscript/core/parser.py,sha256=UVpgxAS1-FeF3cxrpLIl-Z8gf5IGxN7VgMyFgmUOduo,86510
|
|
21
21
|
pyscript/core/position.py,sha256=sTsXi0pZLeKf4izK9S1RARhh0GLLGsygqpJGikA2sv4,4455
|
|
22
|
-
pyscript/core/pysbuiltins.py,sha256=
|
|
23
|
-
pyscript/core/pystypes.py,sha256=
|
|
22
|
+
pyscript/core/pysbuiltins.py,sha256=B12oiUWqpZ0ScnMdaR_0YGca-_Ag4pwus0IvAq5Z4QI,23769
|
|
23
|
+
pyscript/core/pystypes.py,sha256=oSiJfawUXS1SpZNpVSf6GfpYFDCPwfU0q7pTq0YiLqA,11564
|
|
24
24
|
pyscript/core/results.py,sha256=HLw5KizQ7YTljOZH31LfXhUix27-4kMLJatfJYdmMRM,5966
|
|
25
|
-
pyscript/core/runner.py,sha256=
|
|
25
|
+
pyscript/core/runner.py,sha256=kxO2N1-ZNdGIIN7KzOU2d0uD1THE1qkfIcuPJ59_4eA,13592
|
|
26
26
|
pyscript/core/shell.py,sha256=M7eF-NRWf4wUWMKuhleoG1j81-Agwau7px51bGgiDuI,15032
|
|
27
27
|
pyscript/core/symtab.py,sha256=kUka8t6R7u275MSHua8fF2RxnLggfPlYH9F2nnuz1zY,3922
|
|
28
|
-
pyscript/core/token.py,sha256=
|
|
29
|
-
pyscript/core/version.py,sha256=
|
|
28
|
+
pyscript/core/token.py,sha256=smCBhmBzXOZao3nlBMedKuY_1BGhueL5akPUL3-i6H4,4215
|
|
29
|
+
pyscript/core/version.py,sha256=tM667nrxIomcOr60MmhfwB5Wp_RjG_98-y4Bd84OIx8,3297
|
|
30
30
|
pyscript/core/editor/__init__.py,sha256=fNSm0C7zsPgYiUiuEjOK05ZfJFdFz6z34wLATpnKbMk,786
|
|
31
31
|
pyscript/core/editor/bases.py,sha256=26FC7K37hupwTY7BLewV7wuv7Dv3uTqb9yrtk6imFEc,2312
|
|
32
|
-
pyscript/core/editor/gui.py,sha256=
|
|
32
|
+
pyscript/core/editor/gui.py,sha256=mGQIyBsKeKhtq1ZQ8EdLANCJxBoFWIMClTX2BF9OSmc,10831
|
|
33
33
|
pyscript/core/editor/terminal.py,sha256=cNQvtHA4yF3rJcJ2VhaYP63whNApW9DCsuz5Nzxm4wM,8863
|
|
34
34
|
pyscript/core/utils/__init__.py,sha256=gBevG7aXEaijEZOW-NCvyCzvhbdRTT6DUr-f0NCaJww,289
|
|
35
35
|
pyscript/core/utils/ansi.py,sha256=4fi-5OxVNMbxvwdHHDC2_9_urv6eLebJDLk9iYnlrmc,4693
|
|
36
|
-
pyscript/core/utils/debug.py,sha256=
|
|
37
|
-
pyscript/core/utils/decorators.py,sha256=
|
|
38
|
-
pyscript/core/utils/generic.py,sha256=
|
|
39
|
-
pyscript/core/utils/module.py,sha256=
|
|
36
|
+
pyscript/core/utils/debug.py,sha256=JQSFK68xGJDdBgg9ty-T6NJQ8EPA0iTypKiKHc-7h0U,3086
|
|
37
|
+
pyscript/core/utils/decorators.py,sha256=wUHGIcvmGRbsaapWupj3WBRAQ2UOPPJbE6-vdeCXBDc,1559
|
|
38
|
+
pyscript/core/utils/generic.py,sha256=Cp1N1XZlEN6PJCdaMq_1goLnHk4wBTcjrxHyMbHp5BI,2178
|
|
39
|
+
pyscript/core/utils/module.py,sha256=o8e6gF5OhgDH0O1vOfOEHst4FFaPAxXm5tbdXO11XuY,1729
|
|
40
40
|
pyscript/core/utils/path.py,sha256=YF7zCwgq8zT4szb3gVsaLdSo8MYZHW8HmxPxrTL2umQ,583
|
|
41
41
|
pyscript/core/utils/similarity.py,sha256=Ez2BOU4f0134v9aFcOH6GQFET0LN8apjRxVh_B_PKRk,998
|
|
42
|
-
pyscript/core/utils/string.py,sha256
|
|
42
|
+
pyscript/core/utils/string.py,sha256=HUos05kSJnW92yrlQIPAxsbvTkW22_RhVqxP41YE9-4,1701
|
|
43
43
|
pyscript/lib/__hello__.pys,sha256=FwyWxN8xK6S-kXmJN7yX3nvE-OM5_YYVSS1TunUyyYk,91
|
|
44
44
|
pyscript/lib/ansi.pys,sha256=DskXRN7U3rS8Jx91G_g7MMZJeAl1PMshtaHRfGuTvOY,36
|
|
45
|
-
pyscript/lib/brainfuck.pys,sha256=
|
|
45
|
+
pyscript/lib/brainfuck.pys,sha256=mWPQIapDPwnBWdzSdtko4DclO0l8281l2eIFYIM43bM,6035
|
|
46
46
|
pyscript/lib/code.pys,sha256=EUuhoaogFX8zKT0OeBXlpJR_qBSylPiW7EQrRv6Eczs,10
|
|
47
47
|
pyscript/lib/dis.pys,sha256=GDFWyh7gpiUnQh-5kFeX3Sctc_gqsFVE6JAknO-Ppmw,163
|
|
48
48
|
pyscript/lib/explorer.pys,sha256=TfucOBZC4RG00PaXJDw95qU4kSefuqcSNyN1_58T1KI,5141
|
|
@@ -61,12 +61,12 @@ pyscript/lib/ast/ast_dump.py,sha256=j16Ze4J_YQkCNDRCtg66N_JReyuJVrFVhtwGLy7Iy8A,
|
|
|
61
61
|
pyscript/lib/ast/ast_literal_eval.py,sha256=WwjDc6_k1sgUn94vOSDcyfeJ3PMaP_g4jyHTRNlkHUU,3338
|
|
62
62
|
pyscript/lib/ast/ast_unparse.py,sha256=miEfQyQ5Dw8SnqTOyYix9ke4K01AWYDUb_l2cn5B8JM,15020
|
|
63
63
|
pyscript/lib/ast/ast_walk.py,sha256=Q-Nq5sOm1MEniIgZkglELYX8QjX6GXznJrOoUZngAXU,6947
|
|
64
|
-
pyscript/lib/dual/__init__.pys,sha256=
|
|
65
|
-
pyscript/lib/dual/py_dual.py,sha256=
|
|
64
|
+
pyscript/lib/dual/__init__.pys,sha256=zt2zNiN3KMoRUVpft4HZzMcn8IW9zUE4gv9i2_n3GNI,326
|
|
65
|
+
pyscript/lib/dual/py_dual.py,sha256=b5_21Mz8db1JnEOw9_kR7JEe2GzNVymwSkxxwVN3FwM,9545
|
|
66
66
|
pyscript/lib/fpstimer/__init__.pys,sha256=PcBFQCck80IA64Zr6QrZakz1XbuZ7nHmvlN6gTAi-Xg,93
|
|
67
67
|
pyscript/lib/fpstimer/py_fpstimer.py,sha256=H8AbSakjk_7KNwXEYXimmbzdJV43Z7j6BXUGdxWhvag,1651
|
|
68
68
|
pyscript/lib/getch/__init__.pys,sha256=NGb8xlHT8vLkgFwKR8ci8ghs29VTG4CyoiXB1L9izrY,162
|
|
69
|
-
pyscript/lib/getch/py_getch.py,sha256=
|
|
69
|
+
pyscript/lib/getch/py_getch.py,sha256=y0pl9o6m7c9XaI3a8R4ItaYwQgfDvzLz-AooGruQaS0,2504
|
|
70
70
|
pyscript/lib/tokenize/__init__.pys,sha256=lJSBSM5YrfrBNoX1Bk-GdkEiMIzlICnWgvW2CfZQcOI,338
|
|
71
71
|
pyscript/lib/tokenize/tok_untokenize.py,sha256=dUH5qsNyGPD69aEGWSSAPA4Qg5xBQlLkjN2wUqZMsD8,2963
|
|
72
72
|
pyscript/other/.nomedia,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -74,8 +74,9 @@ pyscript/other/PyScript.ico,sha256=8I6gC9ZB3iY5un5tQUZ_chj1XYj24XsIEJzqoXBLI48,8
|
|
|
74
74
|
pyscript/other/copyright,sha256=Ov5gxRKrwwRweaYgYiFTP-rVGGgiWEDCJCi2SSpLYSA,54
|
|
75
75
|
pyscript/other/credits,sha256=c49yrwp4dLyLtlrfAED7PJJ3aElkbRXz7Innu2x-Auc,159
|
|
76
76
|
pyscript/other/license,sha256=ORU3AMOH_uOwOcEe1yAt6r56mvlYjZhvCDKBNB7SU0c,1088
|
|
77
|
+
pyscript/other/message.txt,sha256=GJBnG-fU8zap0jyAun6i5L9K9muY8LCV_5DL2D-pJpE,1863
|
|
77
78
|
pyscript/site-packages/this.pys,sha256=qX6eBYq5bq2_hvpn76w1D4EvVktwwsr-iXysALroCaw,352
|
|
78
|
-
pyscript_programming_language-1.15.
|
|
79
|
-
pyscript_programming_language-1.15.
|
|
80
|
-
pyscript_programming_language-1.15.
|
|
81
|
-
pyscript_programming_language-1.15.
|
|
79
|
+
pyscript_programming_language-1.15.1.dist-info/METADATA,sha256=huxmjjHozKPcJJk8keMpdYHXAZPB9evJaANA_4N6UUw,20085
|
|
80
|
+
pyscript_programming_language-1.15.1.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
81
|
+
pyscript_programming_language-1.15.1.dist-info/top_level.txt,sha256=17-G0eqhWERkkD2m3ZGUqOtJl9SoqFVyR3rdbImxyZI,9
|
|
82
|
+
pyscript_programming_language-1.15.1.dist-info/RECORD,,
|
|
File without changes
|