-
-
Notifications
You must be signed in to change notification settings - Fork 464
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
Running a script with a custom pdb.set_trace() wrapper on 3.14 results in the debugger stopping at the wrong location (one line over)
To Reproduce
Click to show complete reproduction script
#!/bin/bash
# create venvs and install coverage for 3.14 and 3.5
for pyv in 3.14 3.14; do
venv="venv-${pyv}"
uv venv "$venv" --python $pyv
source ${venv}/bin/activate
uv pip install coverage==7.12.0
done
# setup the pdb commands to run
pdb_cmds=$(
cat <<EOF
continue
continue
EOF
)
# reproduction python script: a custom set_trace function plus a set_trace call
repro_pyscript="wrong_break_location_repro.py"
cat >${repro_pyscript} <<EOF
import pdb
import sys
import inspect
def set_trace(frame=None):
if frame is None:
frame = inspect.currentframe().f_back
pdb.Pdb().set_trace(frame)
def f():
print(f"{sys.version=}")
print("coverage=", "coverage" in sys.modules)
a = 1
set_trace()
a = 2
set_trace()
if __name__ == "__main__":
f()
EOF
# run a 4-way diff: python 3.14 vs 3.13 with coverage enabled and disabled
vimdiff \
<(echo -e "$pdb_cmds" | ./venv-3.13/bin/coverage run ${repro_pyscript} 2>&1) \
<(echo -e "$pdb_cmds" | ./venv-3.14/bin/coverage run ${repro_pyscript} 2>&1) \
<(echo -e "$pdb_cmds" | ./venv-3.13/bin/python ${repro_pyscript} 2>&1) \
<(echo -e "$pdb_cmds" | ./venv-3.14/bin/python ${repro_pyscript} 2>&1)Additional information:
- Using python
3.14.0and3.13.1 - Problem happens on latest release (
7.12.0) and latest main (de192da). First commit showing the issue is 7795441 - Running the above script will create virtualenvs for 3.13 and 3.14, write a testfile and show a 4-way diff against python 3.14/3.15 with coverage enabled and disabled. See below for an explanation.
Expected behavior
Running this script through coverage run should break on set_trace():
def set_trace(frame=None):
if frame is None:
frame = inspect.currentframe().f_back
pdb.Pdb().set_trace(frame)
def f():
print(f"{sys.version=}")
print("coverage={"coverage" in in sys.modules}")
a = 1
set_trace()
a = 2
set_trace()This is the output on 3.14 when running through coverage run : Instead of stopping on set_trace(), the we stop on the line following the call, the second one stops on set_trace() as expected:
sys.version='3.14.0 (main, Oct 14 2025, 21:27:55) [Clang 20.1.4 ]'
coverage=True
> ./wrong_break_location_repro.py(19)f()
-> a = 2
continue
(Pdb) > ./wrong_break_location_repro.py(20)f()
-> set_trace()
(Pdb)
continue
This is the output on 3.14 when running as a script: set_trace breaks on the set_trace calls both times (same behaviour as 3.13 with and without coverage enabled)
sys.version='3.14.0 (main, Oct 14 2025, 21:27:55) [Clang 20.1.4 ]'
coverage=False
> ./wrong_break_location_repro.py(18)f()
-> set_trace()
continue
(Pdb) > ./wrong_break_location_repro.py(20)f()
-> set_trace()
(Pdb)
continue
Additional context
Switching over to ctrace solves the issue, e.g. by setting in pyproject.toml:
[tool.coverage.run]
core = "ctrace"Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working