]> granicus.if.org Git - python/commitdiff
#1565525: Add traceback.clear_frames() helper function to clear locals ref'd by a...
authorAndrew Kuchling <amk@amk.ca>
Sun, 15 Sep 2013 22:15:56 +0000 (18:15 -0400)
committerAndrew Kuchling <amk@amk.ca>
Sun, 15 Sep 2013 22:15:56 +0000 (18:15 -0400)
Doc/library/traceback.rst
Doc/whatsnew/3.4.rst
Lib/test/test_traceback.py
Lib/traceback.py
Misc/NEWS

index 0533beaf8c324103bfeb665836d377fb98a37b51..b68a8f1e1971df69c7bd00a412edc24434c6783a 100644 (file)
@@ -129,6 +129,13 @@ The module defines the following functions:
 
    A shorthand for ``format_list(extract_stack(f, limit))``.
 
+.. function:: clear_frames(tb)
+
+   Clears the local variables of all the stack frames in a traceback *tb*
+   by calling the :meth:`clear` method of each frame object.
+
+   .. versionadded:: 3.4
+
 
 .. _traceback-example:
 
index e91ce2a675cde3752f419cd87fa88b89a2127fdd..89912a9cf71e1412c14c2e34d20859d636db7fc4 100644 (file)
@@ -377,6 +377,14 @@ plain tuple.  (Contributed by Claudiu Popa in :issue:`18901`.)
 :meth:`sunau.open` now supports the context manager protocol (:issue:`18878`).
 
 
+traceback
+---------
+
+A new :func:`traceback.clear_frames` function takes a traceback object
+and clears the local variables in all of the frames it references,
+reducing the amount of memory consumed (:issue:`1565525`).
+
+
 urllib
 ------
 
index 66a12bf12c12c5621e4bad4cb1559370def9eff9..96ef951139eb3adcfc837e291afe8646fd6b65a6 100644 (file)
@@ -388,6 +388,36 @@ class CExcReportingTests(BaseExceptionReportingTests, unittest.TestCase):
         return s.getvalue()
 
 
+class MiscTracebackCases(unittest.TestCase):
+    #
+    # Check non-printing functions in traceback module
+    #
+
+    def test_clear(self):
+        def outer():
+            middle()
+        def middle():
+            inner()
+        def inner():
+            i = 1
+            1/0
+
+        try:
+            outer()
+        except:
+            type_, value, tb = sys.exc_info()
+
+        # Initial assertion: there's one local in the inner frame.
+        inner_frame = tb.tb_next.tb_next.tb_next.tb_frame
+        self.assertEqual(len(inner_frame.f_locals), 1)
+
+        # Clear traceback frames
+        traceback.clear_frames(tb)
+
+        # Local variable dict should now be empty.
+        self.assertEqual(len(inner_frame.f_locals), 0)
+
+
 def test_main():
     run_unittest(__name__)
 
index 3aa1578f4e425c9523e9f2b23c35779322571e26..d5b37528babd8a5579db8def4df997d9a45ea4f2 100644 (file)
@@ -7,7 +7,8 @@ import operator
 __all__ = ['extract_stack', 'extract_tb', 'format_exception',
            'format_exception_only', 'format_list', 'format_stack',
            'format_tb', 'print_exc', 'format_exc', 'print_exception',
-           'print_last', 'print_stack', 'print_tb']
+           'print_last', 'print_stack', 'print_tb',
+           'clear_frames']
 
 #
 # Formatting and printing lists of traceback lines.
@@ -299,3 +300,13 @@ def extract_stack(f=None, limit=None):
     stack = list(_extract_stack_iter(_get_stack(f), limit=limit))
     stack.reverse()
     return stack
+
+def clear_frames(tb):
+    "Clear all references to local variables in the frames of a traceback."
+    while tb is not None:
+        try:
+            tb.tb_frame.clear()
+        except RuntimeError:
+            # Ignore the exception raised if the frame is still executing.
+            pass
+        tb = tb.tb_next
index e4325674e2ac59cdb724c2b2dca434ec55466a0f..f13755327174df92125e2e1de1a8fde19e907984 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -32,6 +32,11 @@ Library
   faulthandler module if the variable is non-empty. Same behaviour than other
   variables like :envvar:`PYTHONDONTWRITEBYTECODE`.
 
+- Issue #1565525: New function ``traceback.clear_frames`` will clear
+  the local variables of all the stack frames referenced by a traceback
+  object.
+
+
 Tests
 -----