pyscript-programming-language 1.12.12__tar.gz → 1.12.13__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/PKG-INFO +12 -2
  2. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/README.md +11 -1
  3. pyscript_programming_language-1.12.13/changelog.md +11 -0
  4. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyproject.toml +1 -1
  5. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/__main__.py +18 -16
  6. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/cache.py +1 -0
  7. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/handlers.py +28 -28
  8. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/interpreter.py +6 -7
  9. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/pysbuiltins.py +92 -74
  10. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/pystypes.py +30 -20
  11. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/shell.py +2 -5
  12. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/utils/debug.py +0 -2
  13. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/version.py +2 -2
  14. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/brainfuck.pys +5 -4
  15. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/tokenize/tok_untokenize.py +15 -7
  16. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript_programming_language.egg-info/PKG-INFO +12 -2
  17. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/setup.py +1 -1
  18. pyscript_programming_language-1.12.12/changelog.md +0 -10
  19. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/MANIFEST.in +0 -0
  20. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/__init__.py +0 -0
  21. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/__init__.pyi +0 -0
  22. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/__init__.py +0 -0
  23. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/analyzer.py +0 -0
  24. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/bases.py +0 -0
  25. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/buffer.py +0 -0
  26. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/checks.py +0 -0
  27. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/constants.py +0 -0
  28. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/context.py +0 -0
  29. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/editor/__init__.py +0 -0
  30. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/editor/bases.py +0 -0
  31. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/editor/gui.py +0 -0
  32. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/editor/terminal.py +0 -0
  33. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/exceptions.py +0 -0
  34. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/highlight.py +0 -0
  35. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/lexer.py +0 -0
  36. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/mapping.py +0 -0
  37. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/nodes.py +0 -0
  38. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/parser.py +0 -0
  39. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/position.py +0 -0
  40. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/results.py +0 -0
  41. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/runner.py +0 -0
  42. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/symtab.py +0 -0
  43. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/token.py +0 -0
  44. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/utils/__init__.py +0 -0
  45. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/utils/ansi.py +0 -0
  46. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/utils/decorators.py +0 -0
  47. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/utils/generic.py +0 -0
  48. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/utils/module.py +0 -0
  49. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/utils/path.py +0 -0
  50. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/utils/similarity.py +0 -0
  51. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/core/utils/string.py +0 -0
  52. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/__hello__.pys +0 -0
  53. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/ansi.pys +0 -0
  54. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/ast/__init__.pys +0 -0
  55. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/ast/ast_dump.py +0 -0
  56. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/ast/ast_literal_eval.py +0 -0
  57. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/ast/ast_unparse.py +0 -0
  58. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/ast/ast_walk.py +0 -0
  59. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/code.pys +0 -0
  60. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/dis.pys +0 -0
  61. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/explorer.pys +0 -0
  62. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/fpstimer/__init__.pys +0 -0
  63. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/fpstimer/py_fpstimer.py +0 -0
  64. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/getch/__init__.pys +0 -0
  65. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/getch/py_getch.py +0 -0
  66. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/history.pys +0 -0
  67. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/inspect.pys +0 -0
  68. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/jsdict.pys +0 -0
  69. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/keyword.pys +0 -0
  70. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/opcode.pys +0 -0
  71. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/parser.pys +0 -0
  72. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/pdisplay.pys +0 -0
  73. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/site.pys +0 -0
  74. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/symtable.pys +0 -0
  75. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/token.pys +0 -0
  76. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/lib/tokenize/__init__.pys +0 -0
  77. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/other/.nomedia +0 -0
  78. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/other/PyScript.ico +0 -0
  79. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/other/copyright +0 -0
  80. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/other/credits +0 -0
  81. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/other/license +0 -0
  82. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/site-packages/this.pys +0 -0
  83. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript/this.py +0 -0
  84. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
  85. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  86. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript_programming_language.egg-info/requires.txt +0 -0
  87. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  88. {pyscript_programming_language-1.12.12 → pyscript_programming_language-1.12.13}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.12.12
3
+ Version: 1.12.13
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://azzammuhyala.github.io/pyscript
6
6
  Author: azzammuhyala
@@ -30,10 +30,20 @@ Dynamic: author
30
30
  Dynamic: home-page
31
31
  Dynamic: requires-python
32
32
 
33
- # PyScript 🐍🟨🟦⬛
33
+ # PyScript
34
34
 
35
35
  <div align="center">
36
36
  <img src="https://github.com/azzammuhyala/pyscript/blob/main/PyScript.png?raw=true" alt="PyScript Logo" width="200">
37
+ <br>
38
+ <a href="https://pepy.tech/project/pyscript-programming-language">
39
+ <img src="https://static.pepy.tech/personalized-badge/pyscript-programming-language?period=total&units=NONE&left_color=GRAY&right_color=GREEN&left_text=downloads" alt="PyPI Downloads">
40
+ </a>
41
+ <a href="https://en.wikipedia.org/wiki/MIT_License">
42
+ <img src="https://img.shields.io/badge/license-MIT-orange" alt="License MIT">
43
+ </a>
44
+ <a href="https://www.python.org/">
45
+ <img src="https://img.shields.io/badge/python-3.10-yellow" alt="Python 3.10+">
46
+ </a>
37
47
  </div>
38
48
 
39
49
  PyScript is a programming language built on top of Python. It combines some syntax from Python and JavaScript, so if
@@ -1,7 +1,17 @@
1
- # PyScript 🐍🟨🟦⬛
1
+ # PyScript
2
2
 
3
3
  <div align="center">
4
4
  <img src="https://github.com/azzammuhyala/pyscript/blob/main/PyScript.png?raw=true" alt="PyScript Logo" width="200">
5
+ <br>
6
+ <a href="https://pepy.tech/project/pyscript-programming-language">
7
+ <img src="https://static.pepy.tech/personalized-badge/pyscript-programming-language?period=total&units=NONE&left_color=GRAY&right_color=GREEN&left_text=downloads" alt="PyPI Downloads">
8
+ </a>
9
+ <a href="https://en.wikipedia.org/wiki/MIT_License">
10
+ <img src="https://img.shields.io/badge/license-MIT-orange" alt="License MIT">
11
+ </a>
12
+ <a href="https://www.python.org/">
13
+ <img src="https://img.shields.io/badge/python-3.10-yellow" alt="Python 3.10+">
14
+ </a>
5
15
  </div>
6
16
 
7
17
  PyScript is a programming language built on top of Python. It combines some syntax from Python and JavaScript, so if
@@ -0,0 +1,11 @@
1
+ # Change Log
2
+
3
+ ## [1.12.13] - 03/05/2026
4
+
5
+ ### Added
6
+ - `PysPythonFunction` is immutable.
7
+ - _etc._
8
+
9
+ ### Fixed
10
+ - Fixed some bugs.
11
+ - _etc._
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyscript-programming-language"
7
- version = "1.12.12"
7
+ version = "1.12.13"
8
8
  description = "PyScript Programming Language"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.10"
@@ -13,7 +13,7 @@ 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
16
- from .core.utils.path import getcwd, base, normpath
16
+ from .core.utils.path import getcwd, base
17
17
  from .core.version import __version__
18
18
 
19
19
  if PYGMENTS:
@@ -42,13 +42,13 @@ FORMATER_HIGHLIGHT_MAP = {
42
42
  'bbcode': HLFMT_BBCODE
43
43
  }
44
44
 
45
- EDITOR_MAP = {}
46
- for supported, name, class_editor in [
47
- (GUI_SUPPORT, 'gui', PysGUIEditor),
48
- (TERMINAL_SUPPORT, 'terminal', PysTerminalEditor)
49
- ]:
50
- if supported:
51
- EDITOR_MAP[name] = class_editor
45
+ EDITOR_MAP = {
46
+ name: cls
47
+ for support, name, cls in [
48
+ (GUI_SUPPORT, 'gui', PysGUIEditor),
49
+ (TERMINAL_SUPPORT, 'terminal', PysTerminalEditor)
50
+ ] if support
51
+ }
52
52
 
53
53
  arguments_requiring_value = {'-l', '--highlight', '-r', '--py-recursion'}
54
54
 
@@ -262,9 +262,9 @@ def clean_up() -> None:
262
262
  'PygmentsPyScriptStyle', 'PysFileBuffer', 'PysGUIEditor', 'PysTerminalEditor', 'REMAINDER', 'TERMINAL_SUPPORT',
263
263
  'Terminal256Formatter', 'TerminalFormatter', 'TerminalTrueColorFormatter', 'USE_NOTEBOOK', '__version__',
264
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'
265
+ 'argv', 'base', 'clean_up', 'condition', 'ctypes', 'execute', 'fd', 'file', 'find_module_path', 'flag',
266
+ 'getcwd', 'highlight', 'i', 'index', 'is_environ', 'kernel32', 'load_file', 'module_path', 'parser',
267
+ 'pys_highlight', 'pys_sys', 'remove_python_path'
268
268
  }:
269
269
  try:
270
270
  del g[name]
@@ -272,10 +272,9 @@ def clean_up() -> None:
272
272
  continue
273
273
 
274
274
  def load_file(path) -> PysFileBuffer:
275
- file = PysFileBuffer('', path)
276
275
  try:
277
276
  with open(path, 'r', encoding='utf-8') as file:
278
- file = PysFileBuffer(file, path)
277
+ return PysFileBuffer(file, path)
279
278
  except FileNotFoundError:
280
279
  if not (EDITOR_MAP and args.editor):
281
280
  argument_error('file', f"can't open file \"{path}\": No such file or directory")
@@ -291,7 +290,7 @@ def load_file(path) -> PysFileBuffer:
291
290
  argument_error('file', f"can't read file \"{path}\": Bad file")
292
291
  except BaseException as e:
293
292
  argument_error('file', f"file \"{path}\": Unexpected error: {e}")
294
- return file
293
+ return PysFileBuffer('', path)
295
294
 
296
295
  def execute(file: PysFileBuffer) -> None:
297
296
  global code
@@ -326,7 +325,7 @@ def execute(file: PysFileBuffer) -> None:
326
325
 
327
326
  if args.file is not None:
328
327
  argv[0] = args.file
329
- file = load_file(normpath(args.file))
328
+ file = load_file(args.file)
330
329
 
331
330
  if EDITOR_MAP and args.editor:
332
331
  try:
@@ -348,7 +347,10 @@ if args.file is not None:
348
347
  highlight(
349
348
  code=file.text,
350
349
  lexer=PygmentsPyScriptLexer(),
351
- formatter=FORMATER_PYGMENTS_MAP[args.highlight](style=PygmentsPyScriptStyle, full=True)
350
+ formatter=FORMATER_PYGMENTS_MAP[args.highlight](
351
+ style=PygmentsPyScriptStyle,
352
+ full=True
353
+ )
352
354
  )
353
355
  )
354
356
  except BaseException as e:
@@ -34,6 +34,7 @@ pys_sys.site_packages_path = SITE_PACKAGES_PATH
34
34
  pys_sys.executable = f'{base(sys.executable)} -m pyscript'
35
35
  pys_sys.ps1 = '>>> '
36
36
  pys_sys.ps2 = '... '
37
+ pys_sys._is_gil_enabled = lambda : pys_sys.gil
37
38
 
38
39
  for name in (
39
40
  'exit', 'float_info', 'float_repr_style', 'get_int_max_str_digits', 'getdefaultencoding',
@@ -10,9 +10,34 @@ from typing import Any
10
10
 
11
11
  wrapper_function = (MethodType, classmethod, staticmethod)
12
12
 
13
- if not is_environ(ENV_PYSCRIPT_NO_GIL):
14
- from threading import RLock
13
+ if is_environ(ENV_PYSCRIPT_NO_GIL):
14
+
15
+ def handle_call(object: Any, context: PysContext, position: PysPosition) -> None:
16
+ ins = isinstance
15
17
 
18
+ if ins(object, PysFunction):
19
+ code = object.__code__
20
+ code.context = context
21
+ code.position = position
22
+
23
+ elif ins(object, wrapper_function):
24
+ handle_call(object.__func__, context, position)
25
+
26
+ elif ins(object, type):
27
+ gt = getattr
28
+
29
+ method = gt(object, '__new__', None)
30
+ if method is not None:
31
+ handle_call(method, context, position)
32
+
33
+ method = gt(object, '__init__', None)
34
+ if method is not None:
35
+ handle_call(method, context, position)
36
+
37
+ GIL = pys_sys.gil = False
38
+
39
+ else:
40
+ from threading import RLock
16
41
  gil_lock = RLock()
17
42
 
18
43
  def handle_call(object: Any, context: PysContext, position: PysPosition) -> None:
@@ -38,29 +63,4 @@ if not is_environ(ENV_PYSCRIPT_NO_GIL):
38
63
  if method is not None:
39
64
  handle_call(method, context, position)
40
65
 
41
- GIL = pys_sys.gil = True
42
- else:
43
-
44
- def handle_call(object: Any, context: PysContext, position: PysPosition) -> None:
45
- ins = isinstance
46
-
47
- if ins(object, PysFunction):
48
- code = object.__code__
49
- code.context = context
50
- code.position = position
51
-
52
- elif ins(object, wrapper_function):
53
- handle_call(object.__func__, context, position)
54
-
55
- elif ins(object, type):
56
- gt = getattr
57
-
58
- method = gt(object, '__new__', None)
59
- if method is not None:
60
- handle_call(method, context, position)
61
-
62
- method = gt(object, '__init__', None)
63
- if method is not None:
64
- handle_call(method, context, position)
65
-
66
- GIL = pys_sys.gil = False
66
+ GIL = pys_sys.gil = True
@@ -693,14 +693,15 @@ def visit_TryNode(node: PysTryNode, context: PysContext) -> PysRunTimeResult:
693
693
  error = result.error
694
694
 
695
695
  if error:
696
- failure = result.failure
697
- exception = error.exception
698
-
699
696
  b_isinstance = isinstance
700
697
  b_issubclass = issubclass
701
698
  b_type = type
702
699
  b_BaseException = BaseException
703
700
 
701
+ failure = result.failure
702
+ exception = error.exception
703
+ exception_class = exception if b_isinstance(exception, b_type) else b_type(exception)
704
+
704
705
  failure(None)
705
706
 
706
707
  for (targets, tparameter), body in node.catch_cases:
@@ -729,7 +730,7 @@ def visit_TryNode(node: PysTryNode, context: PysContext) -> PysRunTimeResult:
729
730
  stop = True
730
731
  break
731
732
 
732
- if is_object_of(exception, error_class):
733
+ if b_issubclass(exception_class, error_class):
733
734
  handle_exception = True
734
735
  break
735
736
 
@@ -744,7 +745,7 @@ def visit_TryNode(node: PysTryNode, context: PysContext) -> PysRunTimeResult:
744
745
  with result:
745
746
  symbol_table = context.symbol_table
746
747
  parameter = tparameter.value
747
- symbol_table.set(parameter, error.exception)
748
+ symbol_table.set(parameter, exception)
748
749
  if should_return():
749
750
  break
750
751
 
@@ -755,8 +756,6 @@ def visit_TryNode(node: PysTryNode, context: PysContext) -> PysRunTimeResult:
755
756
  if tparameter:
756
757
  with result:
757
758
  symbol_table.remove(parameter)
758
- if should_return():
759
- break
760
759
 
761
760
  break
762
761
 
@@ -3,9 +3,11 @@ from .buffer import PysFileBuffer
3
3
  from .cache import pys_sys
4
4
  from .checks import is_blacklist_python_builtin, is_private_attribute
5
5
  from .constants import OTHER_PATH, NO_COLOR, CLASSIC_LINE_SHELL, NO_COLOR_PROMPT
6
+ from .context import PysContext
6
7
  from .exceptions import PysSignal
7
8
  from .handlers import handle_call
8
9
  from .mapping import GET_ACOLOR
10
+ from .position import PysPosition
9
11
  from .pystypes import PysFunction, PysPythonFunction, PysBuiltinFunction
10
12
  from .results import PysRunTimeResult
11
13
  from .shell import PysClassicLineShell, PysPromptToolkitLineShell, ADVANCE_LINE_SHELL_SUPPORT
@@ -37,11 +39,17 @@ pyhelp = builtins.help
37
39
  pyvars = builtins.vars
38
40
  pydir = builtins.dir
39
41
 
40
- def _supported_method(pyfunc: PysPythonFunction, object: Any, name: str, *args, **kwargs) -> tuple[bool, Any]:
42
+ def _supported_method(
43
+ context: PysContext,
44
+ position: PysPosition,
45
+ object: Any,
46
+ name: str,
47
+ *args,
48
+ **kwargs
49
+ ) -> tuple[bool, Any]:
41
50
  method = getattr(object, name, None)
42
51
  if callable(method):
43
- code = pyfunc.__code__
44
- handle_call(method, code.context, code.position)
52
+ handle_call(method, context, position)
45
53
  try:
46
54
  result = method(*args, **kwargs)
47
55
  if result is not NotImplemented:
@@ -50,7 +58,7 @@ def _supported_method(pyfunc: PysPythonFunction, object: Any, name: str, *args,
50
58
  pass
51
59
  return False, None
52
60
 
53
- def _unpack_comprehension_function(pyfunc: PysPythonFunction, function: Callable) -> Callable:
61
+ def _unpack_comprehension_function(context: PysContext, position: PysPosition, function: Callable) -> Callable:
54
62
  check = function
55
63
  final = function
56
64
  offset = 0
@@ -80,11 +88,33 @@ def _unpack_comprehension_function(pyfunc: PysPythonFunction, function: Callable
80
88
  def final(item):
81
89
  return function(*item)
82
90
 
83
- code = pyfunc.__code__
84
- handle_call(function, code.context, code.position)
85
-
91
+ handle_call(function, context, position)
86
92
  return final
87
93
 
94
+ def _pyincrement(context: PysContext, position: PysPosition, object: Any) -> Any:
95
+ if isinstance(object, real_number):
96
+ return object + 1
97
+ elif isinstance(object, sequence):
98
+ return tuple(_pyincrement(context, position, obj) for obj in object)
99
+
100
+ success, result = _supported_method(context, position, object, '__increment__')
101
+ if not success:
102
+ raise TypeError(f"bad operand type for unary ++ or increment(): {type(object).__name__!r}")
103
+
104
+ return result
105
+
106
+ def _pydecrement(context: PysContext, position: PysPosition, object: Any) -> Any:
107
+ if isinstance(object, real_number):
108
+ return object - 1
109
+ elif isinstance(object, sequence):
110
+ return tuple(_pydecrement(context, position, obj) for obj in object)
111
+
112
+ success, result = _supported_method(context, position, object, '__decrement__')
113
+ if not success:
114
+ raise TypeError(f"bad operand type for unary -- or decrement(): {type(object).__name__!r}")
115
+
116
+ return result
117
+
88
118
  class PysPrinter(Pys):
89
119
 
90
120
  def __init__(self, name: str, text: str | Any) -> None:
@@ -145,9 +175,12 @@ def require(pyfunc, name):
145
175
  name: A name or path of the module to be imported.
146
176
  """
147
177
 
148
- name, *other_components = normstr(name).split('>')
149
178
  code = pyfunc.__code__
150
179
  context = code.context
180
+ position = code.position
181
+
182
+ name, *other_components = normstr(name).split('>')
183
+
151
184
  filename = context.file.name
152
185
  path, module_path = find_module_path(filename, name)
153
186
 
@@ -202,7 +235,7 @@ def require(pyfunc, name):
202
235
  mode='exec',
203
236
  symbol_table=symtab,
204
237
  context_parent=context,
205
- context_parent_entry_position=code.position
238
+ context_parent_entry_position=position
206
239
  )
207
240
 
208
241
  if result.error:
@@ -248,14 +281,15 @@ def breakpoint(pyfunc):
248
281
  Pauses program execution and enters shell debugging mode.
249
282
  """
250
283
 
284
+ code = pyfunc.__code__
285
+ context = code.context
286
+ position = code.position
287
+
251
288
  if getattr(pys_sys, '__running_breakpoint__', False):
252
289
  raise RuntimeError("another breakpoint is still running")
253
290
 
254
291
  from .runner import pys_runner
255
292
 
256
- code = pyfunc.__code__
257
- context = code.context
258
- position = code.position
259
293
  symtab = context.symbol_table
260
294
  flags = context.flags
261
295
  colored = not (flags & NO_COLOR)
@@ -288,11 +322,8 @@ def breakpoint(pyfunc):
288
322
  print("*** Unable to clean up namespace", file=sys.stderr)
289
323
  continue
290
324
 
291
- split = ['exit'] if text == 0 else text.split()
292
- if split:
293
- command, *args = split
294
- else:
295
- command, args = '', ()
325
+ split = ('exit',) if text == 0 else text.split()
326
+ command, *args = split if split else ('', ())
296
327
 
297
328
  if command in ('c', 'continue'):
298
329
  return
@@ -429,25 +460,21 @@ def exec(pyfunc, source, globals=None):
429
460
  local scope will be used.
430
461
  """
431
462
 
432
- if not isinstance(globals, optional_mapping):
433
- raise TypeError("exec(): globals must be dict")
434
-
435
- file = PysFileBuffer(source, '<exec>')
436
463
  code = pyfunc.__code__
464
+ context = code.context
465
+ position = code.position
437
466
 
438
- if globals is None:
439
- symtab = code.context.symbol_table
440
- else:
441
- symtab, _ = new_module_namespace(symbols=globals)
467
+ if not isinstance(globals, optional_mapping):
468
+ raise TypeError("exec(): globals must be dict")
442
469
 
443
470
  from .runner import pys_runner
444
471
 
445
472
  result = pys_runner(
446
- file=file,
473
+ file=PysFileBuffer(source, '<exec>'),
447
474
  mode='exec',
448
- symbol_table=symtab,
449
- context_parent=code.context,
450
- context_parent_entry_position=code.position
475
+ symbol_table=context.symbol_table if globals is None else new_module_namespace(symbols=globals)[0],
476
+ context_parent=context,
477
+ context_parent_entry_position=position
451
478
  )
452
479
 
453
480
  if result.error:
@@ -466,25 +493,21 @@ def eval(pyfunc, source, globals=None):
466
493
  local scope will be used.
467
494
  """
468
495
 
469
- if not isinstance(globals, optional_mapping):
470
- raise TypeError("eval(): globals must be dict")
471
-
472
- file = PysFileBuffer(source, '<eval>')
473
496
  code = pyfunc.__code__
497
+ context = code.context
498
+ position = code.position
474
499
 
475
- if globals is None:
476
- symtab = code.context.symbol_table
477
- else:
478
- symtab, _ = new_module_namespace(symbols=globals)
500
+ if not isinstance(globals, optional_mapping):
501
+ raise TypeError("eval(): globals must be dict")
479
502
 
480
503
  from .runner import pys_runner
481
504
 
482
505
  result = pys_runner(
483
- file=file,
506
+ file=PysFileBuffer(source, '<eval>'),
484
507
  mode='eval',
485
- symbol_table=symtab,
486
- context_parent=code.context,
487
- context_parent_entry_position=code.position
508
+ symbol_table=context.symbol_table if globals is None else new_module_namespace(symbols=globals)[0],
509
+ context_parent=context,
510
+ context_parent_entry_position=position
488
511
  )
489
512
 
490
513
  if result.error:
@@ -508,16 +531,22 @@ def ce(pyfunc, a, b, *, rel_tol=1e-9, abs_tol=0):
508
531
  abs_tol: maximum difference for being considered "close", regardless of the magnitude of the input values.
509
532
  """
510
533
 
534
+ code = pyfunc.__code__
535
+ context = code.context
536
+ position = code.position
537
+
511
538
  if isinstance(a, real_number) and isinstance(b, real_number):
512
539
  return isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol)
513
540
 
514
- success, result = _supported_method(pyfunc, a, '__ce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
541
+ success, result = _supported_method(context, position, a, '__ce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
515
542
  if not success:
516
- success, result = _supported_method(pyfunc, b, '__ce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
543
+ success, result = _supported_method(context, position, b, '__ce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
517
544
  if not success:
518
- success, result = _supported_method(pyfunc, a, '__nce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
545
+ success, result = _supported_method(context, position, a, '__nce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
519
546
  if not success:
520
- success, result = _supported_method(pyfunc, b, '__nce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
547
+ success, result = _supported_method(
548
+ context, position, b, '__nce__', a, rel_tol=rel_tol, abs_tol=abs_tol
549
+ )
521
550
  if not success:
522
551
  raise TypeError(
523
552
  f"unsupported operand type(s) for ~= or ce(): {type(a).__name__!r} and {type(b).__name__!r}"
@@ -542,16 +571,20 @@ def nce(pyfunc, a, b, *, rel_tol=1e-9, abs_tol=0):
542
571
  abs_tol: maximum difference for being considered "close", regardless of the magnitude of the input values.
543
572
  """
544
573
 
574
+ code = pyfunc.__code__
575
+ context = code.context
576
+ position = code.position
577
+
545
578
  if isinstance(a, real_number) and isinstance(b, real_number):
546
579
  return not isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol)
547
580
 
548
- success, result = _supported_method(pyfunc, a, '__nce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
581
+ success, result = _supported_method(context, position, a, '__nce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
549
582
  if not success:
550
- success, result = _supported_method(pyfunc, b, '__nce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
583
+ success, result = _supported_method(context, position, b, '__nce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
551
584
  if not success:
552
- success, result = _supported_method(pyfunc, a, '__ce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
585
+ success, result = _supported_method(context, position, a, '__ce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
553
586
  if not success:
554
- success, result = _supported_method(pyfunc, b, '__ce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
587
+ success, result = _supported_method(context, position, b, '__ce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
555
588
  if not success:
556
589
  raise TypeError(
557
590
  f"unsupported operand type(s) for ~! or nce(): {type(a).__name__!r} and {type(b).__name__!r}"
@@ -573,16 +606,8 @@ def increment(pyfunc, object):
573
606
  __increment__ method, which if unsuccessful will throw a TypeError.
574
607
  """
575
608
 
576
- if isinstance(object, real_number):
577
- return object + 1
578
- elif isinstance(object, sequence):
579
- return tuple(pyincrement(pyfunc, obj) for obj in object)
580
-
581
- success, result = _supported_method(pyfunc, object, '__increment__')
582
- if not success:
583
- raise TypeError(f"bad operand type for unary ++ or increment(): {type(object).__name__!r}")
584
-
585
- return result
609
+ code = pyfunc.__code__
610
+ return _pyincrement(code.context, code.position, object)
586
611
 
587
612
  @PysBuiltinFunction
588
613
  def decrement(pyfunc, object):
@@ -597,16 +622,8 @@ def decrement(pyfunc, object):
597
622
  call the __decrement__ method, which if unsuccessful will throw a TypeError.
598
623
  """
599
624
 
600
- if isinstance(object, real_number):
601
- return object - 1
602
- elif isinstance(object, sequence):
603
- return tuple(pydecrement(pyfunc, obj) for obj in object)
604
-
605
- success, result = _supported_method(pyfunc, object, '__decrement__')
606
- if not success:
607
- raise TypeError(f"bad operand type for unary -- or decrement(): {type(object).__name__!r}")
608
-
609
- return result
625
+ code = pyfunc.__code__
626
+ return _pydecrement(code.context, code.position, object)
610
627
 
611
628
  @PysBuiltinFunction
612
629
  def unpack(pyfunc, function, args=(), kwargs={}):
@@ -644,19 +661,20 @@ def comprehension(pyfunc, init, wrap, condition=None):
644
661
  condition: The function that filters the iteration (Unpack per-iteration if parameter is more than 1).
645
662
  """
646
663
 
664
+ code = pyfunc.__code__
665
+ context = code.context
666
+ position = code.position
667
+
647
668
  if not callable(wrap):
648
669
  raise TypeError("comprehension(): wrap must be callable")
649
670
  if not (condition is None or callable(condition)):
650
671
  raise TypeError("comprehension(): condition must be callable")
651
672
 
652
673
  return map(
653
- _unpack_comprehension_function(pyfunc, wrap),
654
- init if condition is None else filter(_unpack_comprehension_function(pyfunc, condition), init)
674
+ _unpack_comprehension_function(context, position, wrap),
675
+ init if condition is None else filter(_unpack_comprehension_function(context, position, condition), init)
655
676
  )
656
677
 
657
- pyincrement = increment.__func__
658
- pydecrement = decrement.__func__
659
-
660
678
  pys_builtins = ModuleType(
661
679
  'builtins',
662
680
  "Built-in functions, types, exceptions, and other objects.\n\n"
@@ -5,7 +5,8 @@ from .nodes import PysNode
5
5
  from .position import PysPosition
6
6
  from .results import PysRunTimeResult
7
7
  from .symtab import PysSymbolTable
8
- from .utils.generic import dinit, drepr, dor, dsetitem, ddelitem, ditems
8
+ from .utils.decorators import immutable
9
+ from .utils.generic import setimuattr, dinit, drepr, dor, dsetitem, ddelitem, ditems
9
10
  from .utils.similarity import get_closest
10
11
  from .utils.string import join
11
12
 
@@ -120,6 +121,8 @@ class PysFunction(PysObject):
120
121
 
121
122
  def __call__(self, *args, **kwargs) -> Any:
122
123
  code = self.__code__
124
+ context = code.context
125
+ position = code.position
123
126
 
124
127
  b_zip = zip
125
128
  b_len = len
@@ -152,8 +155,8 @@ class PysFunction(PysObject):
152
155
  result.failure(
153
156
  PysTraceback(
154
157
  TypeError(f"{self.__qualname__}() got multiple values for argument {name!r}"),
155
- code.context,
156
- code.position
158
+ context,
159
+ position
157
160
  )
158
161
  )
159
162
  )
@@ -168,8 +171,8 @@ class PysFunction(PysObject):
168
171
  TypeError(
169
172
  f"{self.__qualname__}() got an unexpected keyword argument {name!r}{hint_message}"
170
173
  ),
171
- code.context,
172
- code.position
174
+ context,
175
+ position
173
176
  )
174
177
  )
175
178
  )
@@ -192,8 +195,8 @@ class PysFunction(PysObject):
192
195
  f"{self.__qualname__}() missing {total_missing} required positional argument"
193
196
  f"{'' if total_missing == 1 else 's'}: {join(missing_arguments, conjunction='and')}"
194
197
  ),
195
- code.context,
196
- code.position
198
+ context,
199
+ position
197
200
  )
198
201
  )
199
202
  )
@@ -211,8 +214,8 @@ class PysFunction(PysObject):
211
214
  f"{self.__qualname__}() takes {code_parameters_length} positional argument"
212
215
  f"{'' if code_parameters_length == 1 else 's'} but {given_arguments} were given"
213
216
  ),
214
- code.context,
215
- code.position
217
+ context,
218
+ position
216
219
  )
217
220
  )
218
221
  )
@@ -227,8 +230,8 @@ class PysFunction(PysObject):
227
230
  name=self.__name__,
228
231
  qualname=self.__qualname__,
229
232
  symbol_table=symbol_table,
230
- parent=code.context,
231
- parent_entry_position=code.position
233
+ parent=context,
234
+ parent_entry_position=position
232
235
  )
233
236
  )
234
237
  )
@@ -238,30 +241,37 @@ class PysFunction(PysObject):
238
241
  return result.func_return_value
239
242
  raise PysSignal(result)
240
243
 
244
+ @immutable
241
245
  class PysPythonFunction(PysFunction):
242
246
 
243
247
  def __init__(self, func: Callable) -> None:
244
248
  # circular import problem solved
245
249
  from .handlers import handle_call
246
250
 
247
- self.__func__ = func
248
- self.__name__ = getattr(func, '__name__', '<function>')
249
- self.__qualname__ = getattr(func, '__qualname__', '<function>')
250
- self.__module__ = getattr(func, '__module__', 'pyscript')
251
- self.__doc__ = getattr(func, '__doc__', None)
252
- self.__code__ = PysCode(
251
+ setimuattr(self, '__func__', func)
252
+ setimuattr(self, '__name__', getattr(func, '__name__', '<function>'))
253
+ setimuattr(self, '__qualname__', getattr(func, '__qualname__', '<function>'))
254
+ setimuattr(self, '__module__', getattr(func, '__module__', 'pyscript'))
255
+ setimuattr(self, '__doc__', getattr(func, '__doc__', None))
256
+ setimuattr(self, '__code__', PysCode(
253
257
  context=None,
254
258
  position=None,
255
259
  handle_call=handle_call
256
- )
260
+ ))
257
261
 
258
262
  def __repr__(self) -> str:
259
263
  return f'<python function {self.__qualname__} at 0x{id(self):016X}>'
260
264
 
265
+ def __get__(self, instance: Any | None, owner: type) -> 'PysPythonFunction':
266
+ return self
267
+
261
268
  def __call__(self, *args, **kwargs) -> Any:
262
- func = self.__func__
263
269
  code = self.__code__
264
- code.handle_call(func, code.context, code.position)
270
+ context = code.context
271
+ position = code.position
272
+
273
+ func = self.__func__
274
+ code.handle_call(func, context, position)
265
275
  return func(self, *args, **kwargs)
266
276
 
267
277
  class PysBuiltinFunction(PysPythonFunction):
@@ -255,9 +255,7 @@ try:
255
255
  if os.path.isfile(HISTORY_PATH):
256
256
 
257
257
  def add_to_string():
258
- line = '\n'.join(lines)
259
- if line:
260
- strings.append(line)
258
+ strings.append('\n'.join(lines))
261
259
  lines.clear()
262
260
 
263
261
  with open(HISTORY_PATH, 'r', encoding='utf-8') as file:
@@ -267,8 +265,7 @@ try:
267
265
  if line.startswith('\x1e'):
268
266
  add_to_string()
269
267
  line = line[1:]
270
- if line:
271
- lines.append(line)
268
+ lines.append(line)
272
269
 
273
270
  if lines:
274
271
  add_to_string()
@@ -33,7 +33,6 @@ USE_NOTEBOOK = False
33
33
 
34
34
  try:
35
35
  from IPython import get_ipython
36
-
37
36
  if type(get_ipython()).__name__ in (
38
37
  'ZMQInteractiveShell', # Jupyter Notebook / Lab
39
38
  'Shell', # Google Colab
@@ -43,7 +42,6 @@ try:
43
42
  def clear_shell() -> None:
44
43
  clear_output()
45
44
  USE_NOTEBOOK = True
46
-
47
45
  except:
48
46
  pass
49
47
 
@@ -6,8 +6,8 @@ from types import MappingProxyType
6
6
 
7
7
  import re
8
8
 
9
- __version__ = '1.12.12'
10
- __date__ = '29 April 2026, 20:00 UTC+7'
9
+ __version__ = '1.12.13'
10
+ __date__ = '03 May 2026, 19:40 UTC+7'
11
11
  __author__ = ('azzammuhyala',)
12
12
 
13
13
  version = pys_sys.version = f'{__version__} ({__date__})'
@@ -8,8 +8,9 @@ func default_input() {
8
8
  }
9
9
 
10
10
  func default_output(byte) {
11
- sys.stdout.write(chr(byte))
12
- sys.stdout.flush()
11
+ stdout = sys.stdout
12
+ stdout.write(chr(byte))
13
+ stdout.flush()
13
14
  }
14
15
 
15
16
  class BFInterpreter {
@@ -40,7 +41,6 @@ class BFInterpreter {
40
41
 
41
42
  self.running = false
42
43
 
43
- self._tokenCursor = -1
44
44
  self._tokens = tokens = []
45
45
  self._bracketMap = {}
46
46
 
@@ -129,6 +129,7 @@ class BFInterpreter {
129
129
  self.running = true
130
130
  self.memory = [0]
131
131
  self.pointer = 0
132
+ self._tokenCursor = -1
132
133
 
133
134
  if (self.cells is not none)
134
135
  self.memory *= self.cells
@@ -204,7 +205,7 @@ class BFInterpreter {
204
205
  self.running = false
205
206
 
206
207
  if (cleanUp)
207
- del self.memory, self.pointer
208
+ del self.memory, self.pointer, self._tokenCursor
208
209
  }
209
210
 
210
211
  }
@@ -24,6 +24,14 @@ def untokenize(iterable: Iterable[PysToken]) -> str:
24
24
  newline = True
25
25
  brackets_stack = 0
26
26
 
27
+ T_NULL = TOKENS['NULL']
28
+ T_NEWLINE = TOKENS['NEWLINE']
29
+ T_KEYWORD = TOKENS['KEYWORD']
30
+ T_IDENTIFIER = TOKENS['IDENTIFIER']
31
+ T_LITERAL = frozenset([TOKENS['NUMBER'], TOKENS['STRING']])
32
+ T_COMMENT = TOKENS['COMMENT']
33
+ T_NONE = TOKENS['NONE']
34
+
27
35
  for i, token in enumerate(iterable):
28
36
  type = token.type
29
37
  value = token.value
@@ -34,10 +42,10 @@ def untokenize(iterable: Iterable[PysToken]) -> str:
34
42
  except:
35
43
  value = token_value_error
36
44
 
37
- if type == TOKENS['NULL']:
45
+ if type == T_NULL:
38
46
  break
39
47
 
40
- elif type == TOKENS['NEWLINE']:
48
+ elif type == T_NEWLINE:
41
49
  stack = (
42
50
  brackets_stack - 1
43
51
  if brackets_stack > 0 and is_right_bracket(get_sequence(iterable, i + 1, token).type) else
@@ -48,23 +56,23 @@ def untokenize(iterable: Iterable[PysToken]) -> str:
48
56
  add_space = False
49
57
  continue
50
58
 
51
- elif type == TOKENS['KEYWORD']:
59
+ elif type == T_KEYWORD:
52
60
  parts.append(f'{" " if add_space else ""}{value}')
53
61
  add_space = True
54
62
 
55
- elif type == TOKENS['IDENTIFIER']:
63
+ elif type == T_IDENTIFIER:
56
64
  parts.append(f'${value}' if is_keyword(value) else f'{" " if add_space else ""}{value}')
57
65
  add_space = True
58
66
 
59
- elif type in (TOKENS['NUMBER'], TOKENS['STRING']):
67
+ elif type in T_LITERAL:
60
68
  parts.append(f'{" " if add_space else ""}{value!r}')
61
69
  add_space = True
62
70
 
63
- elif type == TOKENS['COMMENT']:
71
+ elif type == T_COMMENT:
64
72
  parts.append(f'{"" if newline else " "}#{value}')
65
73
  add_space = False
66
74
 
67
- elif type == TOKENS['NONE']:
75
+ elif type == T_NONE:
68
76
  parts.append(token.position.file.text[token.position.start:token.position.end])
69
77
  add_space = True
70
78
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.12.12
3
+ Version: 1.12.13
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://azzammuhyala.github.io/pyscript
6
6
  Author: azzammuhyala
@@ -30,10 +30,20 @@ Dynamic: author
30
30
  Dynamic: home-page
31
31
  Dynamic: requires-python
32
32
 
33
- # PyScript 🐍🟨🟦⬛
33
+ # PyScript
34
34
 
35
35
  <div align="center">
36
36
  <img src="https://github.com/azzammuhyala/pyscript/blob/main/PyScript.png?raw=true" alt="PyScript Logo" width="200">
37
+ <br>
38
+ <a href="https://pepy.tech/project/pyscript-programming-language">
39
+ <img src="https://static.pepy.tech/personalized-badge/pyscript-programming-language?period=total&units=NONE&left_color=GRAY&right_color=GREEN&left_text=downloads" alt="PyPI Downloads">
40
+ </a>
41
+ <a href="https://en.wikipedia.org/wiki/MIT_License">
42
+ <img src="https://img.shields.io/badge/license-MIT-orange" alt="License MIT">
43
+ </a>
44
+ <a href="https://www.python.org/">
45
+ <img src="https://img.shields.io/badge/python-3.10-yellow" alt="Python 3.10+">
46
+ </a>
37
47
  </div>
38
48
 
39
49
  PyScript is a programming language built on top of Python. It combines some syntax from Python and JavaScript, so if
@@ -9,7 +9,7 @@ with open('./README.md', 'r', encoding='utf-8') as file:
9
9
 
10
10
  setup(
11
11
  name='pyscript-programming-language',
12
- version='1.12.12',
12
+ version='1.12.13',
13
13
  description='PyScript Programming Language',
14
14
  long_description=long_description,
15
15
  long_description_content_type='text/markdown',
@@ -1,10 +0,0 @@
1
- # Change Log
2
-
3
- ## [1.12.12] - 29/04/2026
4
-
5
- ### Added
6
- - Saves screen geometry in gui editor.
7
-
8
- ### Fixed
9
- - Fixed some bugs.
10
- - _etc._