]> granicus.if.org Git - python/commitdiff
Issue #23631: Fix traceback.format_list when a traceback has been mutated.
authorRobert Collins <rbtcollins@hp.com>
Mon, 16 Mar 2015 02:27:16 +0000 (15:27 +1300)
committerRobert Collins <rbtcollins@hp.com>
Mon, 16 Mar 2015 02:27:16 +0000 (15:27 +1300)
Lib/test/test_traceback.py
Lib/traceback.py
Misc/NEWS

index d9b73c133fc2e1db1e60340e8f9f414a409179f9..9c8929fc3245f611a1f8ca7efeee5901e023c4f7 100644 (file)
@@ -555,6 +555,14 @@ class TestStack(unittest.TestCase):
             ['  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 @@ class TestStack(unittest.TestCase):
                 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'
index 0ac181923d762b7ab9816aebcf5a073818597817..f7705cdabc3a5584cd8104fbfde307b23996b206 100644 (file)
@@ -348,11 +348,17 @@ class StackSummary(list):
         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):
index f51a74b09d75b123211d68bc453c567e976cbd24..13c4b3edff2ade38eb086abe96c2f62c603b6c73 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,8 @@ Core and Builtins
 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.