Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix separate-terminal debugging #656

Merged
merged 2 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions pudb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def _get_debugger(**kwargs):
kwargs.setdefault("stdin", tty_file)
kwargs.setdefault("stdout", tty_file)
kwargs.setdefault("term_size", term_size)
tty_file.close()
kwargs.setdefault("tty_file", tty_file)

from pudb.debugger import Debugger
dbg = Debugger(**kwargs)
Expand Down Expand Up @@ -112,12 +112,19 @@ def runmodule(*args, **kwargs):
runscript(*args, **kwargs)


def runscript(mainpyfile, args=None, pre_run="", steal_output=False,
_continue_at_start=False, run_as_module=False):
dbg = _get_debugger(
steal_output=steal_output,
_continue_at_start=_continue_at_start,
)
def runscript(mainpyfile, steal_output=False, _continue_at_start=False,
**kwargs):
try:
dbg = _get_debugger(
steal_output=steal_output,
_continue_at_start=_continue_at_start,
)
_runscript(mainpyfile, dbg, **kwargs)
finally:
dbg.__del__()


def _runscript(mainpyfile, dbg, args=None, pre_run="", run_as_module=False):

# Note on saving/restoring sys.argv: it's a good idea when sys.argv was
# modified by the script being debugged. It's a bad idea when it was
Expand Down
16 changes: 13 additions & 3 deletions pudb/debugger.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class Debugger(bdb.Bdb):
_current_debugger = []

def __init__(self, stdin=None, stdout=None, term_size=None, steal_output=False,
_continue_at_start=False, **kwargs):
_continue_at_start=False, tty_file=None, **kwargs):

if Debugger._current_debugger:
raise ValueError("a Debugger instance already exists")
Expand All @@ -197,6 +197,7 @@ def __init__(self, stdin=None, stdout=None, term_size=None, steal_output=False,
self.ui = DebuggerUI(self, stdin=stdin, stdout=stdout, term_size=term_size)
self.steal_output = steal_output
self._continue_at_start__setting = _continue_at_start
self._tty_file = tty_file

self.setup_state()

Expand All @@ -214,8 +215,17 @@ def __init__(self, stdin=None, stdout=None, term_size=None, steal_output=False,
self._current_debugger.append(self)

def __del__(self):
assert self._current_debugger == [self]
self._current_debugger.pop()
# according to https://stackoverflow.com/a/1481512/1054322, the garbage
# collector cannot be relied on to call this, so we call it explicitly
# in a finally (see __init__.py:runscript). But then, the garbage
# collector *might* call it, so it should tolerate being called twice.

if self._current_debugger:
assert self._current_debugger == [self]
self._current_debugger.pop()
if self._tty_file:
self._tty_file.close()
self._tty_file = None

# These (dispatch_line and set_continue) are copied from bdb with the
# patch from https://bugs.python.org/issue16482 applied. See
Expand Down