Is there some way to get during debugging with pdb
:
and open the file in default text editor?
Example. After running the code below and then using s
to step into Path
execution and using some command/code I'm looking for I wanted to open file c:\python311\lib\pathlib.py
at line 868 and at 5th symbol.
from pathlib import Path
import pdb; pdb.set_trace()
p = Path()
The problem is only about getting current python file in pdb
context. Opening file itself is trivial os.system(r"C:\test.py")
. Active line code and indent is needed so I'd be able to open it in VS Code at exact position: vsc --goto "C:\test.py:1:5"
(comes from vsc --goto "<filepath>:<linenumber>:<x-coordinates>"
).
It would be nice if it was some native way to do it directly from pdb
but since there's nothing related in the documentation, the solution is probably to make some custom method - which is okay too.
I've already tried to use inspect
module but it seems that pdb
is starting new frame where actual debugged python file is not accessible:
from inspect import currentframe, getframeinfo
frameinfo = getframeinfo(currentframe())
print(frameinfo.filename, frameinfo.lineno)
# <stdin> 1
I've found a solution. Investigating pdb
module, I've found that Pdb
class instance has self.curframe
and self.botframe
attributes allowing to access code frames and their paths. When we do import pdb; pdb.set_trace()
it automatically creates an instance of Pdb
class, we need to access.
But I haven't found any other way to get the instance besides the hacky one - pdb.set_trace()
is setting system trace (using sys.settrace
) to Pdb_instance.trace_dispatch
. Therefore we can retrieve Pdb_instance.trace_dispatch
using sys.gettrace()
and get Pdb
instance with __self__
.
Final solution is the vscode()
method in the snippet below. To make it always accessible with pdb you can put it in your pdb.py
file (typically it's in Python311\Lib\pdb.py
). I guess, the good place for it would be after def set_trace(*, header=None):
.
Then you'd be able to call import pdb; pdb.vscode()
during pdb debugging and it will automatically open current file in VS Code. Voila!
You can also add monkey_patch_vscode
to your pdb - it will patch one of the Pdb
methods and you'd be able to open VS Code with just vscode()
.
PS Need to make sure you have vsc
(link to VS Code) is accessable from your system Path.
def monkey_patch_vscode():
def wrap():
original_setup = Pdb.setup
def wrapped_setup(self, *args):
res = original_setup(self, *args)
self.curframe.f_globals["vscode"] = vscode
return res
return wrapped_setup
Pdb.setup = wrap()
monkey_patch_vscode()
def vscode():
"""open file currently debugged with pdb in VS code
(at current line and indent)"""
import os, linecache, sys, types
def get_current_pdb_file():
pdb = sys.gettrace().__self__
# there is also .botframe - the frame when pdb entered
frame = pdb.curframe # type: types.FrameType
return frame.f_code.co_filename, frame.f_lineno
filepath, line = get_current_pdb_file()
current_line = linecache.getlines(filepath)[line]
indent = len(current_line) - len(current_line.lstrip()) + 1
def vscode_run(filepath, line, indent=1):
# `line` and `indent` starting from 1
os.system(f'vsc --goto "{filepath}:{line}:{indent}"')
vscode_run(filepath, line, indent)