jaclang 0.5.11__py3-none-any.whl → 0.5.15__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 (43) hide show
  1. jaclang/cli/cli.py +20 -0
  2. jaclang/compiler/__init__.py +35 -19
  3. jaclang/compiler/absyntree.py +103 -95
  4. jaclang/compiler/generated/jac_parser.py +4069 -0
  5. jaclang/compiler/jac.lark +655 -0
  6. jaclang/compiler/parser.py +44 -31
  7. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +92 -37
  8. jaclang/compiler/passes/main/import_pass.py +8 -5
  9. jaclang/compiler/passes/main/pyast_gen_pass.py +512 -352
  10. jaclang/compiler/passes/main/pyast_load_pass.py +271 -64
  11. jaclang/compiler/passes/main/registry_pass.py +3 -7
  12. jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +2 -0
  13. jaclang/compiler/passes/main/type_check_pass.py +4 -1
  14. jaclang/compiler/passes/tool/jac_formatter_pass.py +7 -0
  15. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +16 -0
  16. jaclang/compiler/passes/utils/mypy_ast_build.py +93 -0
  17. jaclang/compiler/tests/test_importer.py +15 -0
  18. jaclang/core/aott.py +4 -3
  19. jaclang/core/construct.py +1 -1
  20. jaclang/core/importer.py +109 -51
  21. jaclang/core/llms.py +29 -0
  22. jaclang/core/registry.py +22 -0
  23. jaclang/core/utils.py +72 -0
  24. jaclang/plugin/default.py +118 -6
  25. jaclang/plugin/feature.py +29 -2
  26. jaclang/plugin/spec.py +25 -2
  27. jaclang/utils/helpers.py +7 -9
  28. jaclang/utils/lang_tools.py +37 -13
  29. jaclang/utils/test.py +1 -3
  30. jaclang/utils/tests/test_lang_tools.py +6 -0
  31. jaclang/vendor/lark/grammars/common.lark +59 -0
  32. jaclang/vendor/lark/grammars/lark.lark +62 -0
  33. jaclang/vendor/lark/grammars/python.lark +302 -0
  34. jaclang/vendor/lark/grammars/unicode.lark +7 -0
  35. {jaclang-0.5.11.dist-info → jaclang-0.5.15.dist-info}/METADATA +1 -1
  36. {jaclang-0.5.11.dist-info → jaclang-0.5.15.dist-info}/RECORD +40 -36
  37. jaclang/compiler/__jac_gen__/jac_parser.py +0 -4069
  38. jaclang/compiler/tests/fixtures/__jac_gen__/__init__.py +0 -0
  39. jaclang/compiler/tests/fixtures/__jac_gen__/hello_world.py +0 -5
  40. /jaclang/compiler/{__jac_gen__ → generated}/__init__.py +0 -0
  41. {jaclang-0.5.11.dist-info → jaclang-0.5.15.dist-info}/WHEEL +0 -0
  42. {jaclang-0.5.11.dist-info → jaclang-0.5.15.dist-info}/entry_points.txt +0 -0
  43. {jaclang-0.5.11.dist-info → jaclang-0.5.15.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
-
5
+ import keyword
6
6
  import logging
7
7
  import os
8
8
  from typing import Callable, TypeAlias
@@ -167,7 +167,6 @@ class JacParser(Pass):
167
167
  """Grammar rule.
168
168
 
169
169
  element: py_code_block
170
- | include_stmt
171
170
  | import_stmt
172
171
  | ability
173
172
  | architype
@@ -283,7 +282,10 @@ class JacParser(Pass):
283
282
 
284
283
  import_stmt: KW_IMPORT sub_name KW_FROM from_path COMMA import_items SEMI
285
284
  | KW_IMPORT sub_name import_path (COMMA import_path)* SEMI
285
+ | include_stmt
286
286
  """
287
+ if len(kid) == 1 and isinstance(kid[0], ast.Import):
288
+ return self.nu(kid[0])
287
289
  lang = kid[1]
288
290
  paths = [i for i in kid if isinstance(i, ast.ModulePath)]
289
291
 
@@ -2321,16 +2323,34 @@ class JacParser(Pass):
2321
2323
  def atomic_call(self, kid: list[ast.AstNode]) -> ast.FuncCall:
2322
2324
  """Grammar rule.
2323
2325
 
2324
- atomic_call: atomic_chain LPAREN param_list? RPAREN
2326
+ atomic_call: atomic_chain LPAREN param_list? (KW_BY atomic_call)? RPAREN
2325
2327
  """
2328
+ if (
2329
+ len(kid) > 4
2330
+ and isinstance(kid[0], ast.Expr)
2331
+ and kid[-2]
2332
+ and isinstance(kid[-2], ast.FuncCall)
2333
+ ):
2334
+ return self.nu(
2335
+ ast.FuncCall(
2336
+ target=kid[0],
2337
+ params=kid[2] if isinstance(kid[2], ast.SubNodeList) else None,
2338
+ genai_call=kid[-2],
2339
+ kid=kid,
2340
+ )
2341
+ )
2326
2342
  if (
2327
2343
  len(kid) == 4
2328
2344
  and isinstance(kid[0], ast.Expr)
2329
2345
  and isinstance(kid[2], ast.SubNodeList)
2330
2346
  ):
2331
- return self.nu(ast.FuncCall(target=kid[0], params=kid[2], kid=kid))
2347
+ return self.nu(
2348
+ ast.FuncCall(target=kid[0], params=kid[2], genai_call=None, kid=kid)
2349
+ )
2332
2350
  elif len(kid) == 3 and isinstance(kid[0], ast.Expr):
2333
- return self.nu(ast.FuncCall(target=kid[0], params=None, kid=kid))
2351
+ return self.nu(
2352
+ ast.FuncCall(target=kid[0], params=None, genai_call=None, kid=kid)
2353
+ )
2334
2354
  else:
2335
2355
  raise self.ice()
2336
2356
 
@@ -3814,21 +3834,7 @@ class JacParser(Pass):
3814
3834
  def __default_token__(self, token: jl.Token) -> ast.Token:
3815
3835
  """Token handler."""
3816
3836
  ret_type = ast.Token
3817
- if token.type == Tok.KWESC_NAME:
3818
- return self.nu(
3819
- ast.Name(
3820
- file_path=self.parse_ref.mod_path,
3821
- name=token.type,
3822
- value=token.value[2:],
3823
- line=token.line if token.line is not None else 0,
3824
- col_start=token.column if token.column is not None else 0,
3825
- col_end=token.end_column if token.end_column is not None else 0,
3826
- pos_start=token.start_pos if token.start_pos is not None else 0,
3827
- pos_end=token.end_pos if token.end_pos is not None else 0,
3828
- is_kwesc=True,
3829
- )
3830
- )
3831
- elif token.type == Tok.NAME:
3837
+ if token.type in [Tok.NAME, Tok.KWESC_NAME]:
3832
3838
  ret_type = ast.Name
3833
3839
  elif token.type == Tok.SEMI:
3834
3840
  ret_type = ast.Semi
@@ -3854,15 +3860,22 @@ class JacParser(Pass):
3854
3860
  ret_type = ast.Bool
3855
3861
  elif token.type == Tok.PYNLINE and isinstance(token.value, str):
3856
3862
  token.value = token.value.replace("::py::", "")
3857
- return self.nu(
3858
- ret_type(
3859
- file_path=self.parse_ref.mod_path,
3860
- name=token.type,
3861
- value=token.value,
3862
- line=token.line if token.line is not None else 0,
3863
- col_start=token.column if token.column is not None else 0,
3864
- col_end=token.end_column if token.end_column is not None else 0,
3865
- pos_start=token.start_pos if token.start_pos is not None else 0,
3866
- pos_end=token.end_pos if token.end_pos is not None else 0,
3867
- )
3863
+ ret = ret_type(
3864
+ file_path=self.parse_ref.mod_path,
3865
+ name=token.type,
3866
+ value=token.value[2:] if token.type == Tok.KWESC_NAME else token.value,
3867
+ line=token.line if token.line is not None else 0,
3868
+ col_start=token.column if token.column is not None else 0,
3869
+ col_end=token.end_column if token.end_column is not None else 0,
3870
+ pos_start=token.start_pos if token.start_pos is not None else 0,
3871
+ pos_end=token.end_pos if token.end_pos is not None else 0,
3868
3872
  )
3873
+ if isinstance(ret, ast.Name):
3874
+ if token.type == Tok.KWESC_NAME:
3875
+ ret.is_kwesc = True
3876
+ if ret.value in keyword.kwlist:
3877
+ err = jl.UnexpectedInput(f"Python keyword {ret.value} used as name")
3878
+ err.line = ret.loc.first_line
3879
+ err.column = ret.loc.col_start
3880
+ raise err
3881
+ return self.nu(ret)
@@ -13,9 +13,11 @@ from typing import Callable, TypeVar
13
13
  import jaclang.compiler.absyntree as ast
14
14
  from jaclang.compiler.passes import Pass
15
15
  from jaclang.utils.helpers import pascal_to_snake
16
+ from jaclang.vendor.mypy.nodes import Node as VNode # bit of a hack
16
17
 
17
- import mypy.nodes as MypyNode # noqa N812
18
+ import mypy.nodes as MypyNodes # noqa N812
18
19
  import mypy.types as MypyTypes # noqa N812
20
+ from mypy.checkexpr import Type as MyType
19
21
 
20
22
 
21
23
  T = TypeVar("T", bound=ast.AstSymbolNode)
@@ -24,6 +26,8 @@ T = TypeVar("T", bound=ast.AstSymbolNode)
24
26
  class FuseTypeInfoPass(Pass):
25
27
  """Python and bytecode file self.__debug_printing pass."""
26
28
 
29
+ node_type_hash: dict[MypyNodes.Node | VNode, MyType] = {}
30
+
27
31
  def __debug_print(self, *argv: object) -> None:
28
32
  if "FuseTypeInfoDebug" in os.environ:
29
33
  print("FuseTypeInfo::", *argv)
@@ -89,7 +93,9 @@ class FuseTypeInfoPass(Pass):
89
93
  jac_node_str, "has multiple mypy nodes associated to it"
90
94
  )
91
95
  else:
92
- # self.__debug_print(jac_node_str, "has duplicate mypy nodes associated to it")
96
+ self.__debug_print(
97
+ jac_node_str, "has duplicate mypy nodes associated to it"
98
+ )
93
99
  func(self, node)
94
100
  self.__set_sym_table_link(node)
95
101
 
@@ -108,32 +114,28 @@ class FuseTypeInfoPass(Pass):
108
114
 
109
115
  return node_handler
110
116
 
111
- def enter_import(self, node: ast.Import) -> None:
112
- """Pass handler for import nodes."""
113
- # Pruning the import nodes
114
- self.prune()
115
-
116
- @__handle_node
117
- def enter_name(self, node: ast.NameSpec) -> None:
118
- """Pass handler for name nodes."""
117
+ def __collect_type_from_symbol(self, node: ast.AstSymbolNode) -> None:
119
118
  mypy_node = node.gen.mypy_ast[0]
120
119
 
121
120
  if hasattr(mypy_node, "node"):
122
121
  # orig_node = mypy_node
123
122
  mypy_node = mypy_node.node
124
123
 
125
- if isinstance(mypy_node, (MypyNode.Var, MypyNode.FuncDef)):
124
+ if isinstance(mypy_node, (MypyNodes.Var, MypyNodes.FuncDef)):
126
125
  self.__call_type_handler(node, mypy_node.type)
127
126
 
128
- elif isinstance(mypy_node, MypyNode.MypyFile):
127
+ elif isinstance(mypy_node, MypyNodes.MypyFile):
129
128
  node.sym_info = ast.SymbolInfo("types.ModuleType")
130
129
 
131
- elif isinstance(mypy_node, MypyNode.TypeInfo):
130
+ elif isinstance(mypy_node, MypyNodes.TypeInfo):
132
131
  node.sym_info = ast.SymbolInfo(mypy_node.fullname)
133
132
 
134
- elif isinstance(mypy_node, MypyNode.OverloadedFuncDef):
133
+ elif isinstance(mypy_node, MypyNodes.OverloadedFuncDef):
135
134
  self.__call_type_handler(node, mypy_node.items[0].func.type)
136
135
 
136
+ elif mypy_node is None:
137
+ node.sym_info = ast.SymbolInfo("None")
138
+
137
139
  else:
138
140
  self.__debug_print(
139
141
  f'"{node.loc}::{node.__class__.__name__}" mypy (with node attr) node isn\'t supported',
@@ -141,19 +143,31 @@ class FuseTypeInfoPass(Pass):
141
143
  )
142
144
 
143
145
  else:
144
- if isinstance(mypy_node, MypyNode.ClassDef):
146
+ if isinstance(mypy_node, MypyNodes.ClassDef):
145
147
  node.sym_info.typ = mypy_node.fullname
146
148
  self.__set_sym_table_link(node)
147
- elif isinstance(mypy_node, MypyNode.FuncDef):
149
+ elif isinstance(mypy_node, MypyNodes.FuncDef):
148
150
  self.__call_type_handler(node, mypy_node.type)
149
- elif isinstance(mypy_node, MypyNode.Argument):
151
+ elif isinstance(mypy_node, MypyNodes.Argument):
150
152
  self.__call_type_handler(node, mypy_node.variable.type)
153
+ elif isinstance(mypy_node, MypyNodes.Decorator):
154
+ self.__call_type_handler(node, mypy_node.func.type.ret_type)
151
155
  else:
152
156
  self.__debug_print(
153
157
  f'"{node.loc}::{node.__class__.__name__}" mypy node isn\'t supported',
154
158
  type(mypy_node),
155
159
  )
156
160
 
161
+ def enter_import(self, node: ast.Import) -> None:
162
+ """Pass handler for import nodes."""
163
+ # Pruning the import nodes
164
+ self.prune()
165
+
166
+ @__handle_node
167
+ def enter_name(self, node: ast.NameSpec) -> None:
168
+ """Pass handler for name nodes."""
169
+ self.__collect_type_from_symbol(node)
170
+
157
171
  @__handle_node
158
172
  def enter_module_path(self, node: ast.ModulePath) -> None:
159
173
  """Pass handler for ModulePath nodes."""
@@ -167,7 +181,7 @@ class FuseTypeInfoPass(Pass):
167
181
  @__handle_node
168
182
  def enter_architype(self, node: ast.Architype) -> None:
169
183
  """Pass handler for Architype nodes."""
170
- self.__debug_print("Getting type not supported in", type(node))
184
+ self.__collect_type_from_symbol(node)
171
185
 
172
186
  @__handle_node
173
187
  def enter_arch_def(self, node: ast.ArchDef) -> None:
@@ -177,7 +191,7 @@ class FuseTypeInfoPass(Pass):
177
191
  @__handle_node
178
192
  def enter_enum(self, node: ast.Enum) -> None:
179
193
  """Pass handler for Enum nodes."""
180
- self.__debug_print("Getting type not supported in", type(node))
194
+ self.__collect_type_from_symbol(node)
181
195
 
182
196
  @__handle_node
183
197
  def enter_enum_def(self, node: ast.EnumDef) -> None:
@@ -187,23 +201,30 @@ class FuseTypeInfoPass(Pass):
187
201
  @__handle_node
188
202
  def enter_ability(self, node: ast.Ability) -> None:
189
203
  """Pass handler for Ability nodes."""
190
- if isinstance(node.gen.mypy_ast[0], MypyNode.FuncDef):
204
+ if isinstance(node.gen.mypy_ast[0], MypyNodes.FuncDef):
191
205
  self.__call_type_handler(node, node.gen.mypy_ast[0].type.ret_type)
192
206
  else:
193
207
  self.__debug_print(
194
- f"{node.loc}: Can't get type of an ability from mypy node other than Ability."
208
+ f"{node.loc}: Can't get type of an ability from mypy node other than Ability.",
209
+ type(node.gen.mypy_ast[0]),
195
210
  )
196
211
 
197
212
  @__handle_node
198
213
  def enter_ability_def(self, node: ast.AbilityDef) -> None:
199
214
  """Pass handler for AbilityDef nodes."""
200
- self.__debug_print("Getting type not supported in", type(node))
215
+ if isinstance(node.gen.mypy_ast[0], MypyNodes.FuncDef):
216
+ self.__call_type_handler(node, node.gen.mypy_ast[0].type.ret_type)
217
+ else:
218
+ self.__debug_print(
219
+ f"{node.loc}: Can't get type of an AbilityDef from mypy node other than FuncDef.",
220
+ type(node.gen.mypy_ast[0]),
221
+ )
201
222
 
202
223
  @__handle_node
203
224
  def enter_param_var(self, node: ast.ParamVar) -> None:
204
225
  """Pass handler for ParamVar nodes."""
205
- if isinstance(node.gen.mypy_ast[0], MypyNode.Argument):
206
- mypy_node: MypyNode.Argument = node.gen.mypy_ast[0]
226
+ if isinstance(node.gen.mypy_ast[0], MypyNodes.Argument):
227
+ mypy_node: MypyNodes.Argument = node.gen.mypy_ast[0]
207
228
  if mypy_node.variable.type:
208
229
  self.__call_type_handler(node, mypy_node.variable.type)
209
230
  else:
@@ -216,9 +237,9 @@ class FuseTypeInfoPass(Pass):
216
237
  def enter_has_var(self, node: ast.HasVar) -> None:
217
238
  """Pass handler for HasVar nodes."""
218
239
  mypy_node = node.gen.mypy_ast[0]
219
- if isinstance(mypy_node, MypyNode.AssignmentStmt):
240
+ if isinstance(mypy_node, MypyNodes.AssignmentStmt):
220
241
  n = mypy_node.lvalues[0].node
221
- if isinstance(n, (MypyNode.Var, MypyNode.FuncDef)):
242
+ if isinstance(n, (MypyNodes.Var, MypyNodes.FuncDef)):
222
243
  self.__call_type_handler(node, n.type)
223
244
  else:
224
245
  self.__debug_print(
@@ -242,32 +263,50 @@ class FuseTypeInfoPass(Pass):
242
263
  @__handle_node
243
264
  def enter_list_val(self, node: ast.ListVal) -> None:
244
265
  """Pass handler for ListVal nodes."""
245
- self.__debug_print("Getting type not supported in", type(node))
266
+ mypy_node = node.gen.mypy_ast[0]
267
+ if mypy_node in self.node_type_hash:
268
+ node.sym_info.typ = str(self.node_type_hash[mypy_node])
269
+ else:
270
+ node.sym_info.typ = "builtins.list"
246
271
 
247
272
  @__handle_node
248
273
  def enter_set_val(self, node: ast.SetVal) -> None:
249
274
  """Pass handler for SetVal nodes."""
250
- self.__debug_print("Getting type not supported in", type(node))
275
+ mypy_node = node.gen.mypy_ast[0]
276
+ if mypy_node in self.node_type_hash:
277
+ node.sym_info.typ = str(self.node_type_hash[mypy_node])
278
+ else:
279
+ node.sym_info.typ = "builtins.set"
251
280
 
252
281
  @__handle_node
253
282
  def enter_tuple_val(self, node: ast.TupleVal) -> None:
254
283
  """Pass handler for TupleVal nodes."""
255
- self.__debug_print("Getting type not supported in", type(node))
284
+ mypy_node = node.gen.mypy_ast[0]
285
+ if mypy_node in self.node_type_hash:
286
+ node.sym_info.typ = str(self.node_type_hash[mypy_node])
287
+ else:
288
+ node.sym_info.typ = "builtins.tuple"
256
289
 
257
290
  @__handle_node
258
291
  def enter_dict_val(self, node: ast.DictVal) -> None:
259
292
  """Pass handler for DictVal nodes."""
260
- self.__debug_print("Getting type not supported in", type(node))
293
+ mypy_node = node.gen.mypy_ast[0]
294
+ if mypy_node in self.node_type_hash:
295
+ node.sym_info.typ = str(self.node_type_hash[mypy_node])
296
+ else:
297
+ node.sym_info.typ = "builtins.dict"
261
298
 
262
299
  @__handle_node
263
300
  def enter_list_compr(self, node: ast.ListCompr) -> None:
264
301
  """Pass handler for ListCompr nodes."""
265
- self.__debug_print("Getting type not supported in", type(node))
302
+ mypy_node = node.gen.mypy_ast[0]
303
+ node.sym_info.typ = str(self.node_type_hash[mypy_node])
266
304
 
267
305
  @__handle_node
268
306
  def enter_dict_compr(self, node: ast.DictCompr) -> None:
269
307
  """Pass handler for DictCompr nodes."""
270
- self.__debug_print("Getting type not supported in", type(node))
308
+ mypy_node = node.gen.mypy_ast[0]
309
+ node.sym_info.typ = str(self.node_type_hash[mypy_node])
271
310
 
272
311
  @__handle_node
273
312
  def enter_index_slice(self, node: ast.IndexSlice) -> None:
@@ -277,13 +316,17 @@ class FuseTypeInfoPass(Pass):
277
316
  @__handle_node
278
317
  def enter_arch_ref(self, node: ast.ArchRef) -> None:
279
318
  """Pass handler for ArchRef nodes."""
280
- if isinstance(node.gen.mypy_ast[0], MypyNode.ClassDef):
281
- mypy_node: MypyNode.ClassDef = node.gen.mypy_ast[0]
319
+ if isinstance(node.gen.mypy_ast[0], MypyNodes.ClassDef):
320
+ mypy_node: MypyNodes.ClassDef = node.gen.mypy_ast[0]
282
321
  node.sym_info.typ = mypy_node.fullname
283
322
  self.__set_sym_table_link(node)
323
+ elif isinstance(node.gen.mypy_ast[0], MypyNodes.FuncDef):
324
+ mypy_node2: MypyNodes.FuncDef = node.gen.mypy_ast[0]
325
+ self.__call_type_handler(node, mypy_node2.type)
284
326
  else:
285
327
  self.__debug_print(
286
- f"{node.loc}: Can't get ArchRef value from mypyNode other than ClassDef"
328
+ f"{node.loc}: Can't get ArchRef value from mypyNode other than ClassDef",
329
+ type(node.gen.mypy_ast[0]),
287
330
  )
288
331
 
289
332
  @__handle_node
@@ -294,7 +337,7 @@ class FuseTypeInfoPass(Pass):
294
337
  @__handle_node
295
338
  def enter_edge_op_ref(self, node: ast.EdgeOpRef) -> None:
296
339
  """Pass handler for EdgeOpRef nodes."""
297
- self.__debug_print("Getting type not supported in", type(node))
340
+ self.__collect_type_from_symbol(node)
298
341
 
299
342
  @__handle_node
300
343
  def enter_filter_compr(self, node: ast.FilterCompr) -> None:
@@ -329,7 +372,7 @@ class FuseTypeInfoPass(Pass):
329
372
  @__handle_node
330
373
  def enter_builtin_type(self, node: ast.BuiltinType) -> None:
331
374
  """Pass handler for BuiltinType nodes."""
332
- self.__debug_print("Getting type not supported in", type(node))
375
+ self.__collect_type_from_symbol(node)
333
376
 
334
377
  def get_type_from_instance(
335
378
  self, node: ast.AstSymbolNode, mypy_type: MypyTypes.Instance
@@ -355,3 +398,15 @@ class FuseTypeInfoPass(Pass):
355
398
  ) -> None:
356
399
  """Get type info from mypy type NoneType."""
357
400
  node.sym_info = ast.SymbolInfo("None")
401
+
402
+ def get_type_from_any_type(
403
+ self, node: ast.AstSymbolNode, mypy_type: MypyTypes.AnyType
404
+ ) -> None:
405
+ """Get type info from mypy type NoneType."""
406
+ node.sym_info = ast.SymbolInfo("Any")
407
+
408
+ def get_type_from_tuple_type(
409
+ self, node: ast.AstSymbolNode, mypy_type: MypyTypes.TupleType
410
+ ) -> None:
411
+ """Get type info from mypy type TupleType."""
412
+ node.sym_info = ast.SymbolInfo("builtins.tuple")
@@ -7,6 +7,7 @@ symbols are available for matching.
7
7
 
8
8
  import ast as py_ast
9
9
  import importlib.util
10
+ import os
10
11
  import sys
11
12
  from os import path
12
13
  from typing import Optional
@@ -47,10 +48,12 @@ class ImportPass(Pass):
47
48
  self.annex_impl(mod)
48
49
  i.sub_module = mod
49
50
  i.add_kids_right([mod], pos_update=False)
50
- # elif i.parent.lang.tag.value == "py":
51
- # mod = self.import_py_module(node=i, mod_path=node.loc.mod_path)
52
- # i.sub_module = mod
53
- # i.add_kids_right([mod], pos_update=False)
51
+ elif i.parent.lang.tag.value == "py" and os.environ.get(
52
+ "JAC_PROC_DEBUG", False
53
+ ):
54
+ mod = self.import_py_module(node=i, mod_path=node.loc.mod_path)
55
+ i.sub_module = mod
56
+ i.add_kids_right([mod], pos_update=False)
54
57
  self.enter_module_path(i)
55
58
  SubNodeTabPass(prior=self, input_ir=node)
56
59
  self.annex_impl(node)
@@ -95,7 +98,7 @@ class ImportPass(Pass):
95
98
  """Import a module."""
96
99
  self.cur_node = node # impacts error reporting
97
100
  target = import_target_to_relative_path(
98
- node.path_str, path.dirname(node.loc.mod_path)
101
+ node.level, node.path_str, path.dirname(node.loc.mod_path)
99
102
  )
100
103
  return self.import_mod_from_file(target)
101
104