Implement "--continue" CLI arg (alias "-c") (#559)

* Implement "--continue" CLI arg (alias "-c")

* Rename _continue -> _continue_at_start

    - Use _continue_at_start__setting for attribute to differentiate
      from the existing _continue_at_start attribute

* Extract _waiting_for_mainpyfile()

* Add help text
This commit is contained in:
Michael van der Kamp 2022-09-26 22:09:06 -07:00 committed by GitHub
parent 121caa53ca
commit db13b83e80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 17 deletions

View File

@ -106,8 +106,11 @@ def runmodule(*args, **kwargs):
def runscript(mainpyfile, args=None, pre_run="", steal_output=False,
run_as_module=False):
dbg = _get_debugger(steal_output=steal_output)
_continue_at_start=False, run_as_module=False):
dbg = _get_debugger(
steal_output=steal_output,
_continue_at_start=_continue_at_start,
)
# 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

View File

@ -183,7 +183,7 @@ class Debugger(bdb.Bdb):
_current_debugger = []
def __init__(self, stdin=None, stdout=None, term_size=None, steal_output=False,
**kwargs):
_continue_at_start=False, **kwargs):
if Debugger._current_debugger:
raise ValueError("a Debugger instance already exists")
@ -193,6 +193,7 @@ class Debugger(bdb.Bdb):
bdb.Bdb.__init__(self, **kwargs)
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.setup_state()
@ -304,6 +305,7 @@ class Debugger(bdb.Bdb):
self.bottom_frame = None
self.mainpyfile = ""
self._wait_for_mainpyfile = False
self._continue_at_start = self._continue_at_start__setting
self.current_bp = None
self.post_mortem = False
# Mapping of (filename, lineno) to bool. If True, will stop on the
@ -442,12 +444,8 @@ class Debugger(bdb.Bdb):
if "__exc_tuple__" in frame.f_locals:
del frame.f_locals["__exc_tuple__"]
if self._wait_for_mainpyfile:
if (self.mainpyfile != self.canonic(frame.f_code.co_filename)
or frame.f_lineno <= 0):
return
self._wait_for_mainpyfile = False
self.bottom_frame = frame
if self._waiting_for_mainpyfile(frame):
return
if self.get_break(self.canonic(frame.f_code.co_filename), frame.f_lineno):
self.current_bp = (
@ -466,16 +464,25 @@ class Debugger(bdb.Bdb):
if frame.f_code.co_name != "<module>":
frame.f_locals["__return__"] = return_value
if self._wait_for_mainpyfile:
if (self.mainpyfile != self.canonic(frame.f_code.co_filename)
or frame.f_lineno <= 0):
return
self._wait_for_mainpyfile = False
self.bottom_frame = frame
if self._waiting_for_mainpyfile(frame):
return
if "__exc_tuple__" not in frame.f_locals:
self.interaction(frame)
def _waiting_for_mainpyfile(self, frame):
if self._wait_for_mainpyfile:
if (self.mainpyfile != self.canonic(frame.f_code.co_filename)
or frame.f_lineno <= 0):
return True
self._wait_for_mainpyfile = False
self.bottom_frame = frame
if self._continue_at_start:
self._continue_at_start = False
self.set_continue()
return True
return False
def user_exception(self, frame, exc_tuple):
"""This function is called if an exception occurs,
but only if we are to stop at or just below this level."""
@ -506,7 +513,7 @@ class Debugger(bdb.Bdb):
# events depends on python version). So we take special measures to
# avoid stopping before we reach the main script (see user_line and
# user_call for details).
self._wait_for_mainpyfile = 1
self._wait_for_mainpyfile = True
self.mainpyfile = self.canonic(filename)
statement = 'exec(compile(open("{}").read(), "{}", "exec"))'.format(
filename, filename)

View File

@ -32,7 +32,14 @@ def get_argparse_parser():
epilog=version_info
)
shtab.add_argument_to(parser, preamble=PREAMBLE)
parser.add_argument("-s", "--steal-output", action="store_true"),
# dest="_continue_at_start" needed as "continue" is a python keyword
parser.add_argument(
"-c", "--continue",
action="store_true",
dest="_continue_at_start",
help="Let the script run until an exception occurs or a breakpoint is hit",
)
parser.add_argument("-s", "--steal-output", action="store_true")
# note: we're implementing -m as a boolean flag, mimicking pdb's behavior,
# and makes it possible without much fuss to support cases like:
@ -69,6 +76,7 @@ def main(**kwargs):
options_kwargs = {
"pre_run": options.pre_run,
"steal_output": options.steal_output,
"_continue_at_start": options._continue_at_start,
}
if len(args) < 1: