summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_traceback.py35
-rw-r--r--Lib/traceback.py6
-rw-r--r--Misc/NEWS3
3 files changed, 44 insertions, 0 deletions
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 641a2df..0362504 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -289,6 +289,31 @@ class TracebackFormatTests(unittest.TestCase):
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 = (
"\nThe above exception was the direct cause "
@@ -610,6 +635,16 @@ class MiscTracebackCases(unittest.TestCase):
# Local variable dict should now be empty.
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):
diff --git a/Lib/traceback.py b/Lib/traceback.py
index 02edeb6..112e9ba 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -181,11 +181,15 @@ def print_stack(f=None, limit=None, file=None):
stack frame at which to start. The optional 'limit' and 'file'
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)
def format_stack(f=None, limit=None):
"""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))
@@ -198,6 +202,8 @@ def extract_stack(f=None, limit=None):
line number, function name, text), and the entries are in order
from oldest to newest stack frame.
"""
+ if f is None:
+ f = sys._getframe().f_back
stack = StackSummary.extract(walk_stack(f), limit=limit)
stack.reverse()
return stack
diff --git a/Misc/NEWS b/Misc/NEWS
index bd4bd44..02917a1 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -14,6 +14,9 @@ Core and Builtins
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 #24684: socket.socket.getaddrinfo() now calls