#1565525: Add traceback.clear_frames() helper function to clear locals ref'd by a traceback

This commit is contained in:
Andrew Kuchling 2013-09-15 18:15:56 -04:00
parent 8408dc581e
commit 173a157e72
5 changed files with 62 additions and 1 deletions

View 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:

View 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
------

View 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__)

View 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

View File

@ -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
-----