pyscript-programming-language 1.12.0__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.
Files changed (76) hide show
  1. pyscript/__init__.py +49 -0
  2. pyscript/__init__.pyi +96 -0
  3. pyscript/__main__.py +303 -0
  4. pyscript/core/__init__.py +61 -0
  5. pyscript/core/analyzer.py +531 -0
  6. pyscript/core/bases.py +2 -0
  7. pyscript/core/buffer.py +43 -0
  8. pyscript/core/cache.py +70 -0
  9. pyscript/core/checks.py +42 -0
  10. pyscript/core/constants.py +123 -0
  11. pyscript/core/context.py +63 -0
  12. pyscript/core/editor/__init__.py +15 -0
  13. pyscript/core/editor/bases.py +35 -0
  14. pyscript/core/editor/gui.py +144 -0
  15. pyscript/core/editor/terminal.py +175 -0
  16. pyscript/core/exceptions.py +123 -0
  17. pyscript/core/handlers.py +57 -0
  18. pyscript/core/highlight.py +552 -0
  19. pyscript/core/interpreter.py +1546 -0
  20. pyscript/core/lexer.py +863 -0
  21. pyscript/core/mapping.py +139 -0
  22. pyscript/core/nodes.py +663 -0
  23. pyscript/core/objects.py +213 -0
  24. pyscript/core/parser.py +2456 -0
  25. pyscript/core/position.py +114 -0
  26. pyscript/core/pysbuiltins.py +703 -0
  27. pyscript/core/results.py +186 -0
  28. pyscript/core/runner.py +363 -0
  29. pyscript/core/shell.py +287 -0
  30. pyscript/core/symtab.py +103 -0
  31. pyscript/core/token.py +25 -0
  32. pyscript/core/utils/__init__.py +27 -0
  33. pyscript/core/utils/ansi.py +127 -0
  34. pyscript/core/utils/debug.py +60 -0
  35. pyscript/core/utils/decorators.py +53 -0
  36. pyscript/core/utils/generic.py +46 -0
  37. pyscript/core/utils/jsdict.py +32 -0
  38. pyscript/core/utils/module.py +28 -0
  39. pyscript/core/utils/path.py +29 -0
  40. pyscript/core/utils/similarity.py +22 -0
  41. pyscript/core/utils/string.py +49 -0
  42. pyscript/core/version.py +120 -0
  43. pyscript/lib/__hello__.pys +7 -0
  44. pyscript/lib/ansi.pys +14 -0
  45. pyscript/lib/ast/__init__.pys +36 -0
  46. pyscript/lib/ast/ast_dump.py +433 -0
  47. pyscript/lib/ast/ast_literal_eval.py +80 -0
  48. pyscript/lib/ast/ast_unparse.py +540 -0
  49. pyscript/lib/ast/ast_walk.py +256 -0
  50. pyscript/lib/brainfuck.pys +190 -0
  51. pyscript/lib/dis.pys +7 -0
  52. pyscript/lib/explorer.pys +218 -0
  53. pyscript/lib/fpstimer/__init__.pys +6 -0
  54. pyscript/lib/fpstimer/py_fpstimer.py +54 -0
  55. pyscript/lib/getch.pys +28 -0
  56. pyscript/lib/inspect.pys +25 -0
  57. pyscript/lib/jsdict.pys +5 -0
  58. pyscript/lib/keyword.pys +2 -0
  59. pyscript/lib/opcode.pys +1 -0
  60. pyscript/lib/parser.pys +165 -0
  61. pyscript/lib/site.pys +55 -0
  62. pyscript/lib/symtable.pys +5 -0
  63. pyscript/lib/token.pys +12 -0
  64. pyscript/lib/tokenize/__init__.pys +14 -0
  65. pyscript/lib/tokenize/tok_untokenize.py +64 -0
  66. pyscript/other/.nomedia +0 -0
  67. pyscript/other/PyScript.ico +0 -0
  68. pyscript/other/copyright +2 -0
  69. pyscript/other/credits +2 -0
  70. pyscript/other/license +21 -0
  71. pyscript/site-packages/this.pys +19 -0
  72. pyscript/this.py +8 -0
  73. pyscript_programming_language-1.12.0.dist-info/METADATA +133 -0
  74. pyscript_programming_language-1.12.0.dist-info/RECORD +76 -0
  75. pyscript_programming_language-1.12.0.dist-info/WHEEL +5 -0
  76. pyscript_programming_language-1.12.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,703 @@
1
+ from .bases import Pys
2
+ from .buffer import PysFileBuffer
3
+ from .cache import pys_sys
4
+ from .checks import is_blacklist_python_builtins, is_private_attribute
5
+ from .constants import OTHER_PATH, NO_COLOR, CLASSIC_LINE_SHELL
6
+ from .exceptions import PysSignal
7
+ from .handlers import handle_call
8
+ from .mapping import ACOLORS, EMPTY_MAP
9
+ from .objects import PysFunction, PysPythonFunction, PysBuiltinFunction
10
+ from .results import PysRunTimeResult
11
+ from .shell import PysClassicLineShell, PysPromptToolkitLineShell
12
+ from .symtab import new_symbol_table
13
+ from .utils.debug import import_readline
14
+ from .utils.generic import dkeys, get_subscript, is_object_of as isobjectof
15
+ from .utils.module import get_module_path, set_python_path, remove_python_path
16
+ from .utils.path import getcwd, normpath, get_name_from_path
17
+ from .utils.string import normstr
18
+
19
+ from math import inf, nan, isclose
20
+ from importlib import import_module
21
+ from inspect import signature
22
+ from os.path import dirname, isdir
23
+ from types import BuiltinFunctionType, BuiltinMethodType, FunctionType, MethodType, ModuleType
24
+ from typing import Any
25
+
26
+ import builtins
27
+ import sys
28
+
29
+ real_number = (int, float)
30
+ sequence = (list, tuple, set)
31
+ optional_mapping = (dict, type(None))
32
+ static_wrapper_function = (staticmethod,)
33
+ wrapper_function = (MethodType, PysPythonFunction, classmethod)
34
+ python_function = (BuiltinFunctionType, BuiltinMethodType, FunctionType)
35
+
36
+ pyhelp = builtins.help
37
+ pyvars = builtins.vars
38
+ pydir = builtins.dir
39
+
40
+ def _supported_method(pyfunc, object, name, *args, **kwargs):
41
+ if callable(method := getattr(object, name, None)):
42
+ code = pyfunc.__code__
43
+ handle_call(method, code.context, code.position)
44
+ try:
45
+ result = method(*args, **kwargs)
46
+ if result is not NotImplemented:
47
+ return True, result
48
+ except NotImplementedError:
49
+ pass
50
+ return False, None
51
+
52
+ def _unpack_comprehension_function(pyfunc, function):
53
+ code = pyfunc.__code__
54
+ check = function
55
+ final = function
56
+ offset = 0
57
+
58
+ if isinstance(function, wrapper_function):
59
+ check = function.__func__
60
+ offset += 1
61
+ elif isinstance(function, static_wrapper_function):
62
+ check = function.__func__
63
+
64
+ if isinstance(check, PysFunction):
65
+ length = max(check.__code__.parameters_length - offset, 0)
66
+ if length == 0:
67
+ def final(item):
68
+ return function()
69
+ elif length > 1:
70
+ def final(item):
71
+ return function(*item)
72
+
73
+ elif isinstance(check, python_function):
74
+ parameters = signature(check).parameters
75
+ length = max(len(parameters) - offset, 0)
76
+ if length == 0:
77
+ def final(item):
78
+ return function()
79
+ elif length > 1 or any(p.kind == p.VAR_POSITIONAL for p in parameters.values()):
80
+ def final(item):
81
+ return function(*item)
82
+
83
+ handle_call(function, code.context, code.position)
84
+ return final
85
+
86
+ class _Printer(Pys):
87
+
88
+ def __init__(self, name: str, text: str | Any) -> None:
89
+ self.name = name
90
+ self.text = text
91
+
92
+ def __repr__(self) -> str:
93
+ return f'Type {self.name}() to see the full information text.'
94
+
95
+ def __call__(self) -> None:
96
+ print(self.text)
97
+
98
+ class _Helper(_Printer):
99
+
100
+ def __init__(self) -> None:
101
+ super().__init__('help', None)
102
+
103
+ def __repr__(self) -> str:
104
+ return f'Type {self.name}() for interactive help, or {self.name}(object) for help about object.'
105
+
106
+ def __call__(self, *args, **kwargs):
107
+ if not (args or kwargs):
108
+ print(
109
+ "Welcome to the PyScript programming language! "
110
+ "This is the help utility directly to the Python help.\n\n"
111
+ "To get help on a specific object, type 'help(object)'.\n"
112
+ "To get the list of builtin functions, types, exceptions, and other objects, type 'help(\"builtins\")'."
113
+ )
114
+ else:
115
+ return pyhelp(*args, **kwargs)
116
+
117
+ try:
118
+ with (
119
+ open(normpath(OTHER_PATH, 'copyright', absolute=False)) as copyright,
120
+ open(normpath(OTHER_PATH, 'credits', absolute=False)) as credits,
121
+ open(normpath(OTHER_PATH, 'license', absolute=False)) as license
122
+ ):
123
+ copyright = _Printer('copyright', copyright.read())
124
+ credits = _Printer('credits', credits.read())
125
+ license = _Printer('license', license.read())
126
+ except:
127
+ copyright = _Printer('copyright', '')
128
+ credits = _Printer('credits', '')
129
+ license = _Printer('license', '')
130
+
131
+ help = _Helper()
132
+
133
+ @PysBuiltinFunction
134
+ def require(pyfunc, name):
135
+
136
+ """
137
+ require(name: str | bytes) -> ModuleType | Any
138
+
139
+ Import a PyScript module.
140
+
141
+ name: A name or path of the module to be imported.
142
+ """
143
+
144
+ name, *other_components = normstr(name).split('>')
145
+ code = pyfunc.__code__
146
+ context = code.context
147
+ filename = context.file.name
148
+
149
+ for p in pys_sys.path:
150
+ module_path = get_module_path(normpath(p, name, absolute=False))
151
+ if module_path is not None:
152
+ break
153
+ else:
154
+ module_path = get_module_path(normpath(dirname(filename) or getcwd(), name, absolute=False))
155
+ if module_path == filename:
156
+ module_path = None
157
+
158
+ if module_path is None:
159
+ if name == '_pyscript':
160
+ from .. import core as module
161
+ elif name == 'builtins':
162
+ module = pys_builtins
163
+ elif name == 'sys':
164
+ module = pys_sys
165
+ else:
166
+ module_path = name
167
+
168
+ if module_path is not None:
169
+ loading_modules = pys_sys.loading_modules
170
+ modules = pys_sys.modules
171
+ module = modules.get(module_path, None)
172
+
173
+ if module is None:
174
+
175
+ if isdir(module_path):
176
+ raise ModuleNotFoundError(f"No module named {name!r}: Invalid module")
177
+ elif module_path in loading_modules:
178
+ raise ImportError(
179
+ f"cannot import module name {name!r} from partially initialized module {filename!r}, "
180
+ "mostly during circular import"
181
+ )
182
+
183
+ try:
184
+ loading_modules.add(module_path)
185
+
186
+ try:
187
+ with open(module_path, 'r', encoding='utf-8') as file:
188
+ file = PysFileBuffer(file, module_path)
189
+ except FileNotFoundError as e:
190
+ raise ModuleNotFoundError(f"No module named {name!r}") from e
191
+ except (IsADirectoryError, NotADirectoryError) as e:
192
+ raise ModuleNotFoundError(f"No module named {name!r}: Invalid module") from e
193
+ except BaseException as e:
194
+ raise ImportError(f"Cannot import module named {name!r}: {e}") from e
195
+
196
+ from .runner import pys_runner
197
+
198
+ symtab, module = new_symbol_table(file=file.name, name=get_name_from_path(name))
199
+
200
+ # minimize circular imports (python standard)
201
+ modules[module_path] = module
202
+
203
+ result = pys_runner(
204
+ file=file,
205
+ mode='exec',
206
+ symbol_table=symtab,
207
+ context_parent=context,
208
+ context_parent_entry_position=code.position
209
+ )
210
+
211
+ if result.error:
212
+ raise PysSignal(PysRunTimeResult().failure(result.error))
213
+
214
+ # this can also get circular imports
215
+ # modules[module_path] = module
216
+
217
+ except:
218
+ modules.pop(module_path, None)
219
+ raise
220
+
221
+ finally:
222
+ loading_modules.discard(module_path)
223
+
224
+ for component in other_components:
225
+ module = getattr(module, component)
226
+
227
+ return module
228
+
229
+ @PysBuiltinFunction
230
+ def pyimport(pyfunc, name):
231
+
232
+ """
233
+ pyimport(name: str | bytes) -> ModuleType
234
+
235
+ Import a Python module.
236
+
237
+ name: A name of the module to be imported.
238
+ """
239
+
240
+ dirpath = dirname(pyfunc.__code__.context.file.name)
241
+ try:
242
+ set_python_path(dirpath)
243
+ return import_module(normstr(name))
244
+ finally:
245
+ remove_python_path(dirpath)
246
+
247
+ @PysBuiltinFunction
248
+ def breakpoint(pyfunc):
249
+
250
+ """
251
+ Pauses program execution and enters shell debugging mode.
252
+ """
253
+
254
+ if pys_sys.__running_breakpoint__:
255
+ raise RuntimeError("another breakpoint is still running")
256
+
257
+ from .runner import pys_runner
258
+
259
+ code = pyfunc.__code__
260
+ context = code.context
261
+ position = code.position
262
+ symtab = context.symbol_table
263
+ flags = context.flags
264
+ colored = not (flags & NO_COLOR)
265
+ scopes = []
266
+
267
+ if colored:
268
+ reset = ACOLORS('reset')
269
+ bmagenta = ACOLORS('bold-magenta')
270
+ else:
271
+ reset = ''
272
+ bmagenta = ''
273
+
274
+ shell = (PysClassicLineShell if flags & CLASSIC_LINE_SHELL else PysPromptToolkitLineShell)(
275
+ f'{bmagenta}(Pdb) {reset}',
276
+ f'{bmagenta}... {reset}',
277
+ colored=colored
278
+ )
279
+
280
+ def show_line():
281
+ print(f'> {context.file.name}({position.start_line}){context.name}')
282
+
283
+ import_readline()
284
+ show_line()
285
+
286
+ try:
287
+ pys_sys.__running_breakpoint__ = True
288
+
289
+ while True:
290
+
291
+ try:
292
+ text = shell.prompt()
293
+ if text == 1:
294
+ print("*** Unable to clean up namespace", file=sys.stderr)
295
+ continue
296
+
297
+ split = ['exit'] if text == 0 else text.split()
298
+ if split:
299
+ command, *args = split
300
+ else:
301
+ command, args = '', []
302
+
303
+ if command in ('c', 'continue'):
304
+ return
305
+
306
+ elif command in ('h', 'help'):
307
+ print(
308
+ "\n"
309
+ "Documented commands:\n"
310
+ "====================\n"
311
+ "(c)ontinue : Exit the debugger and continue the program.\n"
312
+ "(d)own [count] : Decrease the scope level (default one) to the older frame.\n"
313
+ "(h)elp : Show this help display.\n"
314
+ "(l)ine : Show the position where breakpoint() was called.\n"
315
+ "(q)uit / exit [code]: Exit the interpreter by throwing SystemExit.\n"
316
+ "(u)p [count] : Increase the scope level (default one) to the older frame.\n"
317
+ )
318
+
319
+ elif command in ('l', 'line'):
320
+ show_line()
321
+
322
+ elif command in ('q', 'quit', 'exit'):
323
+ code = get_subscript(args, 0, '0')
324
+ raise SystemExit(int(code) if code.isdigit() else code)
325
+
326
+ elif command in ('u', 'up'):
327
+ count = get_subscript(args, 0, '')
328
+ for _ in range(int(count) if count.isdigit() else 1):
329
+ if scopes:
330
+ symtab = scopes.pop()
331
+ else:
332
+ print('*** Oldest frame')
333
+ break
334
+
335
+ elif command in ('d', 'down'):
336
+ count = get_subscript(args, 0, '')
337
+ parent = symtab.parent
338
+ for _ in range(int(count) if count.isdigit() else 1):
339
+ if parent is None:
340
+ print('*** Newest frame')
341
+ break
342
+ else:
343
+ scopes.append(symtab)
344
+ symtab = parent
345
+
346
+ else:
347
+ exit_code, exit = pys_runner(
348
+ file=PysFileBuffer(text, '<breakpoint>'),
349
+ mode='single',
350
+ symbol_table=symtab
351
+ ).end_process()
352
+
353
+ if exit:
354
+ raise SystemExit(exit_code)
355
+
356
+ except KeyboardInterrupt:
357
+ shell.reset()
358
+ print('\r--KeyboardInterrupt--', file=sys.stderr)
359
+
360
+ except EOFError as e:
361
+ raise SystemExit from e
362
+
363
+ finally:
364
+ pys_sys.__running_breakpoint__ = False
365
+
366
+ @PysBuiltinFunction
367
+ def globals(pyfunc):
368
+
369
+ """
370
+ Returns a dictionary containing the current global scope of variables.
371
+
372
+ NOTE: Modifying the contents of a dictionary within a program or module scope will affect that scope. However,
373
+ this does not apply to local scopes (creating a new dictionary).
374
+ """
375
+
376
+ original = pyfunc.__code__.context.symbol_table
377
+ symbol_table = original.parent
378
+
379
+ if symbol_table:
380
+ result = {}
381
+
382
+ while symbol_table:
383
+ result |= symbol_table.symbols
384
+ symbol_table = symbol_table.parent
385
+
386
+ return result
387
+
388
+ return original.symbols
389
+
390
+ @PysBuiltinFunction
391
+ def locals(pyfunc):
392
+
393
+ """
394
+ Returns a dictionary containing the current local scope of variables.
395
+
396
+ NOTE: Changing the contents of the dictionary will affect the scope.
397
+ """
398
+
399
+ return pyfunc.__code__.context.symbol_table.symbols
400
+
401
+ @PysBuiltinFunction
402
+ def vars(pyfunc, *args):
403
+
404
+ """
405
+ Without arguments, equivalent to locals(). With an argument, equivalent to object.__dict__.
406
+ """
407
+
408
+ return pyvars(*args) if args else pyfunc.__code__.context.symbol_table.symbols
409
+
410
+ @PysBuiltinFunction
411
+ def dir(pyfunc, *args):
412
+
413
+ """
414
+ If called without an argument, return the names in the current scope. Else, return an alphabetized list of names
415
+ comprising (some of) the attributes of the given object, and of attributes reachable from it. If the object supplies
416
+ a method named __dir__, it will be used; otherwise the default dir() logic is used and returns:
417
+ for a module object: the module's attributes.
418
+ for a class object: its attributes, and recursively the attributes of its bases.
419
+ for any other object: its attributes, its class's attributes, and recursively the attributes of its class's base
420
+ classes.
421
+ """
422
+
423
+ return pydir(*args) if args else list(dkeys(pyfunc.__code__.context.symbol_table.symbols))
424
+
425
+ @PysBuiltinFunction
426
+ def exec(pyfunc, source, globals=None):
427
+
428
+ """
429
+ exec(source: str | bytes, globals: Optional[dict]) -> None
430
+
431
+ Executes PyScript code statements from the given source.
432
+
433
+ source: A string containing the code statements to be executed.
434
+ globals: The namespace scope for the code that can be accessed, modified, and deleted. If not provided, the current
435
+ local scope will be used.
436
+ """
437
+
438
+ if not isinstance(globals, optional_mapping):
439
+ raise TypeError("exec(): globals must be dict")
440
+
441
+ file = PysFileBuffer(source, '<exec>')
442
+ code = pyfunc.__code__
443
+
444
+ if globals is None:
445
+ symtab = code.context.symbol_table
446
+ else:
447
+ symtab, _ = new_symbol_table(symbols=globals)
448
+
449
+ from .runner import pys_runner
450
+
451
+ result = pys_runner(
452
+ file=file,
453
+ mode='exec',
454
+ symbol_table=symtab,
455
+ context_parent=code.context,
456
+ context_parent_entry_position=code.position
457
+ )
458
+
459
+ if result.error:
460
+ raise PysSignal(PysRunTimeResult().failure(result.error))
461
+
462
+ @PysBuiltinFunction
463
+ def eval(pyfunc, source, globals=None):
464
+
465
+ """
466
+ eval(source: str | bytes, globals: Optional[dict]) -> None
467
+
468
+ Executes a PyScript code expression from the given source.
469
+
470
+ source: A string containing the code statements to be executed.
471
+ globals: The namespace scope for the code that can be accessed, modified, and deleted. If not provided, the current
472
+ local scope will be used.
473
+ """
474
+
475
+ if not isinstance(globals, optional_mapping):
476
+ raise TypeError("eval(): globals must be dict")
477
+
478
+ file = PysFileBuffer(source, '<eval>')
479
+ code = pyfunc.__code__
480
+
481
+ if globals is None:
482
+ symtab = code.context.symbol_table
483
+ else:
484
+ symtab, _ = new_symbol_table(symbols=globals)
485
+
486
+ from .runner import pys_runner
487
+
488
+ result = pys_runner(
489
+ file=file,
490
+ mode='eval',
491
+ symbol_table=symtab,
492
+ context_parent=code.context,
493
+ context_parent_entry_position=code.position
494
+ )
495
+
496
+ if result.error:
497
+ raise PysSignal(PysRunTimeResult().failure(result.error))
498
+
499
+ return result.value
500
+
501
+ @PysBuiltinFunction
502
+ def ce(pyfunc, a, b, *, rel_tol=1e-9, abs_tol=0):
503
+
504
+ """
505
+ ce(a: Any, b: Any, *, rel_tol: Any = 1e-9, abs_tol: Any = 0) -> Any
506
+ a ~= b
507
+
508
+ Comparing two objects a and b to close equal.
509
+
510
+ a, b: Two objects to be compared. If both are integer or float, it will call `math.isclose()` function. Otherwise,
511
+ it will attempt to call the __ce__ method (if both fail, it calls the negated __nce__ method) of one of the
512
+ two objects. If all else fails, it will throw a TypeError.
513
+ rel_tol: maximum difference for being considered "close", relative to the magnitude of the input values.
514
+ abs_tol: maximum difference for being considered "close", regardless of the magnitude of the input values.
515
+ """
516
+
517
+ if isinstance(a, real_number) and isinstance(b, real_number):
518
+ return isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol)
519
+
520
+ success, result = _supported_method(pyfunc, a, '__ce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
521
+ if not success:
522
+ success, result = _supported_method(pyfunc, b, '__ce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
523
+ if not success:
524
+ success, result = _supported_method(pyfunc, a, '__nce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
525
+ if not success:
526
+ success, result = _supported_method(pyfunc, b, '__nce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
527
+ if not success:
528
+ raise TypeError(
529
+ f"unsupported operand type(s) for ~= or ce(): {type(a).__name__!r} and {type(b).__name__!r}"
530
+ )
531
+ result = not result
532
+
533
+ return result
534
+
535
+ @PysBuiltinFunction
536
+ def nce(pyfunc, a, b, *, rel_tol=1e-9, abs_tol=0):
537
+
538
+ """
539
+ nce(a: Any, b: Any, *, rel_tol: Any = 1e-9, abs_tol: Any = 0) -> Any
540
+ a ~! b
541
+
542
+ Comparing two objects a and b to not close equal.
543
+
544
+ a, b: Two objects to be compared. If both are integer or float, it calls the `not math.isclose()` function.
545
+ Otherwise, it attempts to call the __nce__ method (if both fail, it calls the negated __ce__ method) of one of
546
+ the two objects. If both fail, it throws a TypeError.
547
+ rel_tol: maximum difference for being considered "close", relative to the magnitude of the input values.
548
+ abs_tol: maximum difference for being considered "close", regardless of the magnitude of the input values.
549
+ """
550
+
551
+ if isinstance(a, real_number) and isinstance(b, real_number):
552
+ return not isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol)
553
+
554
+ success, result = _supported_method(pyfunc, a, '__nce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
555
+ if not success:
556
+ success, result = _supported_method(pyfunc, b, '__nce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
557
+ if not success:
558
+ success, result = _supported_method(pyfunc, a, '__ce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
559
+ if not success:
560
+ success, result = _supported_method(pyfunc, b, '__ce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
561
+ if not success:
562
+ raise TypeError(
563
+ f"unsupported operand type(s) for ~! or nce(): {type(a).__name__!r} and {type(b).__name__!r}"
564
+ )
565
+ result = not result
566
+
567
+ return result
568
+
569
+ @PysBuiltinFunction
570
+ def increment(pyfunc, object):
571
+
572
+ """
573
+ increment(object: Any) -> Any
574
+ object++
575
+ ++object
576
+
577
+ Increase to the object. If the given type is integer or float, it will increment by 1, if the given type is unpack
578
+ assignment (list, tuple, or set), it will increment each element. Otherwise, it will attempt to call the
579
+ __increment__ method, which if unsuccessful will throw a TypeError.
580
+ """
581
+
582
+ if isinstance(object, real_number):
583
+ return object + 1
584
+ elif isinstance(object, sequence):
585
+ return tuple(pyincrement(pyfunc, obj) for obj in object)
586
+
587
+ success, result = _supported_method(pyfunc, object, '__increment__')
588
+ if not success:
589
+ raise TypeError(f"bad operand type for unary ++ or increment(): {type(object).__name__!r}")
590
+
591
+ return result
592
+
593
+ @PysBuiltinFunction
594
+ def decrement(pyfunc, object):
595
+
596
+ """
597
+ decrement(object: Any) -> Any
598
+ object--
599
+ --object
600
+
601
+ Decrease to the object. If the given type is integer or float, it will decrement by 1, if the given type is unpack
602
+ assignment (list, tuple, or set), it will decrement each element. Otherwise, it will attempt to
603
+ call the __decrement__ method, which if unsuccessful will throw a TypeError.
604
+ """
605
+
606
+ if isinstance(object, real_number):
607
+ return object - 1
608
+ elif isinstance(object, sequence):
609
+ return tuple(pydecrement(pyfunc, obj) for obj in object)
610
+
611
+ success, result = _supported_method(pyfunc, object, '__decrement__')
612
+ if not success:
613
+ raise TypeError(f"bad operand type for unary -- or decrement(): {type(object).__name__!r}")
614
+
615
+ return result
616
+
617
+ pyincrement = increment.__func__
618
+ pydecrement = decrement.__func__
619
+
620
+ @PysBuiltinFunction
621
+ def unpack(pyfunc, function, args=(), kwargs=EMPTY_MAP):
622
+
623
+ """
624
+ unpack(function: Callable, args: Iterable = (), kwargs: Mapping = {}) -> Any
625
+
626
+ A replacement function for Python's argument unpack on function calls, which uses the syntax
627
+ `function(*args, **kwargs)`.
628
+
629
+ function: the function to be called.
630
+ args: regular arguments (iterable object).
631
+ kwargs: keyword arguments (mapping object).
632
+ """
633
+
634
+ code = pyfunc.__code__
635
+ handle_call(function, code.context, code.position)
636
+ return function(*args, **kwargs)
637
+
638
+ @PysBuiltinFunction
639
+ def comprehension(pyfunc, init, wrap, condition=None):
640
+
641
+ """
642
+ comprehension(
643
+ init: Iterable[Any],
644
+ wrap: Callable[[Any], Any],
645
+ condition: Optional[Callable[[Any], bool]] = None
646
+ ) -> Iterable[Any]
647
+
648
+ A replacement function for Python's list comprehension, which uses the syntax
649
+ `[wrap for item in init if condition]`.
650
+
651
+ init: The iterable object to be iterated.
652
+ wrap: The function that wraps the results of the iteration (Unpack per-iteration if parameter is more than 1).
653
+ condition: The function that filters the iteration (Unpack per-iteration if parameter is more than 1).
654
+ """
655
+
656
+ if not callable(wrap):
657
+ raise TypeError("comprehension(): wrap must be callable")
658
+ if not (condition is None or callable(condition)):
659
+ raise TypeError("comprehension(): condition must be callable")
660
+
661
+ return map(
662
+ _unpack_comprehension_function(pyfunc, wrap),
663
+ init if condition is None else filter(_unpack_comprehension_function(pyfunc, condition), init)
664
+ )
665
+
666
+ pys_builtins = ModuleType(
667
+ 'builtins',
668
+ "Built-in functions, types, exceptions, and other objects.\n\n"
669
+ "This module provides direct access to all 'built-in' identifiers of PyScript and Python."
670
+ )
671
+
672
+ pys_builtins.__dict__.update(
673
+ (name, getattr(builtins, name))
674
+ for name in pydir(builtins)
675
+ if not (is_private_attribute(name) or is_blacklist_python_builtins(name))
676
+ )
677
+
678
+ pys_builtins.true = True
679
+ pys_builtins.false = False
680
+ pys_builtins.none = None
681
+ pys_builtins.ellipsis = Ellipsis
682
+ pys_builtins.inf = pys_builtins.infinity = pys_builtins.Infinity = inf
683
+ pys_builtins.nan = pys_builtins.notanumber = pys_builtins.NaN = pys_builtins.NotANumber = nan
684
+ pys_builtins.copyright = copyright
685
+ pys_builtins.credits = credits
686
+ pys_builtins.license = license
687
+ pys_builtins.help = help
688
+ pys_builtins.require = require
689
+ pys_builtins.pyimport = pyimport
690
+ pys_builtins.breakpoint = breakpoint
691
+ pys_builtins.globals = globals
692
+ pys_builtins.locals = locals
693
+ pys_builtins.vars = vars
694
+ pys_builtins.dir = dir
695
+ pys_builtins.exec = exec
696
+ pys_builtins.eval = eval
697
+ pys_builtins.ce = ce
698
+ pys_builtins.nce = nce
699
+ pys_builtins.increment = increment
700
+ pys_builtins.decrement = decrement
701
+ pys_builtins.unpack = unpack
702
+ pys_builtins.comprehension = comprehension
703
+ pys_builtins.isobjectof = isobjectof