Skip to content

Commit

Permalink
Ensuring opened tty file is closed on exit
Browse files Browse the repository at this point in the history
  • Loading branch information
MatrixManAtYrService authored and inducer committed Jul 22, 2024
1 parent 440a5a7 commit b9c8737
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
20 changes: 14 additions & 6 deletions pudb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def _get_debugger(**kwargs):
kwargs.setdefault("stdin", tty_file)
kwargs.setdefault("stdout", tty_file)
kwargs.setdefault("term_size", term_size)
kwargs.setdefault("tty_file", tty_file)

from pudb.debugger import Debugger
dbg = Debugger(**kwargs)
Expand Down Expand Up @@ -111,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

0 comments on commit b9c8737

Please sign in to comment.