pyscript-programming-language 1.6.0__tar.gz → 1.6.1__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 (71) hide show
  1. {pyscript_programming_language-1.6.0/pyscript_programming_language.egg-info → pyscript_programming_language-1.6.1}/PKG-INFO +1 -1
  2. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/__init__.py +4 -3
  3. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/__init__.pyi +10 -6
  4. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/__main__.py +13 -15
  5. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/analyzer.py +3 -3
  6. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/checks.py +3 -3
  7. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/constants.py +5 -4
  8. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/exceptions.py +2 -3
  9. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/handlers.py +2 -2
  10. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/highlight.py +39 -41
  11. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/interpreter.py +27 -35
  12. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/lexer.py +61 -53
  13. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/mapping.py +9 -9
  14. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/objects.py +6 -8
  15. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/parser.py +12 -17
  16. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/pysbuiltins.py +24 -32
  17. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/runner.py +28 -23
  18. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/utils/decorators.py +11 -5
  19. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/utils/generic.py +6 -3
  20. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/utils/module.py +1 -1
  21. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/version.py +2 -2
  22. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/ast/ast_dump.py +2 -2
  23. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/ast/ast_unparse.py +4 -1
  24. pyscript_programming_language-1.6.1/pyscript/lib/dis.pys +7 -0
  25. pyscript_programming_language-1.6.1/pyscript/lib/keyword.pys +2 -0
  26. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/parser.pys +4 -4
  27. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/this.pys +1 -1
  28. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/tokenize/tok_untokenize.py +9 -6
  29. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1/pyscript_programming_language.egg-info}/PKG-INFO +1 -1
  30. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/setup.py +1 -1
  31. pyscript_programming_language-1.6.0/pyscript/lib/dis.pys +0 -11
  32. pyscript_programming_language-1.6.0/pyscript/lib/keyword.pys +0 -2
  33. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/MANIFEST.in +0 -0
  34. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/README.md +0 -0
  35. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/__init__.py +0 -0
  36. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/bases.py +0 -0
  37. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/buffer.py +0 -0
  38. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/cache.py +0 -0
  39. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/context.py +0 -0
  40. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/nodes.py +0 -0
  41. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/position.py +0 -0
  42. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/results.py +0 -0
  43. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/symtab.py +0 -0
  44. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/token.py +0 -0
  45. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/utils/__init__.py +0 -0
  46. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/utils/ansi.py +0 -0
  47. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/utils/debug.py +0 -0
  48. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/utils/path.py +0 -0
  49. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/utils/similarity.py +0 -0
  50. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/core/utils/string.py +0 -0
  51. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/__hello__.pys +0 -0
  52. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/ast/__init__.pys +0 -0
  53. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/ast/ast_walk.py +0 -0
  54. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/brainfuck.pys +0 -0
  55. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/explorer.pys +0 -0
  56. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/fpstimer.pys +0 -0
  57. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/getch.pys +0 -0
  58. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/inspect.pys +0 -0
  59. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/jsdict.pys +0 -0
  60. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/site.pys +0 -0
  61. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/symtable.pys +0 -0
  62. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/sys.pys +0 -0
  63. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/token.pys +0 -0
  64. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/lib/tokenize/__init__.pys +0 -0
  65. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/site-packages/67.pys +0 -0
  66. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript/this.py +0 -0
  67. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
  68. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  69. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript_programming_language.egg-info/requires.txt +0 -0
  70. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  71. {pyscript_programming_language-1.6.0 → pyscript_programming_language-1.6.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.6.0
3
+ Version: 1.6.1
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://github.com/azzammuhyala/pyscript
6
6
  Author: azzammuhyala
@@ -8,10 +8,10 @@ if __import__('sys').version_info < (3, 10):
8
8
 
9
9
  from . import core
10
10
 
11
- from .core.constants import DEFAULT, DEBUG, SILENT, RETRES, COMMENT, NO_COLOR, REVERSE_POW_XOR
11
+ from .core.constants import DEFAULT, DEBUG, SILENT, RETRES, HIGHLIGHT, NO_COLOR, REVERSE_POW_XOR
12
12
  from .core.cache import undefined
13
13
  from .core.highlight import HLFMT_HTML, HLFMT_ANSI, HLFMT_BBCODE, pys_highlight
14
- from .core.runner import pys_exec, pys_eval, pys_shell
14
+ from .core.runner import pys_exec, pys_eval, pys_require, pys_shell
15
15
  from .core.version import version_info, __version__, __date__
16
16
 
17
17
  __all__ = (
@@ -20,7 +20,7 @@ __all__ = (
20
20
  'DEBUG',
21
21
  'SILENT',
22
22
  'RETRES',
23
- 'COMMENT',
23
+ 'HIGHLIGHT',
24
24
  'NO_COLOR',
25
25
  'REVERSE_POW_XOR',
26
26
  'HLFMT_HTML',
@@ -31,5 +31,6 @@ __all__ = (
31
31
  'pys_highlight',
32
32
  'pys_exec',
33
33
  'pys_eval',
34
+ 'pys_require',
34
35
  'pys_shell'
35
36
  )
@@ -10,6 +10,7 @@ if TYPE_CHECKING:
10
10
  from .core.version import PysVersionInfo
11
11
 
12
12
  from io import IOBase
13
+ from types import ModuleType
13
14
 
14
15
  from . import core as core
15
16
 
@@ -17,7 +18,7 @@ DEFAULT: int
17
18
  DEBUG: int
18
19
  SILENT: int
19
20
  RETRES: int
20
- COMMENT: int
21
+ HIGHLIGHT: int
21
22
  NO_COLOR: int
22
23
  REVERSE_POW_XOR: int
23
24
 
@@ -35,9 +36,9 @@ def pys_highlight(
35
36
  [
36
37
  str | Literal[
37
38
  'start',
38
- 'bracket-unmatch',
39
- 'identifier', 'identifier-const', 'identifier-call', 'identifier-class',
40
- 'keyword', 'keyword-identifier',
39
+ 'invalid',
40
+ 'identifier', 'identifier-constant', 'identifier-function', 'identifier-type',
41
+ 'keyword', 'keyword-constant',
41
42
  'number', 'string', 'comment', 'newline',
42
43
  'default',
43
44
  'end'
@@ -48,8 +49,7 @@ def pys_highlight(
48
49
  str
49
50
  ]
50
51
  ] = None,
51
- max_parenthesis_level: int = 3,
52
- flags: int = DEFAULT
52
+ max_parenthesis_level: int = 3
53
53
  ) -> str: ...
54
54
 
55
55
  def pys_exec(
@@ -64,6 +64,10 @@ def pys_eval(
64
64
  flags: int = DEFAULT
65
65
  ) -> Any | PysExecuteResult: ...
66
66
 
67
+ def pys_require(
68
+ name: str | bytes
69
+ ) -> ModuleType | Any: ...
70
+
67
71
  def pys_shell(
68
72
  globals: Optional[dict[str, Any] | PysSymbolTable | PysUndefined] = None,
69
73
  flags: int = DEFAULT
@@ -5,16 +5,22 @@ from .core.handlers import handle_execute
5
5
  from .core.highlight import HLFMT_HTML, HLFMT_ANSI, HLFMT_BBCODE, pys_highlight
6
6
  from .core.runner import pys_runner, pys_shell
7
7
  from .core.symtab import new_symbol_table
8
- from .core.utils.module import get_module_name_from_path, set_python_path
9
- from .core.utils.path import getcwd, normpath
8
+ from .core.utils.module import get_module_name_from_path
9
+ from .core.utils.path import normpath
10
10
  from .core.version import __version__
11
11
 
12
12
  from argparse import ArgumentParser
13
13
  from sys import executable, stderr, version_info, exit, setrecursionlimit
14
14
 
15
+ FORMAT_HIGHLIGHT_MAP = {
16
+ 'html': HLFMT_HTML,
17
+ 'ansi': HLFMT_ANSI,
18
+ 'bbcode': HLFMT_BBCODE
19
+ }
20
+
15
21
  parser = ArgumentParser(
16
- prog=get_module_name_from_path(executable) + ' -m pyscript',
17
- description='PyScript Launcher for Python Version ' + '.'.join(map(str, version_info))
22
+ prog=f'{get_module_name_from_path(executable)} -m pyscript',
23
+ description=f'PyScript Launcher for Python Version {".".join(map(str, version_info))}'
18
24
  )
19
25
 
20
26
  parser.add_argument(
@@ -52,7 +58,7 @@ parser.add_argument(
52
58
 
53
59
  parser.add_argument(
54
60
  '-l', '--highlight',
55
- choices=('html', 'ansi', 'bbcode'),
61
+ choices=tuple(FORMAT_HIGHLIGHT_MAP.keys()),
56
62
  default=None,
57
63
  help='generate PyScript highlight code from a file'
58
64
  )
@@ -93,8 +99,6 @@ if args.debug:
93
99
  if args.no_color:
94
100
  flags |= NO_COLOR
95
101
 
96
- set_python_path(getcwd())
97
-
98
102
  if args.file is not None:
99
103
  path = normpath(args.file)
100
104
 
@@ -117,16 +121,10 @@ if args.file is not None:
117
121
  parser.error(f"file {path!r}: Unexpected error: {e}")
118
122
 
119
123
  if args.highlight:
120
- format_map = {
121
- 'html': HLFMT_HTML,
122
- 'ansi': HLFMT_ANSI,
123
- 'bbcode': HLFMT_BBCODE
124
- }
125
-
126
124
  try:
127
- print(pys_highlight(file, format_map[args.highlight]))
125
+ print(pys_highlight(file, FORMAT_HIGHLIGHT_MAP.get(args.highlight, None)))
128
126
  except BaseException as e:
129
- parser.error(f"file {path!r}: Tokenize error: {e}")
127
+ parser.error(f"file {path!r}: Highlight error: {e}")
130
128
 
131
129
  else:
132
130
  result = pys_runner(
@@ -2,7 +2,7 @@ from .bases import Pys
2
2
  from .checks import is_assign, is_incremental
3
3
  from .constants import TOKENS, DEFAULT
4
4
  from .context import PysContext
5
- from .exceptions import PysException
5
+ from .exceptions import PysTraceback
6
6
  from .nodes import PysNode, PysKeywordNode, PysIdentifierNode, PysAttributeNode, PysSubscriptNode
7
7
  from .position import PysPosition
8
8
  from .utils.decorators import typechecked
@@ -27,7 +27,7 @@ class PysAnalyzer(Pys):
27
27
 
28
28
  def throw(self, message, position):
29
29
  if self.error is None:
30
- self.error = PysException(
30
+ self.error = PysTraceback(
31
31
  SyntaxError(message),
32
32
  PysContext(
33
33
  file=self.node.position.file,
@@ -39,7 +39,7 @@ class PysAnalyzer(Pys):
39
39
  )
40
40
 
41
41
  @typechecked
42
- def analyze(self) -> PysException | None:
42
+ def analyze(self) -> PysTraceback | None:
43
43
  self.in_loop = 0
44
44
  self.in_function = 0
45
45
  self.in_switch = 0
@@ -41,10 +41,10 @@ is_left_parenthesis = frozenset(PARENTHESISES_MAP.keys()).__contains__
41
41
  is_right_parenthesis = frozenset(PARENTHESISES_MAP.values()).__contains__
42
42
  is_parenthesis = frozenset(PARENTHESISES_MAP.keys() | PARENTHESISES_MAP.values()).__contains__
43
43
 
44
- is_keyword_identifiers = frozenset([
44
+ is_constant_keywords = frozenset([
45
45
  KEYWORDS['__debug__'], KEYWORDS['of'], KEYWORDS['in'], KEYWORDS['is'], KEYWORDS['and'], KEYWORDS['or'],
46
- KEYWORDS['not'], KEYWORDS['False'], KEYWORDS['None'], KEYWORDS['True'], KEYWORDS['false'], KEYWORDS['none'],
47
- KEYWORDS['true']
46
+ KEYWORDS['not'], KEYWORDS['False'], KEYWORDS['None'], KEYWORDS['True'], KEYWORDS['class'], KEYWORDS['false'],
47
+ KEYWORDS['func'], KEYWORDS['function'], KEYWORDS['global'], KEYWORDS['none'], KEYWORDS['true']
48
48
  ]).__contains__
49
49
 
50
50
  is_private_attribute = lambda name : name.startswith('_')
@@ -84,6 +84,7 @@ TOKENS = MappingProxyType({
84
84
  'EQUAL-DOUBLE-SLASH': ord('/') + DOUBLE + WITH_EQUAL,
85
85
  'EQUAL-DOUBLE-LESS-THAN': ord('<') + DOUBLE + WITH_EQUAL,
86
86
  'EQUAL-DOUBLE-GREATER-THAN': ord('>') + DOUBLE + WITH_EQUAL,
87
+ 'NONE': SPECIAL,
87
88
  'EXCLAMATION-TILDE': ord('~') + SPECIAL
88
89
  })
89
90
 
@@ -93,9 +94,6 @@ KEYWORDS = MappingProxyType({
93
94
  'False': 'False',
94
95
  'None': 'None',
95
96
  'True': 'True',
96
- 'false': 'false',
97
- 'none': 'none',
98
- 'true': 'true',
99
97
  'and': 'and',
100
98
  'as': 'as',
101
99
  'assert': 'assert',
@@ -111,6 +109,7 @@ KEYWORDS = MappingProxyType({
111
109
  'elif': 'elif',
112
110
  'else': 'else',
113
111
  'extends': 'extends',
112
+ 'false': 'false',
114
113
  'finally': 'finally',
115
114
  'for': 'for',
116
115
  'from': 'from',
@@ -121,7 +120,9 @@ KEYWORDS = MappingProxyType({
121
120
  'import': 'import',
122
121
  'in': 'in',
123
122
  'is': 'is',
123
+ 'none': 'none',
124
124
  'not': 'not',
125
+ 'true': 'true',
125
126
  'of': 'of',
126
127
  'or': 'or',
127
128
  'return': 'return',
@@ -137,6 +138,6 @@ DEFAULT = 0
137
138
  DEBUG = 1 << 0
138
139
  SILENT = 1 << 1
139
140
  RETRES = 1 << 2
140
- COMMENT = 1 << 3
141
+ HIGHLIGHT = 1 << 3
141
142
  NO_COLOR = 1 << 4
142
143
  REVERSE_POW_XOR = 1 << 5
@@ -6,7 +6,7 @@ from .utils.generic import setimuattr
6
6
  from .utils.string import indent
7
7
 
8
8
  @immutable
9
- class PysException(Pys):
9
+ class PysTraceback(Pys):
10
10
 
11
11
  __slots__ = ('exception', 'context', 'position', 'cause', 'directly')
12
12
 
@@ -18,7 +18,7 @@ class PysException(Pys):
18
18
  setimuattr(self, 'directly', directly)
19
19
 
20
20
  def __repr__(self):
21
- return f'<Exception of {self.exception!r}>'
21
+ return f'<traceback of exception {self.exception!r}>'
22
22
 
23
23
  def string_traceback(self):
24
24
  context = self.context
@@ -110,6 +110,5 @@ class PysSignal(Pys, BaseException):
110
110
 
111
111
  if isinstance(exception, type):
112
112
  return exception.__name__
113
-
114
113
  message = str(exception)
115
114
  return type(exception).__name__ + (f': {message}' if message else '')
@@ -1,6 +1,6 @@
1
1
  from .cache import lock, hook
2
2
  from .constants import PYSCRIPT_GIL
3
- from .exceptions import PysException, PysSignal
3
+ from .exceptions import PysTraceback, PysSignal
4
4
  from .objects import PysPythonFunction, PysFunction
5
5
  from .position import PysPosition
6
6
  from .results import PysRunTimeResult
@@ -31,7 +31,7 @@ class handle_exception:
31
31
  self.result.register(exc_val.result) \
32
32
  if exc_type is PysSignal else \
33
33
  self.result.failure(
34
- PysException(
34
+ PysTraceback(
35
35
  exc_type if exc_val is None else exc_val,
36
36
  self.context,
37
37
  self.position
@@ -1,7 +1,7 @@
1
1
  from .bases import Pys
2
2
  from .buffer import PysFileBuffer
3
- from .checks import is_left_parenthesis, is_right_parenthesis, is_parenthesis, is_keyword_identifiers
4
- from .constants import TOKENS, KEYWORDS, DEFAULT, SILENT, COMMENT
3
+ from .checks import is_left_parenthesis, is_right_parenthesis, is_parenthesis, is_constant_keywords
4
+ from .constants import TOKENS, KEYWORDS, HIGHLIGHT
5
5
  from .lexer import PysLexer
6
6
  from .mapping import PARENTHESISES_MAP, HIGHLIGHT_MAP
7
7
  from .position import PysPosition
@@ -92,8 +92,7 @@ HLFMT_BBCODE = _HighlightFormatter(
92
92
  def pys_highlight(
93
93
  source,
94
94
  format: Optional[Callable[[str, PysPosition, str], str]] = None,
95
- max_parenthesis_level: int = 3,
96
- flags: int = DEFAULT
95
+ max_parenthesis_level: int = 3
97
96
  ) -> str:
98
97
  """
99
98
  Highlight a PyScript code from source given.
@@ -105,8 +104,6 @@ def pys_highlight(
105
104
  format: A function to format the code form.
106
105
 
107
106
  max_parenthesis_level: Maximum difference level of parentheses (with circular indexing).
108
-
109
- flags: A special flags.
110
107
  """
111
108
 
112
109
  file = PysFileBuffer(source)
@@ -119,13 +116,12 @@ def pys_highlight(
119
116
 
120
117
  lexer = PysLexer(
121
118
  file=file,
122
- flags=flags | COMMENT
119
+ flags=HIGHLIGHT
123
120
  )
124
121
 
125
- tokens, error = lexer.make_tokens()
126
- if error and not (flags & SILENT):
127
- raise error.exception
122
+ tokens, _ = lexer.make_tokens()
128
123
 
124
+ text = file.text
129
125
  result = ''
130
126
  last_index_position = 0
131
127
  parenthesis_level = 0
@@ -135,8 +131,6 @@ def pys_highlight(
135
131
  TOKENS['RIGHT-CURLY']: 0
136
132
  }
137
133
 
138
- text = file.text
139
-
140
134
  for i, token in enumerate(tokens):
141
135
  ttype = token.type
142
136
  tvalue = token.value
@@ -149,54 +143,58 @@ def pys_highlight(
149
143
  type_fmt = 'end'
150
144
 
151
145
  elif ttype == TOKENS['KEYWORD']:
152
- type_fmt = 'keyword-identifier' if is_keyword_identifiers(tvalue) else 'keyword'
153
-
154
- elif ttype == TOKENS['NUMBER']:
155
- type_fmt = 'number'
156
-
157
- elif ttype == TOKENS['STRING']:
158
- type_fmt = 'string'
146
+ type_fmt = 'keyword-constant' if is_constant_keywords(tvalue) else 'keyword'
159
147
 
160
148
  elif ttype == TOKENS['IDENTIFIER']:
161
149
  obj = pys_builtins.__dict__.get(tvalue, None)
162
150
 
163
151
  if isinstance(obj, type):
164
- type_fmt = 'identifier-class'
165
-
152
+ type_fmt = 'identifier-type'
166
153
  elif callable(obj):
167
- type_fmt = 'identifier-call'
154
+ type_fmt = 'identifier-function'
168
155
 
169
156
  else:
170
- type_fmt = 'identifier-const' if tvalue.isupper() else 'identifier'
171
-
172
- j = i + 1
173
- if (j < len(tokens) and tokens[j].type == TOKENS['LEFT-PARENTHESIS']):
174
- type_fmt = 'identifier-call'
175
-
176
157
  j = i - 1
177
- while j > 0 and tokens[j].type == TOKENS['NEWLINE']:
158
+ while j > 0 and tokens[j].type in (TOKENS['NEWLINE'], TOKENS['COMMENT']):
178
159
  j -= 1
179
160
 
180
- if tokens[j].match(TOKENS['KEYWORD'], KEYWORDS['class']):
181
- type_fmt = 'identifier-class'
182
- elif tokens[j].matches(TOKENS['KEYWORD'], (KEYWORDS['func'], KEYWORDS['function'])):
183
- type_fmt = 'identifier-call'
161
+ previous_token = tokens[j]
162
+ if previous_token.match(TOKENS['KEYWORD'], KEYWORDS['class']):
163
+ type_fmt = 'identifier-type'
164
+ elif previous_token.matches(TOKENS['KEYWORD'], (KEYWORDS['func'], KEYWORDS['function'])):
165
+ type_fmt = 'identifier-function'
166
+
167
+ else:
168
+ j = i + 1
169
+ if (j < len(tokens) and tokens[j].type == TOKENS['LEFT-PARENTHESIS']):
170
+ type_fmt = 'identifier-function'
171
+ else:
172
+ type_fmt = 'identifier-constant' if tvalue.isupper() else 'identifier'
173
+
174
+ elif ttype == TOKENS['NUMBER']:
175
+ type_fmt = 'number'
176
+
177
+ elif ttype == TOKENS['STRING']:
178
+ type_fmt = 'string'
179
+
180
+ elif ttype == TOKENS['NEWLINE']:
181
+ type_fmt = 'newline'
182
+
183
+ elif ttype == TOKENS['COMMENT']:
184
+ type_fmt = 'comment'
184
185
 
185
186
  elif is_parenthesis(ttype):
186
- type_fmt = 'parenthesis-{}'.format(
187
- 'unmatch'
187
+ type_fmt = (
188
+ 'invalid'
188
189
  if
189
190
  parenthesises_level[PARENTHESISES_MAP.get(ttype, ttype)] < 0 or
190
191
  parenthesis_level < 0
191
192
  else
192
- parenthesis_level % max_parenthesis_level
193
+ f'brackets-{parenthesis_level % max_parenthesis_level}'
193
194
  )
194
195
 
195
- elif ttype == TOKENS['NEWLINE']:
196
- type_fmt = 'newline'
197
-
198
- elif ttype == TOKENS['COMMENT']:
199
- type_fmt = 'comment'
196
+ elif ttype == TOKENS['NONE']:
197
+ type_fmt = 'invalid'
200
198
 
201
199
  else:
202
200
  type_fmt = 'default'
@@ -1,8 +1,8 @@
1
1
  from .constants import TOKENS, KEYWORDS, DEBUG
2
2
  from .cache import undefined
3
- from .checks import is_assign, is_python_extensions, is_equals, is_incremental, is_public_attribute
3
+ from .checks import is_assign, is_equals, is_incremental, is_public_attribute
4
4
  from .context import PysClassContext
5
- from .exceptions import PysException
5
+ from .exceptions import PysTraceback
6
6
  from .handlers import handle_exception, handle_call
7
7
  from .mapping import BINARY_FUNCTIONS_MAP, UNARY_FUNCTIONS_MAP, KEYWORDS_TO_VALUES_MAP
8
8
  from .nodes import PysNode, PysIdentifierNode, PysAttributeNode, PysSubscriptNode
@@ -14,7 +14,6 @@ from .utils.generic import setimuattr, is_object_of, get_error_args
14
14
  from .utils.similarity import get_closest
15
15
 
16
16
  from collections.abc import Iterable
17
- from os.path import splitext as split_file_extension
18
17
 
19
18
  KW__DEBUG__ = KEYWORDS['__debug__']
20
19
  KW_AND = KEYWORDS['and']
@@ -65,7 +64,7 @@ def visit_IdentifierNode(node, context):
65
64
  closest_symbol = find_closest(symbol_table, name)
66
65
 
67
66
  return result.failure(
68
- PysException(
67
+ PysTraceback(
69
68
  NameError(
70
69
  f"name {name!r} is not defined" +
71
70
  (
@@ -421,25 +420,18 @@ def visit_ImportNode(node, context):
421
420
 
422
421
  with handle_exception(result, context, name_position):
423
422
  name_module = tname.value
424
- file, extension = split_file_extension(name_module)
423
+ use_python_package = False
425
424
 
426
- if is_python_extensions(extension):
427
- name_module = file
425
+ require = get_symbol('require')
426
+
427
+ if require is undefined:
428
428
  use_python_package = True
429
429
  else:
430
- use_python_package = False
431
-
432
- if not use_python_package:
433
- require = get_symbol('require')
434
-
435
- if require is undefined:
430
+ handle_call(require, context, name_position)
431
+ try:
432
+ module = require(name_module)
433
+ except ImportError:
436
434
  use_python_package = True
437
- else:
438
- handle_call(require, context, name_position)
439
- try:
440
- module = require(name_module)
441
- except ImportError:
442
- use_python_package = True
443
435
 
444
436
  if use_python_package:
445
437
  pyimport = get_symbol('pyimport')
@@ -449,7 +441,7 @@ def visit_ImportNode(node, context):
449
441
 
450
442
  if pyimport is undefined:
451
443
  return result.failure(
452
- PysException(
444
+ PysTraceback(
453
445
  NameError("names 'require', 'pyimport', and '__import__' is not defined"),
454
446
  context,
455
447
  node.position
@@ -473,7 +465,7 @@ def visit_ImportNode(node, context):
473
465
 
474
466
  if not isinstance(package, str):
475
467
  return result.failure(
476
- PysException(
468
+ PysTraceback(
477
469
  TypeError(f"Item in {module.__name__}.__all__ must be str, not {type(package).__name__}"),
478
470
  context,
479
471
  name_position
@@ -612,7 +604,7 @@ def visit_TryNode(node, context):
612
604
 
613
605
  if not (isinstance(error_cls, type) and issubclass(error_cls, BaseException)):
614
606
  return result.failure(
615
- PysException(
607
+ PysTraceback(
616
608
  TypeError("catching classes that do not inherit from BaseException is not allowed"),
617
609
  context,
618
610
  nname.position,
@@ -677,7 +669,7 @@ def visit_WithNode(node, context):
677
669
 
678
670
  if enter is undefined:
679
671
  return result.failure(
680
- PysException(
672
+ PysTraceback(
681
673
  TypeError(
682
674
  f"{type(context_value).__name__!r} object does not support the context manager protocol"
683
675
  ),
@@ -688,7 +680,7 @@ def visit_WithNode(node, context):
688
680
 
689
681
  elif exit is undefined:
690
682
  return result.failure(
691
- PysException(
683
+ PysTraceback(
692
684
  TypeError(
693
685
  f"{type(context_value).__name__!r} object does not support the context manager protocol "
694
686
  "(missed __exit__ method)"
@@ -1059,7 +1051,7 @@ def visit_ThrowNode(node, context):
1059
1051
 
1060
1052
  if not is_object_of(target, BaseException):
1061
1053
  return result.failure(
1062
- PysException(
1054
+ PysTraceback(
1063
1055
  TypeError("exceptions must derive from BaseException"),
1064
1056
  context,
1065
1057
  ntarget.position
@@ -1073,14 +1065,14 @@ def visit_ThrowNode(node, context):
1073
1065
 
1074
1066
  if not is_object_of(cause, BaseException):
1075
1067
  return result.failure(
1076
- PysException(
1068
+ PysTraceback(
1077
1069
  TypeError("exceptions must derive from BaseException"),
1078
1070
  context,
1079
1071
  ncause.position
1080
1072
  )
1081
1073
  )
1082
1074
 
1083
- cause = PysException(
1075
+ cause = PysTraceback(
1084
1076
  cause,
1085
1077
  context,
1086
1078
  ncause.position
@@ -1090,7 +1082,7 @@ def visit_ThrowNode(node, context):
1090
1082
  cause = None
1091
1083
 
1092
1084
  return result.failure(
1093
- PysException(
1085
+ PysTraceback(
1094
1086
  target,
1095
1087
  context,
1096
1088
  node.position,
@@ -1122,7 +1114,7 @@ def visit_AssertNode(node, context):
1122
1114
  return result
1123
1115
 
1124
1116
  return result.failure(
1125
- PysException(
1117
+ PysTraceback(
1126
1118
  AssertionError(message),
1127
1119
  context,
1128
1120
  node.position
@@ -1130,7 +1122,7 @@ def visit_AssertNode(node, context):
1130
1122
  )
1131
1123
 
1132
1124
  return result.failure(
1133
- PysException(
1125
+ PysTraceback(
1134
1126
  AssertionError,
1135
1127
  context,
1136
1128
  node.position
@@ -1162,7 +1154,7 @@ def visit_DeleteNode(node, context):
1162
1154
  closest_symbol = get_closest(symbol_table.symbols.keys(), name)
1163
1155
 
1164
1156
  return result.failure(
1165
- PysException(
1157
+ PysTraceback(
1166
1158
  NameError(
1167
1159
  (
1168
1160
  f"name {name!r} is not defined"
@@ -1286,7 +1278,7 @@ def visit_declaration_AssignNode(node, context, value, operand=TOKENS['EQUAL']):
1286
1278
  closest_symbol = get_closest(symbol_table.symbols.keys(), name)
1287
1279
 
1288
1280
  result.failure(
1289
- PysException(
1281
+ PysTraceback(
1290
1282
  NameError(
1291
1283
  (
1292
1284
  f"name {name!r} is not defined"
@@ -1345,7 +1337,7 @@ def visit_declaration_AssignNode(node, context, value, operand=TOKENS['EQUAL']):
1345
1337
 
1346
1338
  if not isinstance(value, Iterable):
1347
1339
  return result.failure(
1348
- PysException(
1340
+ PysTraceback(
1349
1341
  TypeError(f"cannot unpack non-iterable {type(value).__name__} object"),
1350
1342
  context,
1351
1343
  position
@@ -1371,7 +1363,7 @@ def visit_declaration_AssignNode(node, context, value, operand=TOKENS['EQUAL']):
1371
1363
 
1372
1364
  if count < length:
1373
1365
  return result.failure(
1374
- PysException(
1366
+ PysTraceback(
1375
1367
  ValueError(f"not enough values to unpack (expected {length}, got {count})"),
1376
1368
  context,
1377
1369
  node.position
@@ -1380,7 +1372,7 @@ def visit_declaration_AssignNode(node, context, value, operand=TOKENS['EQUAL']):
1380
1372
 
1381
1373
  elif count > length:
1382
1374
  return result.failure(
1383
- PysException(
1375
+ PysTraceback(
1384
1376
  ValueError(f"to many values to unpack (expected {length})"),
1385
1377
  context,
1386
1378
  node.position