Fix ignored exception in tracer shutdown related to module deletion (#5806)
Some checks are pending
Build and deploy docs / Xonsh docs to gh-pages (push) Waiting to run
CI Tests / Test Python 3.10 macOS-latest (push) Waiting to run
CI Tests / Test Python 3.11 macOS-latest (push) Waiting to run
CI Tests / Test Python 3.12 macOS-latest (push) Waiting to run
CI Tests / Test Python 3.13 macOS-latest (push) Waiting to run
CI Tests / Test Python 3.10 ubuntu-latest (push) Waiting to run
CI Tests / Test Python 3.11 ubuntu-latest (push) Waiting to run
CI Tests / Test Python 3.12 ubuntu-latest (push) Waiting to run
CI Tests / Test Python 3.13 ubuntu-latest (push) Waiting to run
CI Tests / Test Python 3.10 windows-latest (push) Waiting to run
CI Tests / Test Python 3.11 windows-latest (push) Waiting to run
CI Tests / Test Python 3.12 windows-latest (push) Waiting to run
CI Tests / Test Python 3.13 windows-latest (push) Waiting to run

With the tracer on, modules at shutdown can be destroyed in an order
that prevents the `trace()` function from working. This was currently
the case with Python 3.13 where the function was still being called
during the `xonsh.tracer` module's destruction.

This change adds a test to prevent this from happening in the future,
and works around the issue by creating local references to necessary
functions that were otherwise set to None at shutdown.
This commit is contained in:
Łukasz Langa 2025-03-03 13:07:18 +01:00 committed by GitHub
parent bbd652c06d
commit 1183813ff7
Failed to generate hash of commit
4 changed files with 48 additions and 1 deletions

View file

@ -0,0 +1,5 @@
**Fixed:**
* Using ``trace on`` with ``.xsh`` scripts could previously lead to
a spurious ignored exception showing up on stderr. This is now fixed.

View file

@ -1,10 +1,18 @@
import os
import re
import subprocess
import sys
from pathlib import Path
from textwrap import dedent
import pytest
from xonsh.procs.specs import cmds_to_specs
from xonsh.tracer import tracermain
# Minimum set of environment variables on Windows
W_ENV = "SYSTEMDRIVE SYSTEMROOT ALLUSERSPROFILE HOMEDRIVE HOMEPATH APPDATA LOCALAPPDATA"
def test_tracer_help(capsys, xsh_with_aliases):
"""verify can invoke it, and usage knows about all the options"""
@ -17,3 +25,31 @@ def test_tracer_help(capsys, xsh_with_aliases):
assert m[1]
verbs = {v.strip().lower() for v in m[1].split(",")}
assert verbs == {"rm", "start", "add", "on", "off", "del", "color", "stop", "ls"}
def test_trace_in_script():
CURRENT_DIR = Path(__file__).parent
cmd = [sys.executable, "-m", "xonsh", str(CURRENT_DIR / "tracer" / "example.xsh")]
env = {"XONSH_SHOW_TRACEBACK": "True"}
if sys.platform == "win32":
# required for an empty environment on Windows. see python/cpython#120836
for ev in W_ENV.split():
env[ev] = os.environ[ev]
expected = dedent(
"""\
Some output!
tests/built_ins/tracer/example.xsh:3:variable = ""
tests/built_ins/tracer/example.xsh:4:for part in parts:
tests/built_ins/tracer/example.xsh:5: variable += part
tests/built_ins/tracer/example.xsh:4:for part in parts:
tests/built_ins/tracer/example.xsh:5: variable += part
tests/built_ins/tracer/example.xsh:4:for part in parts:
tests/built_ins/tracer/example.xsh:5: variable += part
tests/built_ins/tracer/example.xsh:4:for part in parts:
tests/built_ins/tracer/example.xsh:6:echo Some @(variable)
"""
).replace("/", os.sep)
proc = subprocess.run(cmd, capture_output=True, encoding="utf8", env=env)
assert proc.returncode == 0
assert proc.stderr == ""
assert proc.stdout == expected

View file

@ -0,0 +1,6 @@
parts = ["out", "put", "!"]
trace on
variable = ""
for part in parts:
variable += part
echo Some @(variable)

View file

@ -81,7 +81,7 @@ class TracerType:
frame.f_trace = self.prev_tracer
self.prev_tracer = DefaultNotGiven
def trace(self, frame, event, arg):
def trace(self, frame, event, arg, *, find_file=find_file, print_color=print_color):
"""Implements a line tracing function."""
if event not in self.valid_events:
return self.trace