Skip to content
Draft
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
12 changes: 12 additions & 0 deletions Lib/bdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,18 @@ def reset(self):
self.botframe = None
self._set_stopinfo(None, None)

def update_skip(self, patterns):
if self.skip is None:
self.skip = set(patterns)
else:
self.skip.update(patterns)

def remove_skip(self, patterns):
if self.skip is None:
return
else:
self.skip.difference_update(patterns)

@contextmanager
def set_enterframe(self, frame):
self.enterframe = frame
Expand Down
48 changes: 48 additions & 0 deletions Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -2269,6 +2269,54 @@ def do_retval(self, arg):
self.error('Not yet returned!')
do_rv = do_retval

def do_skip(self, arg):
"""skip module_pattern [module_pattern ...]

Add glob-style module-name patterns to the modules that the debugger
will not step into. With no arguments, display the current patterns.
"""
if not arg:
skipped_modules = [f"\t{x}" for x in sorted(self.skip or ())]
lines = ["Skipped module patterns:"]
lines.extend(skipped_modules or ["\t(none)"])
self.message("\n".join(lines))
return
args = arg.split()
self.update_skip(args)

def do_skip_stdlib(self, arg):
"""skip_stdlib

Do not step into frames originating in standard-library modules.
"""
if arg:
self._print_invalid_arg(arg)
return
self.update_skip(sys.stdlib_module_names)
self.update_skip((f"{x}.*" for x in sys.stdlib_module_names))

def do_unskip(self, arg):
"""unskip module_pattern [module_pattern ...]

Remove glob-style module-name patterns from the skip set.
"""
if not arg:
self._print_invalid_arg(arg)
return
args = arg.split()
self.remove_skip(args)

def do_unskip_stdlib(self, arg):
"""unskip_stdlib

Remove standard-library module patterns from the skip set.
"""
if arg:
self._print_invalid_arg(arg)
return
self.remove_skip(sys.stdlib_module_names)
self.remove_skip((f"{x}.*" for x in sys.stdlib_module_names))

def _getval(self, arg):
try:
return eval(arg, self.curframe.f_globals, self.curframe.f_locals)
Expand Down
48 changes: 47 additions & 1 deletion Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ def test_pdb_basic_commands():
... 'next', # step to test_function4()
... 'step', # stepping to test_function4()
... 'args', # display function args
... 'skip',
... 'skip asyncio os.*',
... 'skip',
... 'unskip os',
... 'skip',
... 'unskip os.*',
... 'skip',
... 'continue',
... ]):
... test_function()
Expand Down Expand Up @@ -154,7 +161,7 @@ def test_pdb_basic_commands():
[EOF]
(Pdb) bt
...
<doctest test.test_pdb.test_pdb_basic_commands[4]>(26)<module>()
<doctest test.test_pdb.test_pdb_basic_commands[4]>(33)<module>()
-> test_function()
<doctest test.test_pdb.test_pdb_basic_commands[3]>(3)test_function()
-> ret = test_function_2('baz')
Expand Down Expand Up @@ -224,6 +231,23 @@ def test_pdb_basic_commands():
a = 1
b = 2
c = 3
(Pdb) skip
Skipped module patterns:
(none)
(Pdb) skip asyncio os.*
(Pdb) skip
Skipped module patterns:
asyncio
os.*
(Pdb) unskip os
(Pdb) skip
Skipped module patterns:
asyncio
os.*
(Pdb) unskip os.*
(Pdb) skip
Skipped module patterns:
asyncio
(Pdb) continue
BAZ
"""
Expand Down Expand Up @@ -4821,6 +4845,28 @@ def test_checkline_is_not_executable(self):
for lineno in range(num_lines):
self.assertFalse(db.checkline(os_helper.TESTFN, lineno))

class SkipCommandsTestCase(unittest.TestCase):
def test_skip_and_unskip(self):
debugger = pdb.Pdb(readrc=False)

debugger.onecmd("skip asyncio os.*")
self.assertEqual(debugger.skip, {"asyncio", "os.*"})

debugger.onecmd("unskip os.*")
self.assertEqual(debugger.skip, {"asyncio"})

def test_skip_stdlib(self):
debugger = pdb.Pdb(readrc=False)

debugger.onecmd("skip_stdlib")
self.assertIn("os", debugger.skip)
self.assertIn("os.*", debugger.skip)
self.assertEqual(len(debugger.skip), len(sys.stdlib_module_names)*2)

debugger.onecmd("unskip_stdlib")
self.assertNotIn("os", debugger.skip)
self.assertNotIn("os.*", debugger.skip)
self.assertEqual(len(debugger.skip), 0)

@support.requires_subprocess()
class PdbTestInline(unittest.TestCase):
Expand Down
Loading