changeset: 95002:ea3cc128ce35 user: Robert Collins date: Mon Mar 16 15:27:16 2015 +1300 files: Lib/test/test_traceback.py Lib/traceback.py Misc/NEWS description: Issue #23631: Fix traceback.format_list when a traceback has been mutated. diff -r b7affa4517c3 -r ea3cc128ce35 Lib/test/test_traceback.py --- a/Lib/test/test_traceback.py Sun Mar 15 23:43:34 2015 +0200 +++ b/Lib/test/test_traceback.py Mon Mar 16 15:27:16 2015 +1300 @@ -555,6 +555,14 @@ [' File "foo.py", line 1, in fred\n line\n'], s.format()) + def test_from_list_edited_stack(self): + s = traceback.StackSummary.from_list([('foo.py', 1, 'fred', 'line')]) + s[0] = ('foo.py', 2, 'fred', 'line') + s2 = traceback.StackSummary.from_list(s) + self.assertEqual( + [' File "foo.py", line 2, in fred\n line\n'], + s2.format()) + def test_format_smoke(self): # For detailed tests see the format_list tests, which consume the same # code. @@ -585,7 +593,7 @@ traceback.walk_stack(None), capture_locals=True, limit=1) s = some_inner(3, 4) self.assertEqual( - [' File "' + __file__ + '", line 585, ' + [' File "' + __file__ + '", line 593, ' 'in some_inner\n' ' traceback.walk_stack(None), capture_locals=True, limit=1)\n' ' a = 1\n' diff -r b7affa4517c3 -r ea3cc128ce35 Lib/traceback.py --- a/Lib/traceback.py Sun Mar 15 23:43:34 2015 +0200 +++ b/Lib/traceback.py Mon Mar 16 15:27:16 2015 +1300 @@ -348,11 +348,17 @@ This method supports the older Python API. Each tuple should be a 4-tuple with (filename, lineno, name, line) elements. """ - if isinstance(a_list, StackSummary): - return StackSummary(a_list) + # While doing a fast-path check for isinstance(a_list, StackSummary) is + # appealing, idlelib.run.cleanup_traceback and other similar code may + # break this by making arbitrary frames plain tuples, so we need to + # check on a frame by frame basis. result = StackSummary() - for filename, lineno, name, line in a_list: - result.append(FrameSummary(filename, lineno, name, line=line)) + for frame in a_list: + if isinstance(frame, FrameSummary): + result.append(frame) + else: + filename, lineno, name, line = frame + result.append(FrameSummary(filename, lineno, name, line=line)) return result def format(self): diff -r b7affa4517c3 -r ea3cc128ce35 Misc/NEWS --- a/Misc/NEWS Sun Mar 15 23:43:34 2015 +0200 +++ b/Misc/NEWS Mon Mar 16 15:27:16 2015 +1300 @@ -18,6 +18,8 @@ Library ------- +- Issue #23631: Fix traceback.format_list when a traceback has been mutated. + - Issue #23568: Add rdivmod support to MagicMock() objects. Patch by Håkan Lövdahl.