#1565525: Add traceback.clear_frames() helper function to clear locals ref'd by a traceback
This commit is contained in:
parent
8408dc581e
commit
173a157e72
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
------
|
||||
|
||||
|
|
|
@ -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__)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
-----
|
||||
|
||||
|
|
Loading…
Reference in New Issue