jaclang 0.7.1__py3-none-any.whl → 0.7.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of jaclang might be problematic. Click here for more details.

Files changed (85) hide show
  1. jaclang/cli/cli.py +2 -2
  2. jaclang/compiler/absyntree.py +378 -277
  3. jaclang/compiler/codeloc.py +2 -2
  4. jaclang/compiler/constant.py +2 -0
  5. jaclang/compiler/jac.lark +25 -19
  6. jaclang/compiler/parser.py +115 -92
  7. jaclang/compiler/passes/main/access_modifier_pass.py +15 -9
  8. jaclang/compiler/passes/main/def_impl_match_pass.py +29 -11
  9. jaclang/compiler/passes/main/def_use_pass.py +48 -17
  10. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +49 -30
  11. jaclang/compiler/passes/main/import_pass.py +12 -7
  12. jaclang/compiler/passes/main/pyast_gen_pass.py +110 -47
  13. jaclang/compiler/passes/main/pyast_load_pass.py +49 -13
  14. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +25 -11
  15. jaclang/compiler/passes/main/pyout_pass.py +3 -1
  16. jaclang/compiler/passes/main/registry_pass.py +6 -6
  17. jaclang/compiler/passes/main/sym_tab_build_pass.py +30 -72
  18. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +21 -4
  19. jaclang/compiler/passes/main/tests/test_def_use_pass.py +5 -10
  20. jaclang/compiler/passes/main/tests/test_import_pass.py +8 -0
  21. jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
  22. jaclang/compiler/passes/main/type_check_pass.py +2 -1
  23. jaclang/compiler/passes/tool/jac_formatter_pass.py +44 -11
  24. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +16 -0
  25. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +16 -0
  26. jaclang/compiler/passes/tool/tests/fixtures/doc_string.jac +15 -0
  27. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +7 -5
  28. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +1 -2
  29. jaclang/compiler/passes/transform.py +2 -4
  30. jaclang/{core/registry.py → compiler/semtable.py} +1 -3
  31. jaclang/compiler/symtable.py +39 -31
  32. jaclang/compiler/tests/test_parser.py +2 -2
  33. jaclang/core/aott.py +112 -16
  34. jaclang/core/{construct.py → architype.py} +44 -93
  35. jaclang/core/constructs.py +44 -0
  36. jaclang/core/context.py +157 -0
  37. jaclang/core/importer.py +18 -9
  38. jaclang/core/llms/anthropic.py +31 -2
  39. jaclang/core/llms/base.py +3 -3
  40. jaclang/core/llms/groq.py +4 -1
  41. jaclang/core/llms/huggingface.py +4 -1
  42. jaclang/core/llms/ollama.py +4 -1
  43. jaclang/core/llms/openai.py +6 -2
  44. jaclang/core/llms/togetherai.py +4 -1
  45. jaclang/core/memory.py +53 -2
  46. jaclang/core/test.py +90 -0
  47. jaclang/core/utils.py +2 -2
  48. jaclang/langserve/engine.py +119 -122
  49. jaclang/langserve/server.py +27 -5
  50. jaclang/langserve/tests/fixtures/circle.jac +16 -12
  51. jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
  52. jaclang/langserve/tests/fixtures/circle_pure.impl.jac +8 -4
  53. jaclang/langserve/tests/fixtures/circle_pure.jac +2 -2
  54. jaclang/langserve/tests/test_server.py +114 -0
  55. jaclang/langserve/utils.py +104 -10
  56. jaclang/plugin/builtin.py +1 -1
  57. jaclang/plugin/default.py +46 -90
  58. jaclang/plugin/feature.py +32 -16
  59. jaclang/plugin/spec.py +17 -19
  60. jaclang/plugin/tests/test_features.py +0 -33
  61. jaclang/settings.py +4 -0
  62. jaclang/tests/fixtures/abc.jac +16 -12
  63. jaclang/tests/fixtures/byllmissue.jac +12 -0
  64. jaclang/tests/fixtures/edgetypetest.jac +16 -0
  65. jaclang/tests/fixtures/hash_init_check.jac +17 -0
  66. jaclang/tests/fixtures/impl_match_confused.impl.jac +1 -0
  67. jaclang/tests/fixtures/impl_match_confused.jac +5 -0
  68. jaclang/tests/fixtures/math_question.jpg +0 -0
  69. jaclang/tests/fixtures/maxfail_run_test.jac +17 -5
  70. jaclang/tests/fixtures/nosigself.jac +19 -0
  71. jaclang/tests/fixtures/run_test.jac +17 -5
  72. jaclang/tests/fixtures/walker_override.jac +21 -0
  73. jaclang/tests/fixtures/with_llm_vision.jac +25 -0
  74. jaclang/tests/test_bugs.py +19 -0
  75. jaclang/tests/test_cli.py +1 -1
  76. jaclang/tests/test_language.py +116 -11
  77. jaclang/tests/test_reference.py +1 -1
  78. jaclang/utils/lang_tools.py +5 -4
  79. jaclang/utils/test.py +2 -1
  80. jaclang/utils/treeprinter.py +35 -4
  81. {jaclang-0.7.1.dist-info → jaclang-0.7.5.dist-info}/METADATA +3 -2
  82. {jaclang-0.7.1.dist-info → jaclang-0.7.5.dist-info}/RECORD +84 -71
  83. jaclang/core/shelve_storage.py +0 -55
  84. {jaclang-0.7.1.dist-info → jaclang-0.7.5.dist-info}/WHEEL +0 -0
  85. {jaclang-0.7.1.dist-info → jaclang-0.7.5.dist-info}/entry_points.txt +0 -0
@@ -9,7 +9,7 @@ body field.
9
9
  import jaclang.compiler.absyntree as ast
10
10
  from jaclang.compiler.passes import Pass
11
11
  from jaclang.compiler.passes.main import SubNodeTabPass
12
- from jaclang.compiler.symtable import Symbol, SymbolTable, SymbolType
12
+ from jaclang.compiler.symtable import Symbol, SymbolTable
13
13
 
14
14
 
15
15
  class DeclImplMatchPass(Pass):
@@ -28,35 +28,42 @@ class DeclImplMatchPass(Pass):
28
28
  """Rebuild sub node table."""
29
29
  self.ir = SubNodeTabPass(input_ir=self.ir, prior=self).ir
30
30
 
31
- def defn_lookup(self, lookup: Symbol) -> ast.AstImplNeedingNode | None:
31
+ def defn_lookup(self, lookup: Symbol) -> ast.NameAtom | None:
32
32
  """Lookup a definition in a symbol table."""
33
33
  for defn in range(len(lookup.defn)):
34
34
  candidate = lookup.defn[len(lookup.defn) - (defn + 1)]
35
- if isinstance(candidate, ast.AstImplNeedingNode) and candidate.needs_impl:
35
+ if (
36
+ isinstance(candidate.name_of, ast.AstImplNeedingNode)
37
+ and candidate.name_of.needs_impl
38
+ ):
36
39
  return candidate
37
40
  return None
38
41
 
39
42
  def connect_def_impl(self, sym_tab: SymbolTable) -> None:
40
43
  """Connect Decls and Defs."""
41
44
  for sym in sym_tab.tab.values():
42
- if sym.sym_type == SymbolType.IMPL:
45
+ if isinstance(sym.decl.name_of, ast.AstImplOnlyNode):
43
46
  # currently strips the type info from impls
44
47
  arch_refs = [x[3:] for x in sym.sym_name.split(".")]
48
+ name_of_links: list[ast.NameAtom] = [] # to link archref names to decls
45
49
  lookup = sym_tab.lookup(arch_refs[0])
46
- # Below may need to be a while instead of if to skip over local
50
+ # If below may need to be a while instead of if to skip over local
47
51
  # import name collisions (see test: test_impl_decl_resolution_fix)
48
- if lookup and not isinstance(lookup.decl, ast.AstImplNeedingNode):
52
+ if lookup and not isinstance(
53
+ lookup.decl.name_of, ast.AstImplNeedingNode
54
+ ):
49
55
  lookup = sym_tab.parent.lookup(arch_refs[0])
50
56
  decl_node = (
51
57
  self.defn_lookup(lookup)
52
58
  if len(arch_refs) == 1 and lookup
53
59
  else lookup.defn[-1] if lookup else None
54
60
  )
61
+ name_of_links.append(decl_node) if decl_node else None
55
62
  for name in arch_refs[1:]:
56
63
  if decl_node:
57
64
  lookup = (
58
- decl_node.sym_tab.lookup(name)
59
- if decl_node.sym_tab
65
+ decl_node.name_of.sym_tab.lookup(name, deep=False)
66
+ if decl_node.name_of.sym_tab
60
67
  else None
61
68
  )
62
69
  decl_node = (
@@ -64,6 +71,7 @@ class DeclImplMatchPass(Pass):
64
71
  if len(arch_refs) == 1 and lookup
65
72
  else lookup.defn[-1] if lookup else None
66
73
  )
74
+ name_of_links.append(decl_node) if decl_node else None
67
75
  else:
68
76
  break
69
77
  if not decl_node:
@@ -74,8 +82,18 @@ class DeclImplMatchPass(Pass):
74
82
  decl_node,
75
83
  )
76
84
  continue
77
- decl_node.body = sym.decl # type: ignore
78
- sym.decl.decl_link = decl_node # type: ignore
79
- decl_node.sym_tab.tab = sym.decl.sym_tab.tab # type: ignore
85
+ if not isinstance(
86
+ valid_decl := decl_node.name_of, ast.AstImplNeedingNode
87
+ ) or not (valid_decl.sym_tab and sym.decl.name_of.sym_tab):
88
+ raise self.ice(
89
+ f"Expected AstImplNeedingNode, got {valid_decl.__class__.__name__}. Not possible."
90
+ )
91
+ valid_decl.body = sym.decl.name_of
92
+ sym.decl.name_of.decl_link = valid_decl
93
+ for idx, a in enumerate(sym.decl.name_of.target.archs):
94
+ a.name_spec.name_of = name_of_links[idx].name_of
95
+ a.name_spec.sym = name_of_links[idx].sym
96
+ sym.decl.name_of.sym_tab.tab.update(valid_decl.sym_tab.tab)
97
+ valid_decl.sym_tab.tab = sym.decl.name_of.sym_tab.tab
80
98
  for i in sym_tab.kid:
81
99
  self.connect_def_impl(i)
@@ -19,29 +19,60 @@ class DefUsePass(SymTabPass):
19
19
  def after_pass(self) -> None:
20
20
  """After pass."""
21
21
 
22
+ def inherit_baseclasses_sym(self, node: ast.Architype | ast.Enum) -> None:
23
+ """Inherit base classes symbol tables."""
24
+ if node.base_classes:
25
+ for cls in node.base_classes.items:
26
+ if (
27
+ isinstance(cls, ast.AstSymbolNode)
28
+ and (found := self.use_lookup(cls))
29
+ and found
30
+ and found.decl.sym_tab
31
+ and node.sym_tab
32
+ ):
33
+ node.sym_tab.inherit.append(found.decl.sym_tab)
34
+
22
35
  def enter_architype(self, node: ast.Architype) -> None:
23
36
  """Sub objects.
24
37
 
25
38
  name: Name,
26
- doc: Optional[Token],
27
- body: Optional[SubNodeList[ArchStmt]],
28
- sym_tab: Optional[SymbolTable],
39
+ arch_type: Token,
40
+ access: Optional[SubTag[Token]],
41
+ base_classes: Optional[SubNodeList[Expr]],
42
+ body: Optional[SubNodeList[ArchBlockStmt] | ArchDef],
43
+ doc: Optional[String] = None,
44
+ semstr: Optional[String] = None,
45
+ decorators: Optional[SubNodeList[Expr]] = None,
29
46
  """
47
+ self.inherit_baseclasses_sym(node)
48
+
49
+ def inform_from_walker(node: ast.AstNode) -> None:
50
+ for i in (
51
+ node.get_all_sub_nodes(ast.VisitStmt)
52
+ + node.get_all_sub_nodes(ast.IgnoreStmt)
53
+ + node.get_all_sub_nodes(ast.DisengageStmt)
54
+ + node.get_all_sub_nodes(ast.EdgeOpRef)
55
+ ):
56
+ i.from_walker = True
57
+
30
58
  if node.arch_type.name == Tok.KW_WALKER:
31
- self.inform_from_walker(node)
59
+ inform_from_walker(node)
32
60
  for i in self.get_all_sub_nodes(node, ast.Ability):
33
61
  if isinstance(i.body, ast.AbilityDef):
34
- self.inform_from_walker(i.body)
35
-
36
- def inform_from_walker(self, node: ast.AstNode) -> None:
37
- """Inform all sub nodes that they are from a walker."""
38
- for i in (
39
- self.get_all_sub_nodes(node, ast.VisitStmt)
40
- + self.get_all_sub_nodes(node, ast.IgnoreStmt)
41
- + self.get_all_sub_nodes(node, ast.DisengageStmt)
42
- + self.get_all_sub_nodes(node, ast.EdgeOpRef)
43
- ):
44
- i.from_walker = True
62
+ inform_from_walker(i.body)
63
+
64
+ def enter_enum(self, node: ast.Enum) -> None:
65
+ """Sub objects.
66
+
67
+ name: Name,
68
+ access: Optional[SubTag[Token]],
69
+ base_classes: Optional[SubNodeList[Expr]],
70
+ body: Optional[SubNodeList[EnumBlockStmt] | EnumDef],
71
+ doc: Optional[String] = None,
72
+ semstr: Optional[String] = None,
73
+ decorators: Optional[SubNodeList[Expr]] = None,
74
+ """
75
+ self.inherit_baseclasses_sym(node)
45
76
 
46
77
  def enter_arch_ref(self, node: ast.ArchRef) -> None:
47
78
  """Sub objects.
@@ -296,9 +327,9 @@ class DefUsePass(SymTabPass):
296
327
  )
297
328
  for i in items:
298
329
  if isinstance(i, ast.AtomTrailer):
299
- self.unwind_atom_trailer(i)[-1].py_ctx_func = ast3.Del
330
+ self.unwind_atom_trailer(i)[-1].name_spec.py_ctx_func = ast3.Del
300
331
  elif isinstance(i, ast.AstSymbolNode):
301
- i.py_ctx_func = ast3.Del
332
+ i.name_spec.py_ctx_func = ast3.Del
302
333
  else:
303
334
  self.error("Delete target not valid")
304
335
 
@@ -46,7 +46,7 @@ class FuseTypeInfoPass(Pass):
46
46
  )
47
47
 
48
48
  def __set_sym_table_link(self, node: ast.AstSymbolNode) -> None:
49
- typ = node.sym_info.typ.split(".")
49
+ typ = node.sym_type.split(".")
50
50
  typ_sym_table = self.ir.sym_tab
51
51
 
52
52
  if typ[0] == "builtins":
@@ -63,7 +63,7 @@ class FuseTypeInfoPass(Pass):
63
63
  typ_sym_table = f
64
64
 
65
65
  if typ_sym_table != self.ir.sym_tab:
66
- node.sym_info.typ_sym_table = typ_sym_table
66
+ node.name_spec.type_sym_tab = typ_sym_table
67
67
 
68
68
  @staticmethod
69
69
  def __handle_node(
@@ -129,9 +129,11 @@ class FuseTypeInfoPass(Pass):
129
129
  if isinstance(mypy_node, MypyNodes.MemberExpr):
130
130
  if mypy_node in self.node_type_hash:
131
131
  t = str(self.node_type_hash[mypy_node])
132
- if "->" in t:
132
+ if "def" in t and "->" in t:
133
133
  t = t.split("->")[1].strip()
134
- node.sym_info.typ = t
134
+ elif "def" in t:
135
+ t = "None"
136
+ node.name_spec.sym_type = t
135
137
  else:
136
138
  self.__debug_print(f"{node.loc} MemberExpr type is not found")
137
139
 
@@ -143,16 +145,16 @@ class FuseTypeInfoPass(Pass):
143
145
  self.__call_type_handler(node, mypy_node.type)
144
146
 
145
147
  elif isinstance(mypy_node, MypyNodes.MypyFile):
146
- node.sym_info = ast.SymbolInfo("types.ModuleType")
148
+ node.name_spec.sym_type = "types.ModuleType"
147
149
 
148
150
  elif isinstance(mypy_node, MypyNodes.TypeInfo):
149
- node.sym_info = ast.SymbolInfo(mypy_node.fullname)
151
+ node.name_spec.sym_type = mypy_node.fullname
150
152
 
151
153
  elif isinstance(mypy_node, MypyNodes.OverloadedFuncDef):
152
154
  self.__call_type_handler(node, mypy_node.items[0].func.type)
153
155
 
154
156
  elif mypy_node is None:
155
- node.sym_info = ast.SymbolInfo("None")
157
+ node.name_spec.sym_type = "None"
156
158
 
157
159
  else:
158
160
  self.__debug_print(
@@ -162,7 +164,7 @@ class FuseTypeInfoPass(Pass):
162
164
 
163
165
  else:
164
166
  if isinstance(mypy_node, MypyNodes.ClassDef):
165
- node.sym_info.typ = mypy_node.fullname
167
+ node.name_spec.sym_type = mypy_node.fullname
166
168
  self.__set_sym_table_link(node)
167
169
  elif isinstance(mypy_node, MypyNodes.FuncDef):
168
170
  self.__call_type_handler(node, mypy_node.type)
@@ -177,10 +179,22 @@ class FuseTypeInfoPass(Pass):
177
179
  )
178
180
 
179
181
  @__handle_node
180
- def enter_name(self, node: ast.NameSpec) -> None:
182
+ def enter_name(self, node: ast.NameAtom) -> None:
181
183
  """Pass handler for name nodes."""
182
184
  self.__collect_type_from_symbol(node)
183
185
 
186
+ # Assign correct symbols to sym_link in case of
187
+ # AtomTrailer Object
188
+ if isinstance(node.parent, ast.AtomTrailer):
189
+ target_node = node.parent.target
190
+ if isinstance(target_node, ast.AstSymbolNode):
191
+ parent_symbol_table = target_node.type_sym_tab
192
+ if isinstance(parent_symbol_table, ast.SymbolTable):
193
+ owner = parent_symbol_table.owner
194
+ if isinstance(owner, ast.AstSymbolNode):
195
+ target_node.name_spec.sym = owner.sym
196
+ node.sym = parent_symbol_table.lookup(node.sym_name)
197
+
184
198
  @__handle_node
185
199
  def enter_module_path(self, node: ast.ModulePath) -> None:
186
200
  """Pass handler for ModulePath nodes."""
@@ -263,10 +277,15 @@ class FuseTypeInfoPass(Pass):
263
277
  "Getting type of 'HasVar' is only supported with AssignmentStmt"
264
278
  )
265
279
 
280
+ def exit_has_var(self, node: ast.HasVar) -> None:
281
+ """Pass handler for HasVar nodes."""
282
+ node.name_spec.sym_type = node.name.sym_type
283
+ node.name_spec.type_sym_tab = node.name.type_sym_tab
284
+
266
285
  @__handle_node
267
286
  def enter_multi_string(self, node: ast.MultiString) -> None:
268
287
  """Pass handler for MultiString nodes."""
269
- node.sym_info = ast.SymbolInfo("builtins.str")
288
+ node.name_spec.sym_type = "builtins.str"
270
289
 
271
290
  @__handle_node
272
291
  def enter_f_string(self, node: ast.FString) -> None:
@@ -278,48 +297,48 @@ class FuseTypeInfoPass(Pass):
278
297
  """Pass handler for ListVal nodes."""
279
298
  mypy_node = node.gen.mypy_ast[0]
280
299
  if mypy_node in self.node_type_hash:
281
- node.sym_info.typ = str(self.node_type_hash[mypy_node])
300
+ node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
282
301
  else:
283
- node.sym_info.typ = "builtins.list"
302
+ node.name_spec.sym_type = "builtins.list"
284
303
 
285
304
  @__handle_node
286
305
  def enter_set_val(self, node: ast.SetVal) -> None:
287
306
  """Pass handler for SetVal nodes."""
288
307
  mypy_node = node.gen.mypy_ast[0]
289
308
  if mypy_node in self.node_type_hash:
290
- node.sym_info.typ = str(self.node_type_hash[mypy_node])
309
+ node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
291
310
  else:
292
- node.sym_info.typ = "builtins.set"
311
+ node.name_spec.sym_type = "builtins.set"
293
312
 
294
313
  @__handle_node
295
314
  def enter_tuple_val(self, node: ast.TupleVal) -> None:
296
315
  """Pass handler for TupleVal nodes."""
297
316
  mypy_node = node.gen.mypy_ast[0]
298
317
  if mypy_node in self.node_type_hash:
299
- node.sym_info.typ = str(self.node_type_hash[mypy_node])
318
+ node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
300
319
  else:
301
- node.sym_info.typ = "builtins.tuple"
320
+ node.name_spec.sym_type = "builtins.tuple"
302
321
 
303
322
  @__handle_node
304
323
  def enter_dict_val(self, node: ast.DictVal) -> None:
305
324
  """Pass handler for DictVal nodes."""
306
325
  mypy_node = node.gen.mypy_ast[0]
307
326
  if mypy_node in self.node_type_hash:
308
- node.sym_info.typ = str(self.node_type_hash[mypy_node])
327
+ node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
309
328
  else:
310
- node.sym_info.typ = "builtins.dict"
329
+ node.name_spec.sym_type = "builtins.dict"
311
330
 
312
331
  @__handle_node
313
332
  def enter_list_compr(self, node: ast.ListCompr) -> None:
314
333
  """Pass handler for ListCompr nodes."""
315
334
  mypy_node = node.gen.mypy_ast[0]
316
- node.sym_info.typ = str(self.node_type_hash[mypy_node])
335
+ node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
317
336
 
318
337
  @__handle_node
319
338
  def enter_dict_compr(self, node: ast.DictCompr) -> None:
320
339
  """Pass handler for DictCompr nodes."""
321
340
  mypy_node = node.gen.mypy_ast[0]
322
- node.sym_info.typ = str(self.node_type_hash[mypy_node])
341
+ node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
323
342
 
324
343
  @__handle_node
325
344
  def enter_index_slice(self, node: ast.IndexSlice) -> None:
@@ -331,7 +350,7 @@ class FuseTypeInfoPass(Pass):
331
350
  """Pass handler for ArchRef nodes."""
332
351
  if isinstance(node.gen.mypy_ast[0], MypyNodes.ClassDef):
333
352
  mypy_node: MypyNodes.ClassDef = node.gen.mypy_ast[0]
334
- node.sym_info.typ = mypy_node.fullname
353
+ node.name_spec.sym_type = mypy_node.fullname
335
354
  self.__set_sym_table_link(node)
336
355
  elif isinstance(node.gen.mypy_ast[0], MypyNodes.FuncDef):
337
356
  mypy_node2: MypyNodes.FuncDef = node.gen.mypy_ast[0]
@@ -365,22 +384,22 @@ class FuseTypeInfoPass(Pass):
365
384
  @__handle_node
366
385
  def enter_int(self, node: ast.Int) -> None:
367
386
  """Pass handler for Int nodes."""
368
- node.sym_info.typ = "builtins.int"
387
+ node.name_spec.sym_type = "builtins.int"
369
388
 
370
389
  @__handle_node
371
390
  def enter_float(self, node: ast.Float) -> None:
372
391
  """Pass handler for Float nodes."""
373
- node.sym_info.typ = "builtins.float"
392
+ node.name_spec.sym_type = "builtins.float"
374
393
 
375
394
  @__handle_node
376
395
  def enter_string(self, node: ast.String) -> None:
377
396
  """Pass handler for String nodes."""
378
- node.sym_info.typ = "builtins.str"
397
+ node.name_spec.sym_type = "builtins.str"
379
398
 
380
399
  @__handle_node
381
400
  def enter_bool(self, node: ast.Bool) -> None:
382
401
  """Pass handler for Bool nodes."""
383
- node.sym_info.typ = "builtins.bool"
402
+ node.name_spec.sym_type = "builtins.bool"
384
403
 
385
404
  @__handle_node
386
405
  def enter_builtin_type(self, node: ast.BuiltinType) -> None:
@@ -391,13 +410,13 @@ class FuseTypeInfoPass(Pass):
391
410
  self, node: ast.AstSymbolNode, mypy_type: MypyTypes.Instance
392
411
  ) -> None:
393
412
  """Get type info from mypy type Instance."""
394
- node.sym_info = ast.SymbolInfo(str(mypy_type))
413
+ node.name_spec.sym_type = str(mypy_type)
395
414
 
396
415
  def get_type_from_callable_type(
397
416
  self, node: ast.AstSymbolNode, mypy_type: MypyTypes.CallableType
398
417
  ) -> None:
399
418
  """Get type info from mypy type CallableType."""
400
- node.sym_info = ast.SymbolInfo(str(mypy_type.ret_type))
419
+ node.name_spec.sym_type = str(mypy_type.ret_type)
401
420
 
402
421
  # TODO: Which overloaded function to get the return value from?
403
422
  def get_type_from_overloaded(
@@ -410,16 +429,16 @@ class FuseTypeInfoPass(Pass):
410
429
  self, node: ast.AstSymbolNode, mypy_type: MypyTypes.NoneType
411
430
  ) -> None:
412
431
  """Get type info from mypy type NoneType."""
413
- node.sym_info = ast.SymbolInfo("None")
432
+ node.name_spec.sym_type = "None"
414
433
 
415
434
  def get_type_from_any_type(
416
435
  self, node: ast.AstSymbolNode, mypy_type: MypyTypes.AnyType
417
436
  ) -> None:
418
437
  """Get type info from mypy type NoneType."""
419
- node.sym_info = ast.SymbolInfo("Any")
438
+ node.name_spec.sym_type = "Any"
420
439
 
421
440
  def get_type_from_tuple_type(
422
441
  self, node: ast.AstSymbolNode, mypy_type: MypyTypes.TupleType
423
442
  ) -> None:
424
443
  """Get type info from mypy type TupleType."""
425
- node.sym_info = ast.SymbolInfo("builtins.tuple")
444
+ node.name_spec.sym_type = "builtins.tuple"
@@ -63,6 +63,8 @@ class JacImportPass(Pass):
63
63
 
64
64
  def __annex_impl(self, node: ast.Module) -> None:
65
65
  """Annex impl and test modules."""
66
+ if node.stub_only:
67
+ return
66
68
  if not node.loc.mod_path:
67
69
  self.error("Module has no path")
68
70
  if not node.loc.mod_path.endswith(".jac"):
@@ -105,7 +107,7 @@ class JacImportPass(Pass):
105
107
  ) and cur_file.endswith(".test.jac"):
106
108
  mod = self.import_jac_mod_from_file(cur_file)
107
109
  if mod:
108
- node.test_mod = mod
110
+ node.test_mod.append(mod)
109
111
  node.add_kids_right([mod], pos_update=False)
110
112
  mod.parent = node
111
113
 
@@ -167,6 +169,7 @@ class JacImportPass(Pass):
167
169
  doc=None,
168
170
  body=[],
169
171
  is_imported=False,
172
+ stub_only=True,
170
173
  kid=[ast.EmptyToken()],
171
174
  )
172
175
 
@@ -201,15 +204,17 @@ class JacImportPass(Pass):
201
204
  class PyImportPass(JacImportPass):
202
205
  """Jac statically imports Python modules."""
203
206
 
207
+ def before_pass(self) -> None:
208
+ """Only run pass if settings are set to raise python."""
209
+ if not settings.py_raise:
210
+ self.terminate()
211
+ else:
212
+ return super().before_pass()
213
+
204
214
  def process_import(self, node: ast.Module, i: ast.ModulePath) -> None:
205
215
  """Process an import."""
206
216
  lang = i.parent_of_type(ast.Import).hint.tag.value
207
- if (
208
- lang == "py"
209
- and not i.sub_module
210
- and settings.py_raise
211
- and not is_standard_lib_module(i.path_str)
212
- ):
217
+ if lang == "py" and not i.sub_module and not is_standard_lib_module(i.path_str):
213
218
  mod = self.import_py_module(node=i, mod_path=node.loc.mod_path)
214
219
  if mod:
215
220
  i.sub_module = mod