in sapp/ui/interactive.py [0:0]
def parents(self) -> None:
self._verify_entrypoint_selected()
current_trace_tuple = self.trace_tuples[self.current_trace_frame_index]
# Don't allow calling from the leaf node in a trace. Instead, call
# parents() from the placeholder of the caller of the leaf node.
if current_trace_tuple.trace_frame.is_leaf():
raise UserError("Try running from a non-leaf node.")
# Backwards trace checks against the given frame's _caller_.
# If we have A->B as a placeholder, we want parents that call A, since A
# is what is displayed in the trace.
# If we have A->B as a non-placeholder, we want parents that call B,
# since B is what is displayed in the trace. So we go to (A->B)'s child
# B->C, and look for frames that call B.
if not current_trace_tuple.placeholder:
delta_from_child = -1 if self._is_before_root() else 1
current_trace_tuple = self.trace_tuples[
self.current_trace_frame_index + delta_from_child
]
with self.db.make_session() as session:
if current_trace_tuple.trace_frame.kind == TraceKind.POSTCONDITION:
leaf_kind = self.sources
elif current_trace_tuple.trace_frame.kind == TraceKind.PRECONDITION:
leaf_kind = self.sinks
else:
assert (
current_trace_tuple.trace_frame.kind == TraceKind.POSTCONDITION
or current_trace_tuple.trace_frame.kind == TraceKind.PRECONDITION
)
parent_trace_frames = trace.next_frames(
session,
current_trace_tuple.trace_frame,
# pyre-fixme[61]: `leaf_kind` may not be initialized here.
leaf_kind,
set(),
self._current_run_id,
backwards=True,
)
if len(parent_trace_frames) == 0:
print(
f"No parents calling [{current_trace_tuple.trace_frame.caller} "
f": {current_trace_tuple.trace_frame.caller_port}]."
)
return
parent_trace_frame = self._select_parent_trace_frame(parent_trace_frames)
self._update_trace_tuples_new_parent(parent_trace_frame)
self.trace()