pyscript-programming-language 1.13.1__tar.gz → 1.13.3__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.13.1 → pyscript_programming_language-1.13.3}/PKG-INFO +4 -4
  2. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/README.md +1 -1
  3. pyscript_programming_language-1.13.3/changelog.md +13 -0
  4. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyproject.toml +2 -2
  5. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/__main__.py +11 -10
  6. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/cache.py +19 -5
  7. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/checks.py +3 -3
  8. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/exceptions.py +1 -0
  9. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/highlight.py +1 -1
  10. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/interpreter.py +5 -23
  11. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/lexer.py +15 -10
  12. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/mapping.py +14 -2
  13. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/nodes.py +1 -0
  14. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/parser.py +37 -6
  15. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/pysbuiltins.py +5 -1
  16. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/results.py +1 -0
  17. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/shell.py +3 -2
  18. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/token.py +2 -1
  19. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/utils/debug.py +5 -5
  20. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/utils/module.py +3 -1
  21. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/version.py +3 -3
  22. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/ast/ast_literal_eval.py +12 -9
  23. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/site.pys +2 -2
  24. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/tokenize/tok_untokenize.py +3 -3
  25. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript_programming_language.egg-info/PKG-INFO +4 -4
  26. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/setup.py +2 -2
  27. pyscript_programming_language-1.13.1/changelog.md +0 -12
  28. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/MANIFEST.in +0 -0
  29. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/__init__.py +0 -0
  30. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/__init__.pyi +0 -0
  31. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/__init__.py +0 -0
  32. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/analyzer.py +0 -0
  33. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/bases.py +0 -0
  34. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/buffer.py +0 -0
  35. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/constants.py +0 -0
  36. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/context.py +0 -0
  37. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/editor/__init__.py +0 -0
  38. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/editor/bases.py +0 -0
  39. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/editor/gui.py +0 -0
  40. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/editor/terminal.py +0 -0
  41. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/handlers.py +0 -0
  42. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/position.py +0 -0
  43. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/pystypes.py +0 -0
  44. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/runner.py +0 -0
  45. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/symtab.py +0 -0
  46. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/utils/__init__.py +0 -0
  47. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/utils/ansi.py +0 -0
  48. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/utils/decorators.py +0 -0
  49. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/utils/generic.py +0 -0
  50. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/utils/path.py +0 -0
  51. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/utils/similarity.py +0 -0
  52. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/core/utils/string.py +0 -0
  53. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/__hello__.pys +0 -0
  54. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/ansi.pys +0 -0
  55. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/ast/__init__.pys +0 -0
  56. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/ast/ast_dump.py +0 -0
  57. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/ast/ast_unparse.py +0 -0
  58. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/ast/ast_walk.py +0 -0
  59. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/brainfuck.pys +0 -0
  60. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/code.pys +0 -0
  61. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/dis.pys +0 -0
  62. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/explorer.pys +0 -0
  63. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/fpstimer/__init__.pys +0 -0
  64. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/fpstimer/py_fpstimer.py +0 -0
  65. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/getch/__init__.pys +0 -0
  66. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/getch/py_getch.py +0 -0
  67. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/history.pys +0 -0
  68. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/inspect.pys +0 -0
  69. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/jsdict.pys +0 -0
  70. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/keyword.pys +0 -0
  71. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/opcode.pys +0 -0
  72. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/parser.pys +0 -0
  73. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/pdisplay.pys +0 -0
  74. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/symtable.pys +0 -0
  75. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/token.pys +0 -0
  76. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/lib/tokenize/__init__.pys +0 -0
  77. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/other/.nomedia +0 -0
  78. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/other/PyScript.ico +0 -0
  79. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/other/copyright +0 -0
  80. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/other/credits +0 -0
  81. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/other/license +0 -0
  82. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/site-packages/this.pys +0 -0
  83. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript/this.py +0 -0
  84. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
  85. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  86. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript_programming_language.egg-info/requires.txt +0 -0
  87. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  88. {pyscript_programming_language-1.13.1 → pyscript_programming_language-1.13.3}/setup.cfg +0 -0
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.13.1
3
+ Version: 1.13.3
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://azzammuhyala.github.io/pyscript
6
- Author: Azzam Muhyala
7
- Author-email: Azzam Muhyala <azzammuhyala@gmail.com>
6
+ Author: AzzamMuhyala
7
+ Author-email: AzzamMuhyala <azzammuhyala@gmail.com>
8
8
  License-Expression: MIT
9
9
  Project-URL: Homepage, https://azzammuhyala.github.io/pyscript
10
10
  Project-URL: Documentation, https://azzammuhyala.github.io/pyscript
@@ -145,7 +145,7 @@ Familiar? There it is!
145
145
  - **optional**: Not required, but if it is present, some features can be used without issue.
146
146
 
147
147
  ## Highlights 🎨
148
- - [PyScript plugin for Acode (Ace Editor)](https://github.com/azzammuhyala/pyscript/releases/download/v1.13.1/plugin.zip)
148
+ - [PyScript plugin for Acode (Ace Editor)](https://github.com/azzammuhyala/pyscript/releases/download/v1.13.3/plugin-1.0.2.zip)
149
149
  - [PyScript nano for Linux](https://github.com/azzammuhyala/pyscript/tree/main/highlight/nano)
150
150
  - [PyScript extension for VSCode](https://marketplace.visualstudio.com/items?itemName=azzammuhyala.pyslang)
151
151
 
@@ -113,7 +113,7 @@ Familiar? There it is!
113
113
  - **optional**: Not required, but if it is present, some features can be used without issue.
114
114
 
115
115
  ## Highlights 🎨
116
- - [PyScript plugin for Acode (Ace Editor)](https://github.com/azzammuhyala/pyscript/releases/download/v1.13.1/plugin.zip)
116
+ - [PyScript plugin for Acode (Ace Editor)](https://github.com/azzammuhyala/pyscript/releases/download/v1.13.3/plugin-1.0.2.zip)
117
117
  - [PyScript nano for Linux](https://github.com/azzammuhyala/pyscript/tree/main/highlight/nano)
118
118
  - [PyScript extension for VSCode](https://marketplace.visualstudio.com/items?itemName=azzammuhyala.pyslang)
119
119
 
@@ -0,0 +1,13 @@
1
+ # Change Logs
2
+
3
+ ## [1.13.3] - 31/05/2026
4
+
5
+ ### Added
6
+ - Parsing of number literals, string literals, and identifiers is now interned and stored in `sys.interns`.
7
+ - Warning messages in the parser about the use of the `is` and `is not` operators on number and string literals.
8
+ - _etc._
9
+
10
+ ### Fixed
11
+ - Improved lexer and highlighting on numbers.
12
+ - Fixed some bugs.
13
+ - _etc._
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyscript-programming-language"
7
- version = "1.13.1"
7
+ version = "1.13.3"
8
8
  description = "PyScript Programming Language"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.10"
11
11
  license = "MIT"
12
12
 
13
13
  authors = [
14
- { name = "Azzam Muhyala", email = "azzammuhyala@gmail.com" }
14
+ { name = "AzzamMuhyala", email = "azzammuhyala@gmail.com" }
15
15
  ]
16
16
 
17
17
  keywords = [
@@ -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
16
+ from .core.utils.path import getcwd, base, normpath
17
17
  from .core.version import __version__
18
18
 
19
19
  if PYGMENTS:
@@ -272,24 +272,25 @@ def clean_up() -> None:
272
272
  continue
273
273
 
274
274
  def load_file(path) -> PysFileBuffer:
275
+ normalized = normpath(path)
275
276
  try:
276
- with open(path, 'r', encoding='utf-8') as file:
277
- return PysFileBuffer(file, path)
277
+ with open(normalized, 'r', encoding='utf-8') as file:
278
+ return PysFileBuffer(file, normalized)
278
279
  except FileNotFoundError:
279
280
  if not (EDITOR_MAP and args.editor):
280
- argument_error('file', f"can't open file \"{path}\": No such file or directory")
281
+ argument_error('file', f"can't open file \"{normalized}\": No such file or directory")
281
282
  except PermissionError:
282
- argument_error('file', f"can't open file \"{path}\": Permission denied")
283
+ argument_error('file', f"can't open file \"{normalized}\": Permission denied")
283
284
  except IsADirectoryError:
284
- argument_error('file', f"can't open file \"{path}\": Path is not a file")
285
+ argument_error('file', f"can't open file \"{normalized}\": Path is not a file")
285
286
  except NotADirectoryError:
286
- argument_error('file', f"can't open file \"{path}\": Attempting to access directory from file")
287
+ argument_error('file', f"can't open file \"{normalized}\": Attempting to access directory from file")
287
288
  except (OSError, IOError):
288
- argument_error('file', f"can't open file \"{path}\": Attempting to access a system directory or file")
289
+ argument_error('file', f"can't open file \"{normalized}\": Attempting to access a system directory or file")
289
290
  except UnicodeDecodeError:
290
- argument_error('file', f"can't read file \"{path}\": Bad file")
291
+ argument_error('file', f"can't read file \"{normalized}\": Bad file")
291
292
  except BaseException as e:
292
- argument_error('file', f"file \"{path}\": Unexpected error: {e}")
293
+ argument_error('file', f"file \"{normalized}\": Unexpected error: {e}")
293
294
  return PysFileBuffer('', path)
294
295
 
295
296
  def execute(file: PysFileBuffer) -> None:
@@ -2,12 +2,14 @@ from .bases import Pys
2
2
  from .constants import PYSCRIPT_PATH, CORE_PATH, LIBRARIES_PATH, SITE_PACKAGES_PATH, CONFIGURATIONS_PATH, DEFAULT
3
3
  from .utils.debug import print_display, print_traceback, clear_shell
4
4
  from .utils.decorators import inheritable, singleton
5
+ from .utils.module import get_module_candidate
5
6
  from .utils.path import base
6
7
 
7
8
  from types import ModuleType
8
- from typing import Literal
9
+ from typing import Any, Literal
9
10
 
10
11
  import sys
12
+ import os
11
13
 
12
14
  pys_sys = ModuleType(
13
15
  'sys',
@@ -18,9 +20,15 @@ pys_sys = ModuleType(
18
20
 
19
21
  pys_sys.__running_shell__ = False
20
22
  pys_sys.__running_breakpoint__ = False
23
+ pys_sys.builtin_module_names = tuple(
24
+ os.path.splitext(module)[0]
25
+ for module in os.listdir(LIBRARIES_PATH)
26
+ if get_module_candidate(os.path.join(LIBRARIES_PATH, module)) is not None
27
+ )
21
28
  pys_sys.path = [LIBRARIES_PATH, SITE_PACKAGES_PATH]
22
29
  pys_sys.loading_modules = set()
23
30
  pys_sys.modules = {}
31
+ pys_sys.interns = {}
24
32
  pys_sys.singletons = {}
25
33
  pys_sys.argv = ['']
26
34
  pys_sys.flags = DEFAULT
@@ -32,20 +40,26 @@ pys_sys.core_path = CORE_PATH
32
40
  pys_sys.libraries_path = LIBRARIES_PATH
33
41
  pys_sys.site_packages_path = SITE_PACKAGES_PATH
34
42
  pys_sys.configurations_path = CONFIGURATIONS_PATH
43
+ pys_sys.platlibdir = base(LIBRARIES_PATH)
35
44
  pys_sys.executable = f'{base(sys.executable)} -m pyscript'
36
45
  pys_sys.ps1 = '>>> '
37
46
  pys_sys.ps2 = '... '
38
47
  pys_sys._is_gil_enabled = lambda : pys_sys.gil
39
48
 
40
49
  for name in (
41
- 'exit', 'float_info', 'float_repr_style', 'get_int_max_str_digits', 'getdefaultencoding',
42
- 'getfilesystemencodeerrors', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getsizeof',
43
- 'gettotalrefcount', 'hash_info', 'hexversion', 'int_info', 'intern', 'maxsize', 'maxunicode', 'platform',
44
- 'set_int_max_str_digits', 'setrecursionlimit', 'stderr', 'stdin', 'stdout', 'thread_info'
50
+ '_clear_internal_caches', '_is_immortal', '_is_interned', 'byteorder', 'exit', 'float_info', 'float_repr_style',
51
+ 'get_int_max_str_digits', 'getallocatedblocks', 'getdefaultencoding', 'getfilesystemencodeerrors',
52
+ 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
53
+ 'getunicodeinternedsize', 'hash_info', 'hexversion', 'int_info', 'intern', 'is_finalizing', 'maxsize', 'maxunicode',
54
+ 'platform', 'set_int_max_str_digits', 'setrecursionlimit', 'setswitchinterval', 'stderr', 'stdin', 'stdout',
55
+ 'thread_info'
45
56
  ):
46
57
  if hasattr(sys, name):
47
58
  setattr(pys_sys, name, getattr(sys, name))
48
59
 
60
+ def intern_object(object: Any) -> Any:
61
+ return pys_sys.interns.setdefault((type(object), object), object)
62
+
49
63
  # sentinel
50
64
  @singleton
51
65
  @inheritable
@@ -20,9 +20,9 @@ is_sequence = frozenset([
20
20
  PysSetNode, PysListNode, PysTupleNode
21
21
  ]).__contains__
22
22
 
23
- is_constant = frozenset([
24
- PysKeywordNode, PysDebugNode
25
- ])
23
+ is_literal = frozenset([
24
+ PysNumberNode, PysStringNode
25
+ ]).__contains__
26
26
 
27
27
  is_keyword = frozenset(KEYWORDS).__contains__
28
28
  is_constant_keyword = frozenset(CONSTANT_KEYWORDS).__contains__
@@ -7,6 +7,7 @@ from .utils.string import indent
7
7
  from typing import TYPE_CHECKING, Optional
8
8
 
9
9
  if TYPE_CHECKING:
10
+ # circular import problem solved
10
11
  from .context import PysContext
11
12
  from .position import PysPosition
12
13
  from .results import PysRunTimeResult
@@ -204,7 +204,7 @@ try:
204
204
  bygroups(Number.Affix, Number.Hex, Number.Affix)
205
205
  ),
206
206
  (
207
- rf'\b((?:(?:{_integer})?\.{_integer}|{_integer}\.){_scientific}?)({_imaginary})\b',
207
+ rf'(?<![\w.])((?:(?:{_integer})?\.{_integer}|{_integer}\.){_scientific}?)({_imaginary})(?![\w.])',
208
208
  bygroups(Number.Float, Number.Affix)
209
209
  ),
210
210
  (
@@ -6,7 +6,7 @@ from .checks import is_sequence, is_equal, is_public_attribute
6
6
  from .context import PysContext, PysClassContext
7
7
  from .exceptions import PysTraceback
8
8
  from .handlers import handle_call
9
- from .mapping import GET_BINARY_FUNCTION, GET_UNARY_FUNCTION
9
+ from .mapping import GET_BINARY_FUNCTION, GET_UNARY_FUNCTION, GET_VALUE_FROM_CONSTANT_KEYWORDS
10
10
  from .nodes import *
11
11
  from .pysbuiltins import ce, nce, increment, decrement
12
12
  from .pystypes import PysFunction
@@ -22,27 +22,12 @@ from typing import Any, Callable
22
22
 
23
23
  T_STRING = TOKENS['STRING']
24
24
  T_AND = TOKENS['DOUBLE_AMPERSAND']
25
+ T_INCREMENT = TOKENS['DOUBLE_PLUS']
25
26
  T_NULLISH = TOKENS['DOUBLE_QUESTION']
26
27
  T_OR = TOKENS['DOUBLE_PIPE']
27
28
  T_CE = TOKENS['EQUAL_TILDE']
28
29
  T_NCE = TOKENS['EXCLAMATION_TILDE']
29
30
 
30
- get_incremental_function = {
31
- TOKENS['DOUBLE_PLUS']: increment,
32
- TOKENS['DOUBLE_MINUS']: decrement
33
- }.__getitem__
34
-
35
- get_value_from_keyword = {
36
- 'True': True,
37
- 'False': False,
38
- 'None': None,
39
- 'true': True,
40
- 'false': False,
41
- 'nil': None,
42
- 'none': None,
43
- 'null': None
44
- }.__getitem__
45
-
46
31
  def visit_NumberNode(node: PysNumberNode, context: PysContext) -> PysRunTimeResult:
47
32
  return PysRunTimeResult().success(node.value.value)
48
33
 
@@ -50,7 +35,7 @@ def visit_StringNode(node: PysStringNode, context: PysContext) -> PysRunTimeResu
50
35
  return PysRunTimeResult().success(node.value.value)
51
36
 
52
37
  def visit_KeywordNode(node: PysKeywordNode, context: PysContext) -> PysRunTimeResult:
53
- return PysRunTimeResult().success(get_value_from_keyword(node.name.value))
38
+ return PysRunTimeResult().success(GET_VALUE_FROM_CONSTANT_KEYWORDS(node.name.value))
54
39
 
55
40
  def visit_DebugNode(node: PysDebugNode, context: PysContext) -> PysRunTimeResult:
56
41
  return PysRunTimeResult().success(True if context.flags & DEBUG else False)
@@ -381,18 +366,15 @@ def visit_IncrementalNode(node: PysIncrementalNode, context: PysContext) -> PysR
381
366
  result._context = context
382
367
  result._position = nposition = node.position
383
368
  with result:
384
- function = get_incremental_function(node.operand.type)
369
+ function = increment if node.operand.type == T_INCREMENT else decrement
385
370
  handle_call(function, context, nposition)
386
371
  increast_value = function(value)
387
372
 
388
- if node.operand_position == 'left':
389
- value = increast_value
390
-
391
373
  register(visit_declaration_from_AssignmentNode(ntarget, context, increast_value))
392
374
  if should_return():
393
375
  return result
394
376
 
395
- return result.success(value)
377
+ return result.success(increast_value if node.operand_position == 'left' else value)
396
378
 
397
379
  return result
398
380
 
@@ -1,5 +1,6 @@
1
1
  from .bases import Pys
2
2
  from .buffer import PysFileBuffer
3
+ from .cache import intern_object
3
4
  from .checks import is_keyword
4
5
  from .constants import DEFAULT, SILENT, LEXER_HIGHLIGHT, NO_COLOR
5
6
  from .context import PysContext
@@ -299,6 +300,7 @@ class PysLexer(Pys):
299
300
  if self.current_character == '_':
300
301
  is_underscore = True
301
302
  self.advance()
303
+ continue
302
304
 
303
305
  elif self.current_character == '.' and not is_scientific and format is int:
304
306
  format = float
@@ -334,7 +336,7 @@ class PysLexer(Pys):
334
336
 
335
337
  break
336
338
 
337
- elif self.character_in('eE') and not is_scientific:
339
+ if self.character_in('eE') and not is_scientific:
338
340
  format = float
339
341
  is_scientific = True
340
342
 
@@ -382,20 +384,23 @@ class PysLexer(Pys):
382
384
  elif format is int:
383
385
  result = int(number)
384
386
 
385
- self.add_token(TOKENS['NUMBER'], start, complex(0, result) if is_complex else result)
387
+ self.add_token(TOKENS['NUMBER'], start, intern_object(complex(0, result) if is_complex else result))
386
388
 
387
389
  except (ValueError, OverflowError):
388
- integer_to_string_limit = (
389
- f'({sys.get_int_max_str_digits()} digits) '
390
+ integer_to_string_limit, other_message = (
391
+ (
392
+ f"({sys.get_int_max_str_digits()} digits) ",
393
+ "; use sys.set_int_max_str_digits() to increase the limit - Consider hexadecimal for huge integer "
394
+ "literals to avoid decimal conversion limits"
395
+ )
390
396
  if hasattr(sys, 'get_int_max_str_digits') else
391
- ''
397
+ ('', '')
392
398
  )
393
399
 
394
400
  self.throw(
395
401
  start, self.index,
396
402
  f"Exceeds the limit {integer_to_string_limit}for integer string conversion: "
397
- f"value has {len(number)} digits; use sys.set_int_max_str_digits() to increase the limit - "
398
- "Consider hexadecimal for huge integer literals to avoid decimal conversion limits."
403
+ f"value has {len(number)} digits{other_message}."
399
404
  )
400
405
 
401
406
  def make_string(self) -> None:
@@ -560,7 +565,7 @@ class PysLexer(Pys):
560
565
 
561
566
  string += '\\' + character
562
567
  self.warning(
563
- f"{self.file.name}:{position.start_line}:{position.start_column + 1}: "
568
+ f"{self.file.name}:{position.start_line}:{position.start_column}: "
564
569
  f"SyntaxWarning: \"\\{character}\" "
565
570
  "is an invalid escape sequence. Such sequences will not work in the future. Did you mean "
566
571
  f"\"\\\\{character}\"? A raw string is also an option.\n" +
@@ -602,7 +607,7 @@ class PysLexer(Pys):
602
607
  except UnicodeEncodeError:
603
608
  self.throw(start, self.index, "bytes can only contain ASCII literal characters", add_token=False)
604
609
 
605
- self.add_token(TOKENS['STRING'], start, string)
610
+ self.add_token(TOKENS['STRING'], start, intern_object(string))
606
611
 
607
612
  def make_identifier(self) -> None:
608
613
  start = self.index
@@ -629,7 +634,7 @@ class PysLexer(Pys):
629
634
  self.add_token(
630
635
  TOKENS['KEYWORD'] if not identifier and is_keyword(name) else TOKENS['IDENTIFIER'],
631
636
  start,
632
- name
637
+ intern_object(name)
633
638
  )
634
639
 
635
640
  def make_plus(self) -> None:
@@ -2,8 +2,9 @@ from .token import TOKENS
2
2
  from .utils.ansi import BOLD, acolor
3
3
 
4
4
  from operator import (
5
- not_, is_, is_not, eq, ne, lt, gt, le, ge, add, sub, mul, truediv, floordiv, pow, matmul, mod, and_, or_, xor, lshift,
6
- rshift, iadd, isub, imul, itruediv, ifloordiv, ipow, imatmul, imod, iand, ior, ixor, ilshift, irshift, pos, neg, inv
5
+ not_, is_, is_not, eq, ne, lt, gt, le, ge, add, sub, mul, truediv, floordiv, pow, matmul, mod, and_, or_, xor,
6
+ lshift, rshift, iadd, isub, imul, itruediv, ifloordiv, ipow, imatmul, imod, iand, ior, ixor, ilshift, irshift, pos,
7
+ neg, inv
7
8
  )
8
9
  from types import MappingProxyType
9
10
 
@@ -64,6 +65,17 @@ GET_UNARY_FUNCTION = {
64
65
  TOKENS['TILDE']: inv
65
66
  }.__getitem__
66
67
 
68
+ GET_VALUE_FROM_CONSTANT_KEYWORDS = {
69
+ 'True': True,
70
+ 'False': False,
71
+ 'None': None,
72
+ 'true': True,
73
+ 'false': False,
74
+ 'nil': None,
75
+ 'none': None,
76
+ 'null': None
77
+ }.__getitem__
78
+
67
79
  GET_ACOLOR = {
68
80
  'reset': acolor('reset'),
69
81
  'magenta': acolor('magenta'),
@@ -7,6 +7,7 @@ from .utils.generic import setimuattr
7
7
  from typing import TYPE_CHECKING, Literal
8
8
 
9
9
  if TYPE_CHECKING:
10
+ # circular import problem solved
10
11
  from .pystypes import jsdict
11
12
 
12
13
  @immutable
@@ -1,20 +1,24 @@
1
1
  from .bases import Pys
2
- from .checks import is_sequence, is_left_bracket, is_right_bracket
3
- from .constants import DEFAULT, DICT_TO_JSDICT
2
+ from .cache import intern_object
3
+ from .checks import is_sequence, is_literal, is_left_bracket, is_right_bracket
4
+ from .constants import DEFAULT, NO_COLOR, SILENT, DICT_TO_JSDICT
4
5
  from .context import PysContext
5
6
  from .exceptions import PysTraceback
6
7
  from .mapping import BRACKETS_MAP
7
8
  from .nodes import *
8
- from .position import PysPosition
9
+ from .position import PysPosition, format_error_arrow
9
10
  from .pystypes import jsdict
10
11
  from .results import PysParserResult
11
12
  from .token import TOKENS, PysToken
12
13
  from .utils.decorators import typecheck
13
14
  from .utils.generic import setimuattr
15
+ from .utils.string import indent
14
16
 
15
17
  from types import MappingProxyType
16
18
  from typing import Any, Callable, Optional
17
19
 
20
+ import sys
21
+
18
22
  SEQUENCES_MAP = MappingProxyType({
19
23
  'dict': (TOKENS['LEFT_CURLY'], PysDictionaryNode),
20
24
  'set': (TOKENS['LEFT_CURLY'], PysSetNode),
@@ -73,6 +77,10 @@ class PysParser(Pys):
73
77
  self.token_index -= amount
74
78
  self.update_current_token()
75
79
 
80
+ def warning(self, message: str) -> None:
81
+ if not (self.flags & SILENT):
82
+ print(message, file=sys.stderr)
83
+
76
84
  def new_error(self, message: str, position: Optional[PysPosition] = None) -> PysTraceback:
77
85
  return PysTraceback(
78
86
  SyntaxError(message),
@@ -772,7 +780,7 @@ class PysParser(Pys):
772
780
  token.position.start,
773
781
  end
774
782
  ),
775
- string
783
+ intern_object(string)
776
784
  )
777
785
  )
778
786
  )
@@ -2403,7 +2411,11 @@ class PysParser(Pys):
2403
2411
 
2404
2412
  operations[-1] = PysToken(
2405
2413
  TOKENS['EXCLAMATION_GREATER_THAN'],
2406
- self.current_token.position
2414
+ PysPosition(
2415
+ self.current_token.position.file,
2416
+ token.position.start,
2417
+ self.current_token.position.end
2418
+ )
2407
2419
  )
2408
2420
 
2409
2421
  last_token = self.current_token
@@ -2419,7 +2431,11 @@ class PysParser(Pys):
2419
2431
  ):
2420
2432
  operations[-1] = PysToken(
2421
2433
  TOKENS['IS_NOT'],
2422
- self.current_token.position
2434
+ PysPosition(
2435
+ self.current_token.position.file,
2436
+ last_token.position.start,
2437
+ self.current_token.position.end
2438
+ )
2423
2439
  )
2424
2440
 
2425
2441
  result.register_advancement()
@@ -2430,6 +2446,21 @@ class PysParser(Pys):
2430
2446
  if result.error:
2431
2447
  return result
2432
2448
 
2449
+ if (
2450
+ membership and
2451
+ (is_literal(type((literal := expressions[-1]))) or is_literal(type((literal := expression)))) and
2452
+ (token := operations[-1]).type in (TOKENS['IS'], TOKENS['IS_NOT'])
2453
+ ):
2454
+ position = token.position
2455
+ equal = token.type == TOKENS['IS']
2456
+ self.warning(
2457
+ f"{position.file.name}:{position.start_line}:{position.start_column}: "
2458
+ f"SyntaxWarning: \"{'is' if equal else 'is not'}\" "
2459
+ f"with '{type(literal.value.value).__name__}' literal. "
2460
+ f"Did you mean \"{'==' if equal else '!='}\"?\n" +
2461
+ indent(format_error_arrow(position, not (self.flags & NO_COLOR)), 2)
2462
+ )
2463
+
2433
2464
  if operations:
2434
2465
  expressions.append(expression)
2435
2466
 
@@ -195,6 +195,7 @@ def require(context, position, name):
195
195
  except BaseException as e:
196
196
  raise ImportError(f"Cannot import module named {name!r}: {e}") from e
197
197
 
198
+ # circular import problem solved
198
199
  from .runner import pys_runner
199
200
 
200
201
  symbol_table, module = new_module_namespace(file=module_path, name=base(path))
@@ -256,6 +257,7 @@ def breakpoint(context, position):
256
257
  if getattr(pys_sys, '__running_breakpoint__', False):
257
258
  raise RuntimeError("another breakpoint is still running")
258
259
 
260
+ # circular import problem solved
259
261
  from .runner import pys_runner
260
262
 
261
263
  flags = context.flags
@@ -373,7 +375,7 @@ def globals(context, position):
373
375
  result = {}
374
376
 
375
377
  while symbol_table:
376
- result |= symbol_table.symbols
378
+ result = symbol_table.symbols | result
377
379
  symbol_table = symbol_table.parent
378
380
 
379
381
  return result
@@ -431,6 +433,7 @@ def exec(context, position, source, globals=None):
431
433
  if not isinstance(globals, optional_mapping):
432
434
  raise TypeError("exec(): globals must be dict")
433
435
 
436
+ # circular import problem solved
434
437
  from .runner import pys_runner
435
438
 
436
439
  result = pys_runner(
@@ -460,6 +463,7 @@ def eval(context, position, source, globals=None):
460
463
  if not isinstance(globals, optional_mapping):
461
464
  raise TypeError("eval(): globals must be dict")
462
465
 
466
+ # circular import problem solved
463
467
  from .runner import pys_runner
464
468
 
465
469
  result = pys_runner(
@@ -175,6 +175,7 @@ class PysExecuteResult(PysResult):
175
175
  elif type(self.error.exception) is SystemExit:
176
176
  return self.error.exception.code, True
177
177
  elif (excepthook := pys_sys.excepthook) is not None:
178
+ # circular import problem solved
178
179
  from .handlers import handle_call
179
180
  handle_call(excepthook, context, position)
180
181
  excepthook(*get_traceback_info(self.error))
@@ -255,6 +255,8 @@ try:
255
255
  if os.path.isfile(HISTORY_PATH):
256
256
 
257
257
  def add_to_string():
258
+ if not lines:
259
+ return
258
260
  strings.append('\n'.join(lines))
259
261
  lines.clear()
260
262
 
@@ -267,8 +269,7 @@ try:
267
269
  line = line[1:]
268
270
  lines.append(line)
269
271
 
270
- if lines:
271
- add_to_string()
272
+ add_to_string()
272
273
 
273
274
  else:
274
275
  update_history = True
@@ -6,6 +6,7 @@ from types import MappingProxyType
6
6
  from typing import TYPE_CHECKING, Any, Optional
7
7
 
8
8
  if TYPE_CHECKING:
9
+ # circular import problem solved
9
10
  from .position import PysPosition
10
11
 
11
12
  DOUBLE = 2**8
@@ -102,7 +103,7 @@ class PysToken(Pys):
102
103
  if TYPECHECK_STACK > 0:
103
104
  if not isinstance(type, int):
104
105
  raise TypeError('type must be integer')
105
- # circular import solved
106
+ # circular import problem solved
106
107
  from .position import PysPosition
107
108
  if not isinstance(position, PysPosition):
108
109
  raise TypeError('position must be pyscript.core.position.PysPosition')
@@ -16,14 +16,14 @@ def print_display(value: Any) -> None:
16
16
  def print_traceback(exc_type: type[BaseException], exc_value: BaseException | None, exc_tb: PysTraceback) -> None:
17
17
  print(exc_tb.string_traceback(), file=sys.stderr)
18
18
 
19
- def sys_excepthook(exc_type: type[BaseException], exc_value: BaseException | None, exc_tb: TracebackType) -> None:
19
+ def pys_excepthook(exc_type: type[BaseException], exc_value: BaseException | None, exc_tb: TracebackType) -> None:
20
20
  if exc_type is PysSignal and (traceback := exc_value.result.error) is not None:
21
21
  print_traceback(None, None, traceback)
22
22
  print('\nThe above PyScript exception was the direct cause of the following exception:\n', file=sys.stderr)
23
23
  excepthook(exc_type, exc_value, exc_tb)
24
24
 
25
- def thread_excepthook(args: Any) -> None:
26
- sys_excepthook(args.exc_type, args.exc_value, args.exc_traceback)
25
+ def single_excepthook(args) -> None:
26
+ pys_excepthook(args.exc_type, args.exc_value, args.exc_traceback)
27
27
 
28
28
  def import_readline() -> Literal[False]:
29
29
  return False
@@ -75,5 +75,5 @@ def get_traceback_info(traceback: PysTraceback | None) -> tuple[type[BaseExcepti
75
75
  if not is_environ(ENV_PYSCRIPT_NO_EXCEPTHOOK):
76
76
  import threading
77
77
 
78
- sys.excepthook = sys_excepthook
79
- threading.excepthook = thread_excepthook
78
+ sys.excepthook = pys_excepthook
79
+ sys.unraisablehook = threading.excepthook = single_excepthook
@@ -1,4 +1,3 @@
1
- from ..cache import pys_sys
2
1
  from .path import getcwd, extension, normpath
3
2
 
4
3
  import os
@@ -20,6 +19,9 @@ def get_module_candidate(path: str, entry: str = '__init__') -> str | None:
20
19
  return candidate
21
20
 
22
21
  def find_module_path(filename: str | None, name: str, entry: str = '__init__') -> tuple[str | None, str | None]:
22
+ # circular import problem solved
23
+ from ..cache import pys_sys
24
+
23
25
  for path in pys_sys.path:
24
26
  path = normpath(path, name)
25
27
  module_path = get_module_candidate(path, entry)
@@ -6,9 +6,9 @@ from types import MappingProxyType
6
6
 
7
7
  import re
8
8
 
9
- __version__ = '1.13.1'
10
- __date__ = '16 May 2026, 21:00 UTC+7'
11
- __author__ = ('Azzam Muhyala',)
9
+ __version__ = '1.13.3'
10
+ __date__ = '31 May 2026, 22:30 UTC+7'
11
+ __author__ = ('AzzamMuhyala',)
12
12
 
13
13
  version = pys_sys.version = f'{__version__} ({__date__})'
14
14
 
@@ -1,5 +1,4 @@
1
- from pyscript.core.interpreter import get_value_from_keyword
2
- from pyscript.core.mapping import GET_BINARY_FUNCTION, GET_UNARY_FUNCTION
1
+ from pyscript.core.mapping import GET_VALUE_FROM_CONSTANT_KEYWORDS
3
2
  from pyscript.core.nodes import (
4
3
  PysNode, PysNumberNode, PysStringNode, PysKeywordNode, PysIdentifierNode, PysDictionaryNode, PysSetNode,
5
4
  PysListNode, PysTupleNode, PysCallNode, PysUnaryOperatorNode, PysBinaryOperatorNode, PysEllipsisNode
@@ -11,7 +10,8 @@ from pyscript.core.token import TOKENS, REVERSE_TOKENS
11
10
  from types import EllipsisType
12
11
  from typing import Any, Callable
13
12
 
14
- is_arithmetic = frozenset([TOKENS['PLUS'], TOKENS['MINUS']]).__contains__
13
+ T_ADD = TOKENS['PLUS']
14
+ T_SUB = TOKENS['MINUS']
15
15
 
16
16
  get_identifier = {
17
17
  'Ellipsis': pys_builtins.Ellipsis,
@@ -42,8 +42,7 @@ def visit_StringNode(node: PysStringNode) -> str | bytes:
42
42
  return node.value.value
43
43
 
44
44
  def visit_KeywordNode(node: PysKeywordNode) -> bool | None:
45
- # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv <- always boolean or none
46
- return get_value_from_keyword(node.name.value)
45
+ return GET_VALUE_FROM_CONSTANT_KEYWORDS(node.name.value)
47
46
 
48
47
  def visit_IdentifierNode(node: PysIdentifierNode) -> Any:
49
48
  name = node.name.value
@@ -72,14 +71,18 @@ def visit_CallNode(node: PysCallNode) -> set:
72
71
 
73
72
  def visit_UnaryOperatorNode(node: PysUnaryOperatorNode) -> Any:
74
73
  operand = node.operand.type
75
- if is_arithmetic(operand):
76
- return GET_UNARY_FUNCTION(operand)(visit(node.value))
74
+ if operand == T_SUB:
75
+ return -visit(node.value)
76
+ elif operand == T_ADD:
77
+ return +visit(node.value)
77
78
  raise _error(ValueError(f"invalid unary operator node: {REVERSE_TOKENS[operand]}"), node.position)
78
79
 
79
80
  def visit_BinaryOperatorNode(node: PysBinaryOperatorNode) -> Any:
80
81
  operand = node.operand.type
81
- if is_arithmetic(operand):
82
- return GET_BINARY_FUNCTION(operand)(visit(node.left), visit(node.right))
82
+ if operand == T_ADD:
83
+ return visit(node.left) + visit(node.right)
84
+ elif operand == T_SUB:
85
+ return visit(node.left) - visit(node.right)
83
86
  raise _error(ValueError(f"invalid binary operator node: {REVERSE_TOKENS[operand]}"), node.position)
84
87
 
85
88
  def visit_EllipsisNode(node: PysEllipsisNode) -> EllipsisType:
@@ -82,13 +82,13 @@ if (__name__ == '__main__') {
82
82
  parser.add_argument(
83
83
  '-a',
84
84
  metavar='PATH',
85
- help='add a package to site-packages'
85
+ help='add a package to site packages'
86
86
  )
87
87
 
88
88
  parser.add_argument(
89
89
  '-r',
90
90
  metavar='NAME',
91
- help='remove a package from site-packages'
91
+ help='remove a package from site packages'
92
92
  )
93
93
 
94
94
  args = parser.parse_args(sys.argv[1:])
@@ -10,14 +10,14 @@ from typing import Iterable
10
10
  @inheritable
11
11
  @singleton
12
12
  class TokenValueError:
13
-
14
13
  def __repr__(self):
15
14
  return '\\ERROR'
16
15
 
17
16
  token_value_error = TokenValueError()
18
17
 
19
- def untokenize(iterable: Iterable[PysToken]) -> str:
18
+ def untokenize(iterable: Iterable[PysToken], *, indent: int = 4) -> str:
20
19
  iterable = tuple(iterable)
20
+ indent_character = ' ' * indent
21
21
 
22
22
  parts = []
23
23
  add_space = False
@@ -51,7 +51,7 @@ def untokenize(iterable: Iterable[PysToken]) -> str:
51
51
  if brackets_stack > 0 and is_right_bracket(get_sequence(iterable, i + 1, token).type) else
52
52
  brackets_stack
53
53
  )
54
- parts.append(f'\n{" " * stack}')
54
+ parts.append(f'\n{indent_character * stack}')
55
55
  newline = True
56
56
  add_space = False
57
57
  continue
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.13.1
3
+ Version: 1.13.3
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://azzammuhyala.github.io/pyscript
6
- Author: Azzam Muhyala
7
- Author-email: Azzam Muhyala <azzammuhyala@gmail.com>
6
+ Author: AzzamMuhyala
7
+ Author-email: AzzamMuhyala <azzammuhyala@gmail.com>
8
8
  License-Expression: MIT
9
9
  Project-URL: Homepage, https://azzammuhyala.github.io/pyscript
10
10
  Project-URL: Documentation, https://azzammuhyala.github.io/pyscript
@@ -145,7 +145,7 @@ Familiar? There it is!
145
145
  - **optional**: Not required, but if it is present, some features can be used without issue.
146
146
 
147
147
  ## Highlights 🎨
148
- - [PyScript plugin for Acode (Ace Editor)](https://github.com/azzammuhyala/pyscript/releases/download/v1.13.1/plugin.zip)
148
+ - [PyScript plugin for Acode (Ace Editor)](https://github.com/azzammuhyala/pyscript/releases/download/v1.13.3/plugin-1.0.2.zip)
149
149
  - [PyScript nano for Linux](https://github.com/azzammuhyala/pyscript/tree/main/highlight/nano)
150
150
  - [PyScript extension for VSCode](https://marketplace.visualstudio.com/items?itemName=azzammuhyala.pyslang)
151
151
 
@@ -9,11 +9,11 @@ with open('./README.md', 'r', encoding='utf-8') as file:
9
9
 
10
10
  setup(
11
11
  name='pyscript-programming-language',
12
- version='1.13.1',
12
+ version='1.13.3',
13
13
  description='PyScript Programming Language',
14
14
  long_description=long_description,
15
15
  long_description_content_type='text/markdown',
16
- author='Azzam Muhyala',
16
+ author='AzzamMuhyala',
17
17
  author_email='azzammuhyala@gmail.com',
18
18
  url='https://azzammuhyala.github.io/pyscript',
19
19
  project_urls={
@@ -1,12 +0,0 @@
1
- # Change Logs
2
-
3
- ## [1.13.1] - 16/05/2026
4
-
5
- ### Added
6
- - `__builtins__` is available in the module namespace.
7
- - The editor can save multiple configurations.
8
-
9
- ### Fixed
10
- - Changed the order of `instanceof` operation.
11
- - Fixed some bugs.
12
- - _etc._