mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
gh-96092: Fix traceback.walk_stack(None) skipping too many frames (#129330)
As it says in its documentation, walk_stack was meant to just follow `f.f_back` like other functions in the traceback module. Instead it was previously doing `f.f_back.f_back` and then this changed to `f_back.f_back.f_back.f_back' in Python 3.11 breaking its behavior for external users. This happened because the walk_stack function never really had any good direct tests and its only consumer in the traceback module was `extract_stack` which passed the result into `StackSummary.extract`. As a generator, it was previously capturing the state of the stack when it was first iterated over, rather than the stack when `walk_stack` was called. Meaning when called inside the two method deep `extract` and `extract_stack` calls, two `f_back`s were needed. When 3.11 modified the sequence of calls in `extract`, two more `f_back`s were needed to make the tests happy. This changes the generator to capture the stack when `walk_stack` is called, rather than when it is first iterated over. Since this is technically a breaking change in behavior, there is a versionchanged to the documentation. In practice, this is unlikely to break anyone, you would have been needing to store the result of `walk_stack` and expecting it to change.
This commit is contained in:
parent
6fb5138776
commit
f9a7d41bac
4 changed files with 25 additions and 6 deletions
|
@ -3229,11 +3229,17 @@ class TestStack(unittest.TestCase):
|
|||
def test_walk_stack(self):
|
||||
def deeper():
|
||||
return list(traceback.walk_stack(None))
|
||||
s1 = list(traceback.walk_stack(None))
|
||||
s2 = deeper()
|
||||
s1, s2 = list(traceback.walk_stack(None)), deeper()
|
||||
self.assertEqual(len(s2) - len(s1), 1)
|
||||
self.assertEqual(s2[1:], s1)
|
||||
|
||||
def test_walk_innermost_frame(self):
|
||||
def inner():
|
||||
return list(traceback.walk_stack(None))
|
||||
frames = inner()
|
||||
innermost_frame, _ = frames[0]
|
||||
self.assertEqual(innermost_frame.f_code.co_name, "inner")
|
||||
|
||||
def test_walk_tb(self):
|
||||
try:
|
||||
1/0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue