From a079570b8f94a67199df40acafde8b3a9502b78d Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 20 Dec 2024 14:10:48 -0500 Subject: [PATCH] Small changes to stack printing & Tracestack[] doc --- mathics/builtin/trace.py | 28 +++++++++++++++------------- mathics/eval/trace.py | 23 ++++++++++++++--------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/mathics/builtin/trace.py b/mathics/builtin/trace.py index d8d659779..a9396252a 100644 --- a/mathics/builtin/trace.py +++ b/mathics/builtin/trace.py @@ -125,7 +125,7 @@ class PrintTrace(_TraceBase): Note: before '$TraceBuiltins' is set to 'True', 'PrintTrace[]' will print an empty list. - >> PrintTrace[] + >> PrintTrace[] (* See console log *) >> $TraceBuiltins = True = True @@ -158,19 +158,21 @@ class Stacktrace(_TraceBase):
Print Mathics3 stack trace of evalutations leading to this point - Show evaluation stack when computing a homegrown factorial function: + To show the Mathics3 evaluation stack at the \ + point where expression $expr$ is evaluated, wrap $expr$ inside '{$expr$ Stacktrace[]}[1]]' \ + or something similar. - >> F[0] := {1, Stacktrace[]}[[1]] - = None + Here is a complete example. To show the evaluation stack when computing a homegrown \ + factorial function: - >> F[n_] := n * F[n-1] + >> F[0] := {1, Stacktrace[]}[[1]]; F[n_] := n * F[n-1] = None - >> F[3] + >> F[3] (* See console log *) = None - The actual 'Stacktrace[0]' call is hidden from the output so when \ - run on its own nothing app + The actual 'Stacktrace[0]' call is hidden from the output; so when \ + run on its own, nothing appears. >> Stacktrace[] = None @@ -183,7 +185,7 @@ class Stacktrace(_TraceBase): def eval(self, evaluation: Evaluation): "Stacktrace[]" - # use longer-form resolve call + # Use longer-form resolve call # so a debugger can change this. mathics.eval.trace.eval_Stacktrace() return SymbolNull @@ -209,22 +211,22 @@ class TraceBuiltins(_TraceBase): - >> TraceBuiltins[Graphics3D[Tetrahedron[]]] + >> TraceBuiltins[Graphics3D[Tetrahedron[]]] (* See console log *) = -Graphics3D- By default, the output is sorted by the name: - >> TraceBuiltins[Times[x, x]] + >> TraceBuiltins[Times[x, x]] (* See console log *) = x ^ 2 By default, the output is sorted by the number of calls of the builtin from \ highest to lowest: - >> TraceBuiltins[Times[x, x], SortBy->"count"] + >> TraceBuiltins[Times[x, x], SortBy->"count"] (* See console log *) = x ^ 2 You can have results ordered by name, or time. Trace an expression and list the result by time from highest to lowest. - >> TraceBuiltins[Times[x, x], SortBy->"time"] + >> TraceBuiltins[Times[x, x], SortBy->"time"] (* See console log *) = x ^ 2 """ diff --git a/mathics/eval/trace.py b/mathics/eval/trace.py index 5a72e78cc..6772ea79e 100644 --- a/mathics/eval/trace.py +++ b/mathics/eval/trace.py @@ -6,12 +6,13 @@ from math import log10 from typing import Any, Tuple +from mathics.core.expression import Expression + def eval_Stacktrace(): """ Display the Python call stack but filtered so that we Builtin calls. """ - from mathics.core.expression import Expression frame = inspect.currentframe() assert frame is not None @@ -33,15 +34,19 @@ def eval_Stacktrace(): last_was_eval = True builtin_class = self_obj.__class__ mathics_builtin_name = builtin_class.__name__ - if len(frame.f_code.co_consts) > 0: - # Use code's __doc__ string - frame_str = frame.f_code.co_consts[0] - if frame_str.startswith("%(name)s"): - frame_str = frame_str.replace( - "%(name)s", mathics_builtin_name - ) + eval_name = frame.f_code.co_name + if hasattr(self_obj, eval_name): + docstring = getattr(self_obj, eval_name).__doc__ + docstring = docstring.replace("%(name)s", mathics_builtin_name) + args_pattern = ( + docstring[len(mathics_builtin_name) + 1 : -1] + if docstring.startswith(mathics_builtin_name) + else "" + ) else: - frame_str = mathics_builtin_name + args_pattern = "" + + frame_str = f"{mathics_builtin_name}[{args_pattern}]" frames.append(frame_str) frame_number += 1 frame = frame.f_back