bpo-35931: Gracefully handle any exception in pdb debug command (GH-12103)
This is relevant for `debug doesnotexist()`, which would crash with a NameError otherwise.
This commit is contained in:
parent
1ceb3a3d17
commit
3e936431e2
12
Lib/pdb.py
12
Lib/pdb.py
|
@ -1093,16 +1093,14 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
sys.settrace(None)
|
sys.settrace(None)
|
||||||
globals = self.curframe.f_globals
|
globals = self.curframe.f_globals
|
||||||
locals = self.curframe_locals
|
locals = self.curframe_locals
|
||||||
try:
|
|
||||||
code = compile(arg, "<string>", "exec")
|
|
||||||
except SyntaxError:
|
|
||||||
exc_info = sys.exc_info()[:2]
|
|
||||||
self.error(traceback.format_exception_only(*exc_info)[-1].strip())
|
|
||||||
return
|
|
||||||
p = Pdb(self.completekey, self.stdin, self.stdout)
|
p = Pdb(self.completekey, self.stdin, self.stdout)
|
||||||
p.prompt = "(%s) " % self.prompt.strip()
|
p.prompt = "(%s) " % self.prompt.strip()
|
||||||
self.message("ENTERING RECURSIVE DEBUGGER")
|
self.message("ENTERING RECURSIVE DEBUGGER")
|
||||||
sys.call_tracing(p.run, (code, globals, locals))
|
try:
|
||||||
|
sys.call_tracing(p.run, (arg, globals, locals))
|
||||||
|
except Exception:
|
||||||
|
exc_info = sys.exc_info()[:2]
|
||||||
|
self.error(traceback.format_exception_only(*exc_info)[-1].strip())
|
||||||
self.message("LEAVING RECURSIVE DEBUGGER")
|
self.message("LEAVING RECURSIVE DEBUGGER")
|
||||||
sys.settrace(self.trace_dispatch)
|
sys.settrace(self.trace_dispatch)
|
||||||
self.lastcmd = p.lastcmd
|
self.lastcmd = p.lastcmd
|
||||||
|
|
|
@ -1486,12 +1486,26 @@ class PdbTestCase(unittest.TestCase):
|
||||||
stdout, _ = self._run_pdb(['-m', self.module_name + '.runme'], commands)
|
stdout, _ = self._run_pdb(['-m', self.module_name + '.runme'], commands)
|
||||||
self.assertTrue(any("VAR from module" in l for l in stdout.splitlines()), stdout)
|
self.assertTrue(any("VAR from module" in l for l in stdout.splitlines()), stdout)
|
||||||
|
|
||||||
def test_syntaxerror_in_command(self):
|
def test_errors_in_command(self):
|
||||||
commands = "print(\ndebug print("
|
commands = "\n".join([
|
||||||
stdout, _ = self.run_pdb_script("", commands)
|
'print(',
|
||||||
|
'debug print(',
|
||||||
|
'debug doesnotexist',
|
||||||
|
'c',
|
||||||
|
])
|
||||||
|
stdout, _ = self.run_pdb_script('', commands + '\n')
|
||||||
|
|
||||||
self.assertEqual(stdout.splitlines()[1:], [
|
self.assertEqual(stdout.splitlines()[1:], [
|
||||||
'(Pdb) *** SyntaxError: unexpected EOF while parsing',
|
'(Pdb) *** SyntaxError: unexpected EOF while parsing',
|
||||||
'(Pdb) *** SyntaxError: unexpected EOF while parsing',
|
|
||||||
|
'(Pdb) ENTERING RECURSIVE DEBUGGER',
|
||||||
|
'*** SyntaxError: unexpected EOF while parsing',
|
||||||
|
'LEAVING RECURSIVE DEBUGGER',
|
||||||
|
|
||||||
|
'(Pdb) ENTERING RECURSIVE DEBUGGER',
|
||||||
|
'> <string>(1)<module>()',
|
||||||
|
"((Pdb)) *** NameError: name 'doesnotexist' is not defined",
|
||||||
|
'LEAVING RECURSIVE DEBUGGER',
|
||||||
'(Pdb) ',
|
'(Pdb) ',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
The :mod:`pdb` ``debug`` command now gracefully handles all exceptions.
|
Loading…
Reference in New Issue