Source code for simvx.editor.error_nav

"""Error-navigation helpers — extract source locations from Python tracebacks."""

import re
from pathlib import Path

__all__ = ["parse_traceback_source"]

_FRAME_RE = re.compile(r'File "([^"]+)", line (\d+)')

[docs] def parse_traceback_source( tb: str, project_path: Path | str | None = None, ) -> tuple[str, int] | None: """Return ``(file_path, line)`` of the last user frame in *tb*, or ``None``. When *project_path* is given, the last frame whose path sits inside the project wins — this hides engine/site-packages frames that sandwich user code in real tracebacks. Falls back to the last ``File "…", line N`` match overall if no project-local frame is present. """ frames = _FRAME_RE.findall(tb) if not frames: return None if project_path is not None: try: root = Path(project_path).resolve() except (OSError, ValueError): root = None if root is not None: for path_str, line_str in reversed(frames): try: candidate = Path(path_str).resolve() except (OSError, ValueError): continue try: candidate.relative_to(root) except ValueError: continue return str(candidate), int(line_str) path_str, line_str = frames[-1] return path_str, int(line_str)