mower-ng/mower/utils/traceback.py
2024-11-26 10:55:50 +08:00

64 lines
1.8 KiB
Python

import inspect
import itertools
from pathlib import Path
from types import FrameType
from mower.utils.path import get_path
# https://stackoverflow.com/a/78770438
def fast_stack(max_depth: int | None = None):
def frame_infos(frame: FrameType | None):
while frame := frame and frame.f_back:
yield inspect.FrameInfo(
frame,
inspect.getfile(frame),
frame.f_lineno,
frame.f_code.co_name,
None,
None,
)
return list(itertools.islice(frame_infos(inspect.currentframe()), max_depth))
def caller_info():
caller = fast_stack(3)[2]
relative_path = Path(caller.filename)
try:
relative_path = relative_path.relative_to(get_path("@install"))
except ValueError:
pass
return f"{relative_path}:{caller.lineno}"
def log_info():
caller_class = []
tmp_class = []
stack_info = fast_stack()
func_name = stack_info[2].function
lineno = stack_info[2].lineno
relative_path = Path(stack_info[2].filename)
try:
relative_path = relative_path.relative_to(get_path("@install"))
except ValueError:
pass
for st in stack_info[2:]:
try:
caller = st.frame.f_locals["self"].__class__
except Exception:
continue
try:
name = caller.solver_name
solver = True
except Exception:
name = caller.__qualname__
solver = False
if name is None:
continue
tmp_class.insert(0, name)
if solver:
caller_class = tmp_class + caller_class
tmp_class = []
caller_class = "|".join([key for key, _ in itertools.groupby(caller_class)])
return (caller_class, relative_path, func_name, lineno)