Skip to content

Commit

Permalink
[FEATURE-REQUEST]: Allow node traversing to ignore non existing archi…
Browse files Browse the repository at this point in the history
…types
  • Loading branch information
amadolid committed Aug 31, 2023
1 parent 79279af commit cbbda0b
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 32 deletions.
11 changes: 9 additions & 2 deletions jaseci_core/jaseci/extens/api/tests/fixtures/without_node_b.jac
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ node a {}

walker init {
root {
take --> node::a;
take -->;
spawn --> walker::sample;
}

a {
report here;
report here.info.name;
}
}

walker sample {
with entry {
report here.info.name;
}
}
12 changes: 9 additions & 3 deletions jaseci_core/jaseci/extens/api/tests/test_uncommon.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ def test_existing_node_in_graph_but_not_in_sentinel(self):

res = self.call(self.smast, ["walker_run", {"name": "init"}])

self.assertTrue(res["success"])
self.assertEqual(1, len(res["report"]))
self.assertTrue("a", len(res["report"][0]["name"]))
self.assertFalse(res["success"])
self.assertEqual(["a", "a"], res["report"])
self.assertEqual(
[
"default:init - line 5, col 13 - rule edge_to - Unable to find architype for node:node:b from sentinel:generic:default",
"default:sample - line 6, col 18 - rule walker_ref - Unable to find architype for node:node:b from sentinel:generic:default",
],
res["errors"],
)
1 change: 1 addition & 0 deletions jaseci_core/jaseci/jac/interpreter/interp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,7 @@ def run_walker_ref(self, jac_ast, to_await=False):
self.rt_error(f"No walker {name} exists!", kid[-1])
else:
wlk._to_await = to_await
wlk._cur_jac_ast = jac_ast
return wlk

def run_graph_ref(self, jac_ast):
Expand Down
10 changes: 6 additions & 4 deletions jaseci_core/jaseci/jac/interpreter/walker_interp.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,19 @@ def run_take_action(self, jac_ast):
before = len(self.next_node_ids)
if isinstance(result, Node):
if style in ["b", "bfs"]:
self.next_node_ids.add_obj(result, allow_dups=True)
self.next_node_ids.add_obj(result, allow_dups=True, interp=self)
elif style in ["d", "dfs"]:
self.next_node_ids.add_obj(result, push_front=True, allow_dups=True)
self.next_node_ids.add_obj(
result, push_front=True, allow_dups=True, interp=self
)
else:
self.rt_error(f"{style} is invalid take operation", kid[0])
elif isinstance(result, JacSet):
if style in ["b", "bfs"]:
self.next_node_ids.add_obj_list(result, allow_dups=True)
self.next_node_ids.add_obj_list(result, allow_dups=True, interp=self)
elif style in ["d", "dfs"]:
self.next_node_ids.add_obj_list(
result, push_front=True, allow_dups=True
result, push_front=True, allow_dups=True, interp=self
)
else:
self.rt_error(f"{style} is invalid take operation", kid[0])
Expand Down
1 change: 0 additions & 1 deletion jaseci_core/jaseci/jac/machine/machine_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ def reset(self):
self.report_status = None
self.report_custom = None
self.report_file = None
self.runtime_errors = []
self.runtime_stack_trace = []
self._scope_stack = [None]
self._jac_scope = None
Expand Down
37 changes: 24 additions & 13 deletions jaseci_core/jaseci/prim/obj_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,33 @@ class Anchored:
def __init__(self):
self.context = {}

def get_architype(self):
def get_architype(self, interp=None):
arch = self.get_arch_from_cache() # Optimization
if arch and id(arch._h) == id(self._h):
return arch
arch = (
self._h._machine.parent().get_arch_for(self)
if self._h._machine is not None
and self._h._machine.parent() is not None
and self._h._machine.parent().j_type == "sentinel"
else None
)
mast = self.get_master()
if arch is None and mast.active_snt() is not None:
arch = mast.active_snt().get_arch_for(self)
elif arch is None and self.parent() and self.parent().j_type == "sentinel":
arch = self.parent().get_arch_for(self)

# Initial checking is from current machine parent
sent_cur = None
arch = None
if self._h._machine is not None:
sent_cur = self._h._machine.parent()
if sent_cur is not None and sent_cur.j_type == "sentinel":
arch = sent_cur.get_arch_for(self, interp=interp)

# secondary checking if machine sentinel return arch None
# it will ignore the check if the machine sentinel is equal to the secondary sentinel to avoid duplicate checking
if arch is None:
mast = self.get_master()
for sent in [mast.active_snt, self.parent]:
sent_bak = sent()
if (
sent_bak is not None
and sent_bak != sent_cur
and sent_bak.j_type == "sentinel"
):
arch = sent_bak.get_arch_for(self, interp=interp)
break

self.cache_arch(arch)
return arch

Expand Down
9 changes: 5 additions & 4 deletions jaseci_core/jaseci/prim/sentinel.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,14 @@ def run_architype(self, name, kind=None, caller=None, is_async=None):
Element.destroy(arch)
return ret

def get_arch_for(self, obj):
def get_arch_for(self, obj, interp=None):
"""Returns the architype that matches object"""
ret = self.arch_ids.get_obj_by_name(name=obj.name, kind=obj.kind)
if ret is None:
self.rt_subtle_error(
f"Unable to find architype for {obj.name}, {obj.kind}",
self._cur_jac_ast,
_interp = interp or self
_interp.rt_subtle_error(
f"Unable to find architype for {obj.j_type}:{obj.kind}:{obj.name} from {self.j_type}:{self.kind}:{self.name}",
_interp._cur_jac_ast,
)
return ret

Expand Down
2 changes: 1 addition & 1 deletion jaseci_core/jaseci/prim/walker.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def step(self):
def prime(self, start_node, prime_ctx=None, request_ctx=None):
"""Place walker on node and get ready to step step"""
if not self.yielded or not len(self.next_node_ids): # modus ponens
self.next_node_ids.add_obj(start_node, push_front=True)
self.next_node_ids.add_obj(start_node, push_front=True, interp=self)
if prime_ctx:
for i in prime_ctx.keys():
self.context[str(i)] = prime_ctx[i]
Expand Down
18 changes: 14 additions & 4 deletions jaseci_core/jaseci/utils/id_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ def __init__(self, parent_obj, auto_save=True, in_list=None):
def cache_reset(self):
self.cached_objects = []

def add_obj(self, obj, push_front=False, allow_dups=False, silent=False):
def add_obj(
self, obj, push_front=False, allow_dups=False, silent=False, interp=None
):
"""Adds a obj obj to Jaseci object"""
self.parent_obj.check_hooks_match(obj)
if not allow_dups and obj.jid in self:
if not silent:
logger.warning(str(f"{obj} is already in {self.parent_obj}'s list"))
else:
elif not interp or obj.get_architype(interp):
self.cache_reset()
if push_front:
self.insert(0, obj.jid)
Expand All @@ -44,12 +46,20 @@ def add_obj(self, obj, push_front=False, allow_dups=False, silent=False):
self.save(obj)
self.save()

def add_obj_list(self, obj_list, push_front=False, allow_dups=False, silent=False):
def add_obj_list(
self, obj_list, push_front=False, allow_dups=False, silent=False, interp=None
):
self.cache_reset()
if push_front:
obj_list.reverse()
for i in obj_list:
self.add_obj(i, push_front=push_front, allow_dups=allow_dups, silent=silent)
self.add_obj(
i,
push_front=push_front,
allow_dups=allow_dups,
silent=silent,
interp=interp,
)

def remove_obj(self, obj):
"""Remove a Jaseci obj from list"""
Expand Down

0 comments on commit cbbda0b

Please sign in to comment.