jaclang 0.7.25__py3-none-any.whl → 0.7.26__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 (32) hide show
  1. jaclang/compiler/absyntree.py +27 -18
  2. jaclang/compiler/jac.lark +4 -1
  3. jaclang/compiler/parser.py +37 -20
  4. jaclang/compiler/passes/main/def_impl_match_pass.py +50 -13
  5. jaclang/compiler/passes/main/def_use_pass.py +1 -2
  6. jaclang/compiler/passes/main/pyast_gen_pass.py +46 -20
  7. jaclang/compiler/passes/main/pyast_load_pass.py +20 -6
  8. jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -2
  9. jaclang/compiler/passes/main/tests/fixtures/uninitialized_hasvars.jac +26 -0
  10. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +36 -29
  11. jaclang/compiler/passes/main/tests/test_def_use_pass.py +3 -3
  12. jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -2
  13. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +3 -3
  14. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +3 -3
  15. jaclang/compiler/tests/test_parser.py +7 -1
  16. jaclang/plugin/default.py +48 -11
  17. jaclang/plugin/feature.py +10 -0
  18. jaclang/plugin/spec.py +12 -0
  19. jaclang/plugin/tests/fixtures/graph_purger.jac +101 -0
  20. jaclang/plugin/tests/fixtures/other_root_access.jac +9 -0
  21. jaclang/plugin/tests/test_jaseci.py +126 -6
  22. jaclang/runtimelib/architype.py +12 -1
  23. jaclang/runtimelib/memory.py +5 -1
  24. jaclang/tests/fixtures/architype_def_bug.jac +17 -0
  25. jaclang/tests/fixtures/decl_defn_param_name.jac +19 -0
  26. jaclang/tests/fixtures/multi_dim_array_split.jac +19 -0
  27. jaclang/tests/test_cli.py +18 -0
  28. jaclang/tests/test_language.py +44 -0
  29. {jaclang-0.7.25.dist-info → jaclang-0.7.26.dist-info}/METADATA +1 -1
  30. {jaclang-0.7.25.dist-info → jaclang-0.7.26.dist-info}/RECORD +32 -27
  31. {jaclang-0.7.25.dist-info → jaclang-0.7.26.dist-info}/WHEEL +0 -0
  32. {jaclang-0.7.25.dist-info → jaclang-0.7.26.dist-info}/entry_points.txt +0 -0
jaclang/plugin/default.py CHANGED
@@ -11,7 +11,7 @@ from collections import OrderedDict
11
11
  from dataclasses import field
12
12
  from functools import wraps
13
13
  from logging import getLogger
14
- from typing import Any, Callable, Mapping, Optional, Sequence, Type, Union
14
+ from typing import Any, Callable, Mapping, Optional, Sequence, Type, Union, cast
15
15
  from uuid import UUID
16
16
 
17
17
  from jaclang.compiler.constant import colors
@@ -41,6 +41,7 @@ from jaclang.runtimelib.constructs import (
41
41
  )
42
42
  from jaclang.runtimelib.importer import ImportPathSpec, JacImporter, PythonImporter
43
43
  from jaclang.runtimelib.machine import JacMachine, JacProgram
44
+ from jaclang.runtimelib.memory import Shelf, ShelfStorage
44
45
  from jaclang.runtimelib.utils import collect_node_connections, traverse_graph
45
46
 
46
47
 
@@ -53,6 +54,13 @@ logger = getLogger(__name__)
53
54
  class JacAccessValidationImpl:
54
55
  """Jac Access Validation Implementations."""
55
56
 
57
+ @staticmethod
58
+ @hookimpl
59
+ def elevate_root() -> None:
60
+ """Elevate context root to system_root."""
61
+ jctx = Jac.get_context()
62
+ jctx.root = jctx.system_root
63
+
56
64
  @staticmethod
57
65
  @hookimpl
58
66
  def allow_root(
@@ -379,7 +387,8 @@ class JacWalkerImpl:
379
387
  if walker.next:
380
388
  current_node = walker.next[-1].architype
381
389
  for i in warch._jac_entry_funcs_:
382
- if not i.trigger:
390
+ trigger = i.get_funcparam_annotations(i.func)
391
+ if not trigger:
383
392
  if i.func:
384
393
  i.func(warch, current_node)
385
394
  else:
@@ -387,7 +396,8 @@ class JacWalkerImpl:
387
396
  while len(walker.next):
388
397
  if current_node := walker.next.pop(0).architype:
389
398
  for i in current_node._jac_entry_funcs_:
390
- if not i.trigger or isinstance(warch, i.trigger):
399
+ trigger = i.get_funcparam_annotations(i.func)
400
+ if not trigger or isinstance(warch, trigger):
391
401
  if i.func:
392
402
  i.func(current_node, warch)
393
403
  else:
@@ -395,27 +405,30 @@ class JacWalkerImpl:
395
405
  if walker.disengaged:
396
406
  return warch
397
407
  for i in warch._jac_entry_funcs_:
398
- if not i.trigger or isinstance(current_node, i.trigger):
399
- if i.func and i.trigger:
408
+ trigger = i.get_funcparam_annotations(i.func)
409
+ if not trigger or isinstance(current_node, trigger):
410
+ if i.func and trigger:
400
411
  i.func(warch, current_node)
401
- elif not i.trigger:
412
+ elif not trigger:
402
413
  continue
403
414
  else:
404
415
  raise ValueError(f"No function {i.name} to call.")
405
416
  if walker.disengaged:
406
417
  return warch
407
418
  for i in warch._jac_exit_funcs_:
408
- if not i.trigger or isinstance(current_node, i.trigger):
409
- if i.func and i.trigger:
419
+ trigger = i.get_funcparam_annotations(i.func)
420
+ if not trigger or isinstance(current_node, trigger):
421
+ if i.func and trigger:
410
422
  i.func(warch, current_node)
411
- elif not i.trigger:
423
+ elif not trigger:
412
424
  continue
413
425
  else:
414
426
  raise ValueError(f"No function {i.name} to call.")
415
427
  if walker.disengaged:
416
428
  return warch
417
429
  for i in current_node._jac_exit_funcs_:
418
- if not i.trigger or isinstance(warch, i.trigger):
430
+ trigger = i.get_funcparam_annotations(i.func)
431
+ if not trigger or isinstance(warch, trigger):
419
432
  if i.func:
420
433
  i.func(current_node, warch)
421
434
  else:
@@ -423,7 +436,8 @@ class JacWalkerImpl:
423
436
  if walker.disengaged:
424
437
  return warch
425
438
  for i in warch._jac_exit_funcs_:
426
- if not i.trigger:
439
+ trigger = i.get_funcparam_annotations(i.func)
440
+ if not trigger:
427
441
  if i.func:
428
442
  i.func(warch, current_node)
429
443
  else:
@@ -560,6 +574,29 @@ class JacFeatureImpl(
560
574
  """Get current execution context."""
561
575
  return ExecutionContext.get()
562
576
 
577
+ @staticmethod
578
+ @hookimpl
579
+ def reset_graph(root: Optional[Root] = None) -> int:
580
+ """Purge current or target graph."""
581
+ ctx = Jac.get_context()
582
+ mem = cast(ShelfStorage, ctx.mem)
583
+ ranchor = root.__jac__ if root else ctx.root
584
+
585
+ deleted_count = 0
586
+ for anchor in (
587
+ anchors.values()
588
+ if isinstance(anchors := mem.__shelf__, Shelf)
589
+ else mem.__mem__.values()
590
+ ):
591
+ if anchor == ranchor or anchor.root != ranchor.id:
592
+ continue
593
+
594
+ if loaded_anchor := mem.find_by_id(anchor.id):
595
+ deleted_count += 1
596
+ Jac.destroy(loaded_anchor)
597
+
598
+ return deleted_count
599
+
563
600
  @staticmethod
564
601
  @hookimpl
565
602
  def get_object(id: str) -> Architype | None:
jaclang/plugin/feature.py CHANGED
@@ -41,6 +41,11 @@ from jaclang.plugin.spec import (
41
41
  class JacAccessValidation:
42
42
  """Jac Access Validation Specs."""
43
43
 
44
+ @staticmethod
45
+ def elevate_root() -> None:
46
+ """Elevate context root to system_root."""
47
+ plugin_manager.hook.elevate_root()
48
+
44
49
  @staticmethod
45
50
  def allow_root(
46
51
  architype: Architype,
@@ -254,6 +259,11 @@ class JacFeature(
254
259
  """Get current execution context."""
255
260
  return plugin_manager.hook.get_context()
256
261
 
262
+ @staticmethod
263
+ def reset_graph(root: Optional[Root] = None) -> int:
264
+ """Purge current or target graph."""
265
+ return plugin_manager.hook.reset_graph(root=root)
266
+
257
267
  @staticmethod
258
268
  def get_object(id: str) -> Architype | None:
259
269
  """Get object given id."""
jaclang/plugin/spec.py CHANGED
@@ -46,6 +46,12 @@ P = ParamSpec("P")
46
46
  class JacAccessValidationSpec:
47
47
  """Jac Access Validation Specs."""
48
48
 
49
+ @staticmethod
50
+ @hookspec(firstresult=True)
51
+ def elevate_root() -> None:
52
+ """Elevate context root to system_root."""
53
+ raise NotImplementedError
54
+
49
55
  @staticmethod
50
56
  @hookspec(firstresult=True)
51
57
  def allow_root(
@@ -244,6 +250,12 @@ class JacFeatureSpec(
244
250
  """Get current execution context."""
245
251
  raise NotImplementedError
246
252
 
253
+ @staticmethod
254
+ @hookspec(firstresult=True)
255
+ def reset_graph(root: Optional[Root]) -> int:
256
+ """Purge current or target graph."""
257
+ raise NotImplementedError
258
+
247
259
  @staticmethod
248
260
  @hookspec(firstresult=True)
249
261
  def get_object(id: str) -> Architype | None:
@@ -0,0 +1,101 @@
1
+ node A {
2
+ has id: int;
3
+ }
4
+
5
+ node B {
6
+ has id: int;
7
+ }
8
+
9
+ node C {
10
+ has id: int;
11
+ }
12
+
13
+ node D {
14
+ has id: int;
15
+ }
16
+
17
+ node E {
18
+ has id: int;
19
+ }
20
+
21
+
22
+ walker populate {
23
+ can setup1 with `root entry {
24
+ for i in range(2) {
25
+ here ++> A(id=i);
26
+ }
27
+ visit [-->];
28
+ }
29
+
30
+ can setup2 with A entry {
31
+ for i in range(2) {
32
+ here ++> B(id=i);
33
+ }
34
+ visit [-->];
35
+ }
36
+
37
+ can setup3 with B entry {
38
+ for i in range(2) {
39
+ here ++> C(id=i);
40
+ }
41
+ visit [-->];
42
+ }
43
+
44
+ can setup4 with C entry {
45
+ for i in range(2) {
46
+ here ++> D(id=i);
47
+ }
48
+ visit [-->];
49
+ }
50
+
51
+ can setup5 with D entry {
52
+ for i in range(2) {
53
+ here ++> E(id=i);
54
+ }
55
+ visit [-->];
56
+ }
57
+ }
58
+
59
+ walker traverse {
60
+ can enter1 with `root entry {
61
+ print(here);
62
+ visit [-->];
63
+ }
64
+
65
+ can enter2 with A entry {
66
+ print(here);
67
+ visit [-->];
68
+ }
69
+
70
+ can enter3 with B entry {
71
+ print(here);
72
+ visit [-->];
73
+ }
74
+
75
+ can enter4 with C entry {
76
+ print(here);
77
+ visit [-->];
78
+ }
79
+
80
+ can enter5 with D entry {
81
+ print(here);
82
+ visit [-->];
83
+ }
84
+
85
+ can enter6 with E entry {
86
+ print(here);
87
+ visit [-->];
88
+ }
89
+ }
90
+
91
+ walker purge {
92
+ can purge with `root entry {
93
+ print(Jac.reset_graph());
94
+ }
95
+ }
96
+
97
+ walker check {
98
+ can enter with `root entry {
99
+ print(len(Jac.get_context().mem.__shelf__.values()));
100
+ }
101
+ }
@@ -23,6 +23,15 @@ walker update_node {
23
23
  }
24
24
  }
25
25
 
26
+ walker update_node_forced {
27
+ has val: int;
28
+
29
+ can enter2 with A entry {
30
+ Jac.elevate_root();
31
+ here.val = self.val;
32
+ }
33
+ }
34
+
26
35
  walker create_node {
27
36
  has val: int;
28
37
 
@@ -269,6 +269,75 @@ class TestJaseciPlugin(TestCase):
269
269
  )
270
270
  self._del_session(session)
271
271
 
272
+ def test_walker_purger(self) -> None:
273
+ """Test simple persistent object."""
274
+ session = self.fixture_abs_path("test_walker_purger.session")
275
+ self._output2buffer()
276
+ cli.enter(
277
+ filename=self.fixture_abs_path("graph_purger.jac"),
278
+ session=session,
279
+ entrypoint="populate",
280
+ args=[],
281
+ )
282
+ cli.enter(
283
+ filename=self.fixture_abs_path("graph_purger.jac"),
284
+ session=session,
285
+ entrypoint="traverse",
286
+ args=[],
287
+ )
288
+ cli.enter(
289
+ filename=self.fixture_abs_path("graph_purger.jac"),
290
+ session=session,
291
+ entrypoint="check",
292
+ args=[],
293
+ )
294
+ cli.enter(
295
+ filename=self.fixture_abs_path("graph_purger.jac"),
296
+ session=session,
297
+ entrypoint="purge",
298
+ args=[],
299
+ )
300
+ output = self.capturedOutput.getvalue().strip()
301
+ self.assertEqual(
302
+ output,
303
+ (
304
+ "Root()\n"
305
+ "A(id=0)\nA(id=1)\n"
306
+ "B(id=0)\nB(id=1)\nB(id=0)\nB(id=1)\n"
307
+ "C(id=0)\nC(id=1)\nC(id=0)\nC(id=1)\nC(id=0)\nC(id=1)\nC(id=0)\nC(id=1)\n"
308
+ "D(id=0)\nD(id=1)\nD(id=0)\nD(id=1)\nD(id=0)\nD(id=1)\nD(id=0)\nD(id=1)\n"
309
+ "D(id=0)\nD(id=1)\nD(id=0)\nD(id=1)\nD(id=0)\nD(id=1)\nD(id=0)\nD(id=1)\n"
310
+ "E(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\n"
311
+ "E(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\n"
312
+ "E(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\n"
313
+ "E(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\nE(id=0)\nE(id=1)\n"
314
+ "125\n124"
315
+ ),
316
+ )
317
+ self._output2buffer()
318
+ cli.enter(
319
+ filename=self.fixture_abs_path("graph_purger.jac"),
320
+ session=session,
321
+ entrypoint="traverse",
322
+ args=[],
323
+ )
324
+ cli.enter(
325
+ filename=self.fixture_abs_path("graph_purger.jac"),
326
+ session=session,
327
+ entrypoint="check",
328
+ args=[],
329
+ )
330
+ cli.enter(
331
+ filename=self.fixture_abs_path("graph_purger.jac"),
332
+ session=session,
333
+ entrypoint="purge",
334
+ args=[],
335
+ )
336
+ output = self.capturedOutput.getvalue().strip()
337
+ self.assertEqual(output, "Root()\n1\n0")
338
+
339
+ self._del_session(session)
340
+
272
341
  def trigger_access_validation_test(
273
342
  self, give_access_to_full_graph: bool, via_all: bool = False
274
343
  ) -> None:
@@ -340,6 +409,55 @@ class TestJaseciPlugin(TestCase):
340
409
  self.assertEqual(archs[0], "A(val=2)")
341
410
  self.assertEqual(archs[1], "A(val=1)")
342
411
 
412
+ ##############################################
413
+ # WITH READ ACCESS BUT ELEVATED #
414
+ ##############################################
415
+
416
+ self._output2buffer()
417
+
418
+ cli.enter(
419
+ filename=self.fixture_abs_path("other_root_access.jac"),
420
+ entrypoint="update_node_forced",
421
+ args=[20],
422
+ session=session,
423
+ root=self.roots[0],
424
+ node=self.nodes[1],
425
+ )
426
+ cli.enter(
427
+ filename=self.fixture_abs_path("other_root_access.jac"),
428
+ entrypoint="update_node_forced",
429
+ args=[10],
430
+ session=session,
431
+ root=self.roots[1],
432
+ node=self.nodes[0],
433
+ )
434
+
435
+ cli.enter(
436
+ filename=self.fixture_abs_path("other_root_access.jac"),
437
+ entrypoint="check_node",
438
+ args=[],
439
+ session=session,
440
+ root=self.roots[0],
441
+ node=self.nodes[1],
442
+ )
443
+ cli.enter(
444
+ filename=self.fixture_abs_path("other_root_access.jac"),
445
+ entrypoint="check_node",
446
+ args=[],
447
+ session=session,
448
+ root=self.roots[1],
449
+ node=self.nodes[0],
450
+ )
451
+ archs = self.capturedOutput.getvalue().strip().split("\n")
452
+ self.assertTrue(len(archs) == 2)
453
+
454
+ # ---------- UPDATE SHOULD HAPPEN ---------- #
455
+
456
+ self.assertEqual(archs[0], "A(val=20)")
457
+ self.assertEqual(archs[1], "A(val=10)")
458
+
459
+ # ---------- DISALLOW READ ACCESS ---------- #
460
+
343
461
  self._output2buffer()
344
462
  cli.enter(
345
463
  filename=self.fixture_abs_path("other_root_access.jac"),
@@ -400,7 +518,7 @@ class TestJaseciPlugin(TestCase):
400
518
  cli.enter(
401
519
  filename=self.fixture_abs_path("other_root_access.jac"),
402
520
  entrypoint="update_node",
403
- args=[20],
521
+ args=[200],
404
522
  root=self.roots[0],
405
523
  node=self.nodes[1],
406
524
  session=session,
@@ -408,7 +526,7 @@ class TestJaseciPlugin(TestCase):
408
526
  cli.enter(
409
527
  filename=self.fixture_abs_path("other_root_access.jac"),
410
528
  entrypoint="update_node",
411
- args=[10],
529
+ args=[100],
412
530
  session=session,
413
531
  root=self.roots[1],
414
532
  node=self.nodes[0],
@@ -433,10 +551,12 @@ class TestJaseciPlugin(TestCase):
433
551
  archs = self.capturedOutput.getvalue().strip().split("\n")
434
552
  self.assertTrue(len(archs) == 2)
435
553
 
436
- # --------- UPDATE SHOULD HAPPEN -------- #
554
+ # ---------- UPDATE SHOULD HAPPEN ---------- #
437
555
 
438
- self.assertEqual(archs[0], "A(val=20)")
439
- self.assertEqual(archs[1], "A(val=10)")
556
+ self.assertEqual(archs[0], "A(val=200)")
557
+ self.assertEqual(archs[1], "A(val=100)")
558
+
559
+ # ---------- DISALLOW WRITE ACCESS --------- #
440
560
 
441
561
  self._output2buffer()
442
562
  cli.enter(
@@ -474,7 +594,7 @@ class TestJaseciPlugin(TestCase):
474
594
  )
475
595
  self.assertFalse(self.capturedOutput.getvalue().strip())
476
596
 
477
- # --------- ROOTS RESET OWN NODE -------- #
597
+ # ---------- ROOTS RESET OWN NODE ---------- #
478
598
 
479
599
  cli.enter(
480
600
  filename=self.fixture_abs_path("other_root_access.jac"),
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import inspect
5
6
  from dataclasses import asdict, dataclass, field, fields, is_dataclass
6
7
  from enum import IntEnum
7
8
  from logging import getLogger
@@ -291,9 +292,19 @@ class DSFunc:
291
292
  """Data Spatial Function."""
292
293
 
293
294
  name: str
294
- trigger: type | UnionType | tuple[type | UnionType, ...] | None
295
295
  func: Callable[[Any, Any], Any] | None = None
296
296
 
297
297
  def resolve(self, cls: type) -> None:
298
298
  """Resolve the function."""
299
299
  self.func = getattr(cls, self.name)
300
+
301
+ def get_funcparam_annotations(
302
+ self, func: Callable[[Any, Any], Any] | None
303
+ ) -> type | UnionType | tuple[type | UnionType, ...] | None:
304
+ """Get function parameter annotations."""
305
+ if not func:
306
+ return None
307
+ annotation = (
308
+ inspect.signature(func, eval_str=True).parameters["_jac_here_"].annotation
309
+ )
310
+ return annotation if annotation != inspect._empty else None
@@ -25,6 +25,10 @@ class Memory(Generic[ID, TANCH]):
25
25
  self.__mem__.clear()
26
26
  self.__gc__.clear()
27
27
 
28
+ def is_cached(self, id: ID) -> bool:
29
+ """Check if id if already cached."""
30
+ return id in self.__mem__
31
+
28
32
  def find(
29
33
  self,
30
34
  ids: ID | Iterable[ID],
@@ -96,7 +100,7 @@ class ShelfStorage(Memory[UUID, Anchor]):
96
100
  and p_d.edges != d.edges
97
101
  and Jac.check_connect_access(d)
98
102
  ):
99
- if not d.edges:
103
+ if not d.edges and not isinstance(d.architype, Root):
100
104
  self.__shelf__.pop(_id, None)
101
105
  continue
102
106
  p_d.edges = d.edges
@@ -0,0 +1,17 @@
1
+ # fix test type 2
2
+ walker MyWalker {
3
+ can travel with `root | MyNode entry {
4
+ print("MyWalker");
5
+ }
6
+ }
7
+
8
+ node MyNode {
9
+ can work with MyWalker entry {
10
+ print("MyNode");
11
+ }
12
+ }
13
+
14
+ with entry {
15
+ Node_1 = MyNode();
16
+ Node_1 spawn MyWalker();
17
+ }
@@ -0,0 +1,19 @@
1
+
2
+ obj SomeClass {
3
+ can method1(some_long_paramenter_name: int) -> None;
4
+ can method2(param1:int, param2:str) -> None;
5
+ }
6
+
7
+ :o:SomeClass:c:method1(short_name:int) -> None {
8
+ print("short_name =", short_name);
9
+ }
10
+
11
+ :o:SomeClass:c:method2(p1:int, p2: str) -> None {
12
+ print("p1 =", p1, ", p2 =", p2);
13
+ }
14
+
15
+ with entry {
16
+ sc = SomeClass();
17
+ sc.method1(42);
18
+ sc.method2(64, "foobar");
19
+ }
@@ -0,0 +1,19 @@
1
+ import:py numpy as np;
2
+
3
+ with entry {
4
+ arr = np.array(
5
+ [[1, 2, 3, 4, 5],
6
+ [6, 7, 8, 9, 10],
7
+ [11, 12, 13, 14, 15],
8
+ [16, 17, 18, 19, 20],
9
+ [21, 22, 23, 24, 25]]
10
+ );
11
+
12
+ print('Original Array:');
13
+ print(arr);
14
+
15
+ print();
16
+
17
+ print('Sliced Array:');
18
+ print(arr[1:3, 1::2]);
19
+ }
jaclang/tests/test_cli.py CHANGED
@@ -94,6 +94,24 @@ class JacCliTests(TestCase):
94
94
  path_to_file = self.fixture_abs_path("err.impl.jac")
95
95
  self.assertIn(f'"{path_to_file}", line 2', stdout_value)
96
96
 
97
+ def test_param_name_diff(self) -> None:
98
+ """Test when parameter name from definitinon and declaration are mismatched."""
99
+ captured_output = io.StringIO()
100
+ sys.stdout = captured_output
101
+ sys.stderr = captured_output
102
+ with contextlib.suppress(Exception):
103
+ cli.run(self.fixture_abs_path("decl_defn_param_name.jac"))
104
+ sys.stdout = sys.__stdout__
105
+ sys.stderr = sys.__stderr__
106
+
107
+ expected_stdout_values = (
108
+ "short_name = 42",
109
+ "p1 = 64 , p2 = foobar",
110
+ )
111
+ output = captured_output.getvalue()
112
+ for exp in expected_stdout_values:
113
+ self.assertIn(exp, output)
114
+
97
115
  def test_jac_test_err(self) -> None:
98
116
  """Basic test for pass."""
99
117
  captured_output = io.StringIO()
@@ -103,6 +103,40 @@ class JacLanguageTests(TestCase):
103
103
  "Too high!\nToo low!\nToo high!\nCongratulations! You guessed correctly.\n",
104
104
  )
105
105
 
106
+ def test_multi_dim_arr_slice(self) -> None:
107
+ """Parse micro jac file."""
108
+ captured_output = io.StringIO()
109
+ sys.stdout = captured_output
110
+ cli.tool(
111
+ "ir",
112
+ [
113
+ "ast",
114
+ self.fixture_abs_path("multi_dim_array_split.jac"),
115
+ ],
116
+ )
117
+ sys.stdout = sys.__stdout__
118
+ stdout_value = captured_output.getvalue()
119
+
120
+ # print(arr[1:3, 1::2]);
121
+ expected_outputs = [
122
+ "+-- AtomTrailer - Type: Any",
123
+ " +-- Name - arr - Type: Any, SymbolTable: None",
124
+ " +-- IndexSlice - [IndexSlice] - Type: builtins.slice, SymbolTable: None",
125
+ " +-- Token - [,",
126
+ " +-- Int - 1 - Type: Literal[1]?, SymbolTable: None",
127
+ " +-- Token - :,",
128
+ " +-- Int - 3 - Type: Literal[3]?, SymbolTable: None",
129
+ " +-- Token - ,,",
130
+ " +-- Int - 1 - Type: Literal[1]?, SymbolTable: None",
131
+ " +-- Token - :,",
132
+ " +-- Token - :,",
133
+ " +-- Int - 2 - Type: Literal[2]?, SymbolTable: None",
134
+ " +-- Token - ],",
135
+ ]
136
+
137
+ for expected in expected_outputs:
138
+ self.assertIn(expected, stdout_value)
139
+
106
140
  def test_chandra_bugs(self) -> None:
107
141
  """Parse micro jac file."""
108
142
  captured_output = io.StringIO()
@@ -1189,3 +1223,13 @@ class JacLanguageTests(TestCase):
1189
1223
  stdout_value = captured_output.getvalue().split("\n")
1190
1224
  self.assertIn("Hello World !", stdout_value[0])
1191
1225
  self.assertIn("Welcome to Jaseci!", stdout_value[1])
1226
+
1227
+ def test_architype_def(self) -> None:
1228
+ """Test architype definition bug."""
1229
+ captured_output = io.StringIO()
1230
+ sys.stdout = captured_output
1231
+ jac_import("architype_def_bug", base_path=self.fixture_abs_path("./"))
1232
+ sys.stdout = sys.__stdout__
1233
+ stdout_value = captured_output.getvalue().split("\n")
1234
+ self.assertIn("MyNode", stdout_value[0])
1235
+ self.assertIn("MyWalker", stdout_value[1])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaclang
3
- Version: 0.7.25
3
+ Version: 0.7.26
4
4
  Summary: Jac is a unique and powerful programming language that runs on top of Python, offering an unprecedented level of intelligence and intuitive understanding.
5
5
  Home-page: https://jaseci.org
6
6
  License: MIT