Skip to content

Commit 7d2f597

Browse files
Stop early when tracing exceptions
1 parent 1a390e1 commit 7d2f597

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

Lib/test/test_capi/test_opt.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3606,6 +3606,51 @@ async def async_for_driver():
36063606
"""), PYTHON_JIT="1")
36073607
self.assertEqual(result[0].rc, 0, result)
36083608

3609+
def test_143358(self):
3610+
# https://github.com/python/cpython/issues/143358
3611+
3612+
result = script_helper.run_python_until_end('-c', textwrap.dedent(f"""
3613+
def f1():
3614+
3615+
class EvilIterator:
3616+
3617+
def __init__(self):
3618+
self._items = [1, 2]
3619+
self._index = 1
3620+
3621+
def __iter__(self):
3622+
return self
3623+
3624+
def __next__(self):
3625+
if not len(self._items) % 13:
3626+
self._items.clear()
3627+
3628+
for i_loop_9279 in range(10):
3629+
self._items.extend([1, "", None])
3630+
3631+
if not len(self._items) % 11:
3632+
return 'unexpected_type_from_iterator'
3633+
3634+
if self._index >= len(self._items):
3635+
raise StopIteration
3636+
3637+
item = self._items[self._index]
3638+
self._index += 1
3639+
return item
3640+
3641+
evil_iter = EvilIterator()
3642+
3643+
large_num = 2**31
3644+
for _ in range(400):
3645+
try:
3646+
_ = [x + y for x in evil_iter for y in evil_iter if evil_iter._items.append(x) or large_num]
3647+
except TypeError:
3648+
pass
3649+
3650+
f1()
3651+
"""), PYTHON_JIT="1", PYTHON_JIT_JUMP_BACKWARD_INITIAL_VALUE="64")
3652+
self.assertEqual(result[0].rc, 0, result)
3653+
36093654
def global_identity(x):
36103655
return x
36113656

Python/bytecodes.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5607,6 +5607,16 @@ dummy_func(
56075607
#else
56085608
assert(_PyErr_Occurred(tstate));
56095609
#endif
5610+
#if _Py_TIER2
5611+
if (IS_JIT_TRACING()) {
5612+
LEAVE_TRACING();
5613+
int res = stop_tracing_and_jit(tstate, frame);
5614+
(void)res;
5615+
// We shouldn't ven have compiled in the first place.
5616+
assert(res == 0);
5617+
}
5618+
#endif
5619+
56105620

56115621
/* Log traceback info. */
56125622
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);

Python/generated_cases.c.h

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)