Issue #25108: Omitted internal frames in traceback functions print_stack(),

format_stack(), and extract_stack() called without arguments.
This commit is contained in:
Serhiy Storchaka 2015-09-18 10:06:23 +03:00
commit 4ebf9d3a21
3 changed files with 44 additions and 0 deletions

View File

@ -289,6 +289,31 @@ class TracebackFormatTests(unittest.TestCase):
self.assertEqual(ststderr.getvalue(), "".join(stfmt)) self.assertEqual(ststderr.getvalue(), "".join(stfmt))
def test_print_stack(self):
def prn():
traceback.print_stack()
with captured_output("stderr") as stderr:
prn()
lineno = prn.__code__.co_firstlineno
self.assertEqual(stderr.getvalue().splitlines()[-4:], [
' File "%s", line %d, in test_print_stack' % (__file__, lineno+3),
' prn()',
' File "%s", line %d, in prn' % (__file__, lineno+1),
' traceback.print_stack()',
])
def test_format_stack(self):
def fmt():
return traceback.format_stack()
result = fmt()
lineno = fmt.__code__.co_firstlineno
self.assertEqual(result[-2:], [
' File "%s", line %d, in test_format_stack\n'
' result = fmt()\n' % (__file__, lineno+2),
' File "%s", line %d, in fmt\n'
' return traceback.format_stack()\n' % (__file__, lineno+1),
])
cause_message = ( cause_message = (
"\nThe above exception was the direct cause " "\nThe above exception was the direct cause "
@ -610,6 +635,16 @@ class MiscTracebackCases(unittest.TestCase):
# Local variable dict should now be empty. # Local variable dict should now be empty.
self.assertEqual(len(inner_frame.f_locals), 0) self.assertEqual(len(inner_frame.f_locals), 0)
def test_extract_stack(self):
def extract():
return traceback.extract_stack()
result = extract()
lineno = extract.__code__.co_firstlineno
self.assertEqual([tuple(x) for x in result[-2:]], [
(__file__, lineno+2, 'test_extract_stack', 'result = extract()'),
(__file__, lineno+1, 'extract', 'return traceback.extract_stack()'),
])
class TestFrame(unittest.TestCase): class TestFrame(unittest.TestCase):

View File

@ -181,11 +181,15 @@ def print_stack(f=None, limit=None, file=None):
stack frame at which to start. The optional 'limit' and 'file' stack frame at which to start. The optional 'limit' and 'file'
arguments have the same meaning as for print_exception(). arguments have the same meaning as for print_exception().
""" """
if f is None:
f = sys._getframe().f_back
print_list(extract_stack(f, limit=limit), file=file) print_list(extract_stack(f, limit=limit), file=file)
def format_stack(f=None, limit=None): def format_stack(f=None, limit=None):
"""Shorthand for 'format_list(extract_stack(f, limit))'.""" """Shorthand for 'format_list(extract_stack(f, limit))'."""
if f is None:
f = sys._getframe().f_back
return format_list(extract_stack(f, limit=limit)) return format_list(extract_stack(f, limit=limit))
@ -198,6 +202,8 @@ def extract_stack(f=None, limit=None):
line number, function name, text), and the entries are in order line number, function name, text), and the entries are in order
from oldest to newest stack frame. from oldest to newest stack frame.
""" """
if f is None:
f = sys._getframe().f_back
stack = StackSummary.extract(walk_stack(f), limit=limit) stack = StackSummary.extract(walk_stack(f), limit=limit)
stack.reverse() stack.reverse()
return stack return stack

View File

@ -103,6 +103,9 @@ Core and Builtins
Library Library
------- -------
- Issue #25108: Omitted internal frames in traceback functions print_stack(),
format_stack(), and extract_stack() called without arguments.
- Issue #25118: Fix a regression of Python 3.5.0 in os.waitpid() on Windows. - Issue #25118: Fix a regression of Python 3.5.0 in os.waitpid() on Windows.
- Issue #24684: socket.socket.getaddrinfo() now calls - Issue #24684: socket.socket.getaddrinfo() now calls