summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_bdb.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_bdb.py')
-rw-r--r--Lib/test/test_bdb.py269
1 files changed, 71 insertions, 198 deletions
diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py
index 6e82cce..3ad70e2 100644
--- a/Lib/test/test_bdb.py
+++ b/Lib/test/test_bdb.py
@@ -48,6 +48,9 @@
The arguments of the set method if any, packed in a tuple.
"""
+from __future__ import absolute_import
+from __future__ import print_function
+
import bdb as _bdb
import sys
import os
@@ -70,6 +73,8 @@ class BdbNotExpectedError(BdbException): """Unexpected result."""
# after each 'line' event where a breakpoint has been hit.
dry_run = 0
+__file__ = os.path.splitext(__file__)[0] + '.py'
+
def reset_Breakpoint():
_bdb.Breakpoint.next = 1
_bdb.Breakpoint.bplist = {}
@@ -96,12 +101,12 @@ def info_breakpoints():
info += '\n'
return info
-class Bdb(_bdb.Bdb):
+class Bdb(_bdb.Bdb, object):
"""Extend Bdb to enhance test coverage."""
def trace_dispatch(self, frame, event, arg):
self.currentbp = None
- return super().trace_dispatch(frame, event, arg)
+ return super(Bdb, self).trace_dispatch(frame, event, arg)
def set_break(self, filename, lineno, temporary=False, cond=None,
funcname=None):
@@ -117,14 +122,35 @@ class Bdb(_bdb.Bdb):
lineno = code.co_firstlineno
funcname = code.co_name
- res = super().set_break(filename, lineno, temporary=temporary,
- cond=cond, funcname=funcname)
+ res = super(Bdb, self).set_break(filename, lineno,
+ temporary=temporary, cond=cond, funcname=funcname)
if isinstance(res, str):
raise BdbError(res)
return res
+ # Back port of get_bpbynumber() from bdb.Bdb in Python 3.
+ def get_bpbynumber(self, arg):
+ """Return a breakpoint by its index in Breakpoint.bybpnumber.
+
+ For invalid arg values or if the breakpoint doesn't exist,
+ raise a ValueError.
+ """
+ if not arg:
+ raise ValueError('Breakpoint number expected')
+ try:
+ number = int(arg)
+ except ValueError:
+ raise ValueError('Non-numeric breakpoint number %s' % arg)
+ try:
+ bp = _bdb.Breakpoint.bpbynumber[number]
+ except IndexError:
+ raise ValueError('Breakpoint number %d out of range' % number)
+ if bp is None:
+ raise ValueError('Breakpoint %d already deleted' % number)
+ return bp
+
def get_stack(self, f, t):
- self.stack, self.index = super().get_stack(f, t)
+ self.stack, self.index = super(Bdb, self).get_stack(f, t)
self.frame = self.stack[self.index][0]
return self.stack, self.index
@@ -164,7 +190,7 @@ class Tracer(Bdb):
"""A tracer for testing the bdb module."""
def __init__(self, expect_set, skip=None, dry_run=False, test_case=None):
- super().__init__(skip=skip)
+ super(Tracer, self).__init__(skip=skip)
self.expect_set = expect_set
self.dry_run = dry_run
self.header = ('Dry-run results for %s:' % test_case if
@@ -188,13 +214,13 @@ class Tracer(Bdb):
if event == 'exception':
try:
- res = super().trace_dispatch(frame, event, arg)
+ res = super(Tracer, self).trace_dispatch(frame, event, arg)
return res
except BdbException as e:
self.cur_except = e
return self.trace_dispatch
else:
- return super().trace_dispatch(frame, event, arg)
+ return super(Tracer, self).trace_dispatch(frame, event, arg)
def user_call(self, frame, argument_list):
# Adopt the same behavior as pdb and, as a side effect, skip also the
@@ -372,11 +398,7 @@ class Tracer(Bdb):
set_method(self.frame)
return
elif set_type == 'until':
- lineno = None
- if args:
- lineno = self.lno_rel2abs(self.frame.f_code.co_filename,
- args[0])
- set_method(self.frame, lineno)
+ set_method(self.frame)
return
# The following set methods do not give back control to the tracer and
@@ -384,10 +406,10 @@ class Tracer(Bdb):
if (args and set_type in ('break', 'clear', 'ignore', 'enable',
'disable')) or set_type in ('up', 'down'):
if set_type in ('break', 'clear'):
- fname, lineno, *remain = args
+ fname = args[0]
+ lineno = args[1]
lineno = self.lno_rel2abs(fname, lineno)
- args = [fname, lineno]
- args.extend(remain)
+ args = [fname, lineno] + list(args[2:])
set_method(*args)
elif set_type in ('ignore', 'enable', 'disable'):
set_method(*args)
@@ -417,17 +439,15 @@ class TracerRun():
self.dry_run = test_case.dry_run
self.tracer = Tracer(test_case.expect_set, skip=skip,
dry_run=self.dry_run, test_case=test_case.id())
- self._original_tracer = None
def __enter__(self):
# test_pdb does not reset Breakpoint class attributes on exit :-(
reset_Breakpoint()
- self._original_tracer = sys.gettrace()
return self.tracer
def __exit__(self, type_=None, value=None, traceback=None):
reset_Breakpoint()
- sys.settrace(self._original_tracer)
+ sys.settrace(None)
not_empty = ''
if self.tracer.set_list:
@@ -526,25 +546,25 @@ def run_test(modules, set_list, skip=None):
test.id = lambda : None
test.expect_set = list(gen(repeat(()), iter(sl)))
with create_modules(modules):
+ sys.path.append(os.getcwd())
with TracerRun(test, skip=skip) as tracer:
tracer.runcall(tfunc_import)
@contextmanager
def create_modules(modules):
with test.support.temp_cwd():
- sys.path.append(os.getcwd())
try:
+ sys.path.insert(0, os.getcwd())
for m in modules:
fname = m + '.py'
with open(fname, 'w') as f:
f.write(textwrap.dedent(modules[m]))
linecache.checkcache(fname)
- importlib.invalidate_caches()
yield
finally:
+ sys.path.pop(0)
for m in modules:
test.support.forget(m)
- sys.path.pop()
def break_in_func(funcname, fname=__file__, temporary=False, cond=None):
return 'break', (fname, None, temporary, cond, funcname)
@@ -573,14 +593,8 @@ def tfunc_second():
class BaseTestCase(unittest.TestCase):
"""Base class for all tests."""
-
dry_run = dry_run
- def fail(self, msg=None):
- # Override fail() to use 'raise from None' to avoid repetition of the
- # error message and traceback.
- raise self.failureException(msg) from None
-
class StateTestCase(BaseTestCase):
"""Test the step, next, return, until and quit 'set_' methods."""
@@ -594,19 +608,29 @@ class StateTestCase(BaseTestCase):
with TracerRun(self) as tracer:
tracer.runcall(tfunc_main)
- def test_step_next_on_last_statement(self):
- for set_type in ('step', 'next'):
- with self.subTest(set_type=set_type):
- self.expect_set = [
- ('line', 2, 'tfunc_main'), ('step', ),
- ('line', 3, 'tfunc_main'), ('step', ),
- ('call', 1, 'tfunc_first'), ('break', (__file__, 3)),
- ('None', 1, 'tfunc_first'), ('continue', ),
- ('line', 3, 'tfunc_first', ({1:1}, [])), (set_type, ),
- ('line', 4, 'tfunc_first'), ('quit', ),
- ]
- with TracerRun(self) as tracer:
- tracer.runcall(tfunc_main)
+ def test_step_on_last_statement(self):
+ self.expect_set = [
+ ('line', 2, 'tfunc_main'), ('step', ),
+ ('line', 3, 'tfunc_main'), ('step', ),
+ ('call', 1, 'tfunc_first'), ('break', (__file__, 3)),
+ ('None', 1, 'tfunc_first'), ('continue', ),
+ ('line', 3, 'tfunc_first', ({1:1}, [])), ('step', ),
+ ('line', 4, 'tfunc_first'), ('quit', ),
+ ]
+ with TracerRun(self) as tracer:
+ tracer.runcall(tfunc_main)
+
+ def test_next_on_last_statement(self):
+ self.expect_set = [
+ ('line', 2, 'tfunc_main'), ('step', ),
+ ('line', 3, 'tfunc_main'), ('step', ),
+ ('call', 1, 'tfunc_first'), ('break', (__file__, 3)),
+ ('None', 1, 'tfunc_first'), ('continue', ),
+ ('line', 3, 'tfunc_first', ({1:1}, [])), ('next', ),
+ ('line', 4, 'tfunc_first'), ('quit', ),
+ ]
+ with TracerRun(self) as tracer:
+ tracer.runcall(tfunc_main)
def test_next(self):
self.expect_set = [
@@ -686,18 +710,8 @@ class StateTestCase(BaseTestCase):
('line', 2, 'tfunc_main'), ('step', ),
('line', 3, 'tfunc_main'), ('step', ),
('call', 1, 'tfunc_first'), ('step', ),
- ('line', 2, 'tfunc_first'), ('until', (4, )),
- ('line', 4, 'tfunc_first'), ('quit', ),
- ]
- with TracerRun(self) as tracer:
- tracer.runcall(tfunc_main)
-
- def test_until_with_too_large_count(self):
- self.expect_set = [
- ('line', 2, 'tfunc_main'), break_in_func('tfunc_first'),
- ('None', 2, 'tfunc_main'), ('continue', ),
- ('line', 2, 'tfunc_first', ({1:1}, [])), ('until', (9999, )),
- ('return', 4, 'tfunc_first'), ('quit', ),
+ ('line', 2, 'tfunc_first'), ('until', ),
+ ('line', 3, 'tfunc_first'), ('quit', ),
]
with TracerRun(self) as tracer:
tracer.runcall(tfunc_main)
@@ -707,8 +721,8 @@ class StateTestCase(BaseTestCase):
('line', 2, 'tfunc_main'), ('step', ),
('line', 3, 'tfunc_main'), ('step', ),
('call', 1, 'tfunc_first'), ('up', ),
- ('None', 3, 'tfunc_main'), ('until', (6, )),
- ('line', 6, 'tfunc_main'), ('quit', ),
+ ('None', 3, 'tfunc_main'), ('until', ),
+ ('line', 4, 'tfunc_main'), ('quit', ),
]
with TracerRun(self) as tracer:
tracer.runcall(tfunc_main)
@@ -726,17 +740,10 @@ class StateTestCase(BaseTestCase):
('line', 2, 'tfunc_import'), ('step', ),
('line', 3, 'tfunc_import'), ('quit', ),
]
- skip = ('importlib*', 'zipimport', TEST_MODULE)
+ skip = ('importlib*', TEST_MODULE)
with TracerRun(self, skip=skip) as tracer:
tracer.runcall(tfunc_import)
- def test_skip_with_no_name_module(self):
- # some frames have `globals` with no `__name__`
- # for instance the second frame in this traceback
- # exec(compile('raise ValueError()', '', 'exec'), {})
- bdb = Bdb(skip=['anything*'])
- self.assertIs(bdb.is_skipped_module(None), False)
-
def test_down(self):
# Check that set_down() raises BdbError at the newest frame.
self.expect_set = [
@@ -861,7 +868,7 @@ class BreakpointTestCase(BaseTestCase):
with create_modules(modules):
self.expect_set = [
('line', 2, 'tfunc_import'),
- break_in_func('func', TEST_MODULE_FNAME, False, '1 / 0'),
+ break_in_func('func', TEST_MODULE_FNAME, False, '1 // 0'),
('None', 2, 'tfunc_import'), ('continue', ),
('line', 3, 'func', ({1:1}, [])), ('quit', ),
]
@@ -1015,140 +1022,6 @@ class IssuesTestCase(BaseTestCase):
with TracerRun(self) as tracer:
tracer.runcall(tfunc_import)
- def test_next_until_return_in_generator(self):
- # Issue #16596.
- # Check that set_next(), set_until() and set_return() do not treat the
- # `yield` and `yield from` statements as if they were returns and stop
- # instead in the current frame.
- code = """
- def test_gen():
- yield 0
- lno = 4
- return 123
-
- def main():
- it = test_gen()
- next(it)
- next(it)
- lno = 11
- """
- modules = { TEST_MODULE: code }
- for set_type in ('next', 'until', 'return'):
- with self.subTest(set_type=set_type):
- with create_modules(modules):
- self.expect_set = [
- ('line', 2, 'tfunc_import'),
- break_in_func('test_gen', TEST_MODULE_FNAME),
- ('None', 2, 'tfunc_import'), ('continue', ),
- ('line', 3, 'test_gen', ({1:1}, [])), (set_type, ),
- ]
-
- if set_type == 'return':
- self.expect_set.extend(
- [('exception', 10, 'main', StopIteration), ('step',),
- ('return', 10, 'main'), ('quit', ),
- ]
- )
- else:
- self.expect_set.extend(
- [('line', 4, 'test_gen'), ('quit', ),]
- )
- with TracerRun(self) as tracer:
- tracer.runcall(tfunc_import)
-
- def test_next_command_in_generator_for_loop(self):
- # Issue #16596.
- code = """
- def test_gen():
- yield 0
- lno = 4
- yield 1
- return 123
-
- def main():
- for i in test_gen():
- lno = 10
- lno = 11
- """
- modules = { TEST_MODULE: code }
- with create_modules(modules):
- self.expect_set = [
- ('line', 2, 'tfunc_import'),
- break_in_func('test_gen', TEST_MODULE_FNAME),
- ('None', 2, 'tfunc_import'), ('continue', ),
- ('line', 3, 'test_gen', ({1:1}, [])), ('next', ),
- ('line', 4, 'test_gen'), ('next', ),
- ('line', 5, 'test_gen'), ('next', ),
- ('line', 6, 'test_gen'), ('next', ),
- ('exception', 9, 'main', StopIteration), ('step', ),
- ('line', 11, 'main'), ('quit', ),
-
- ]
- with TracerRun(self) as tracer:
- tracer.runcall(tfunc_import)
-
- def test_next_command_in_generator_with_subiterator(self):
- # Issue #16596.
- code = """
- def test_subgen():
- yield 0
- return 123
-
- def test_gen():
- x = yield from test_subgen()
- return 456
-
- def main():
- for i in test_gen():
- lno = 12
- lno = 13
- """
- modules = { TEST_MODULE: code }
- with create_modules(modules):
- self.expect_set = [
- ('line', 2, 'tfunc_import'),
- break_in_func('test_gen', TEST_MODULE_FNAME),
- ('None', 2, 'tfunc_import'), ('continue', ),
- ('line', 7, 'test_gen', ({1:1}, [])), ('next', ),
- ('line', 8, 'test_gen'), ('next', ),
- ('exception', 11, 'main', StopIteration), ('step', ),
- ('line', 13, 'main'), ('quit', ),
-
- ]
- with TracerRun(self) as tracer:
- tracer.runcall(tfunc_import)
-
- def test_return_command_in_generator_with_subiterator(self):
- # Issue #16596.
- code = """
- def test_subgen():
- yield 0
- return 123
-
- def test_gen():
- x = yield from test_subgen()
- return 456
-
- def main():
- for i in test_gen():
- lno = 12
- lno = 13
- """
- modules = { TEST_MODULE: code }
- with create_modules(modules):
- self.expect_set = [
- ('line', 2, 'tfunc_import'),
- break_in_func('test_subgen', TEST_MODULE_FNAME),
- ('None', 2, 'tfunc_import'), ('continue', ),
- ('line', 3, 'test_subgen', ({1:1}, [])), ('return', ),
- ('exception', 7, 'test_gen', StopIteration), ('return', ),
- ('exception', 11, 'main', StopIteration), ('step', ),
- ('line', 13, 'main'), ('quit', ),
-
- ]
- with TracerRun(self) as tracer:
- tracer.runcall(tfunc_import)
-
def test_main():
test.support.run_unittest(
StateTestCase,