Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit601ae09

Browse files
authored
GH-105162: Account forINSTRUMENTED_RESUME in gen.close/throw. (GH-105187)
1 parentee26ca1 commit601ae09

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

‎Lib/test/test_monitoring.py‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,3 +1425,38 @@ def f():
14251425

14261426
deftest_get_local_events_uninitialized(self):
14271427
self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL,self.f.__code__),0)
1428+
1429+
classTestRegressions(MonitoringTestBase,unittest.TestCase):
1430+
1431+
deftest_105162(self):
1432+
caught=None
1433+
1434+
definner():
1435+
nonlocalcaught
1436+
try:
1437+
yield
1438+
exceptException:
1439+
caught="inner"
1440+
yield
1441+
1442+
defouter():
1443+
nonlocalcaught
1444+
try:
1445+
yieldfrominner()
1446+
exceptException:
1447+
caught="outer"
1448+
yield
1449+
1450+
defrun():
1451+
gen=outer()
1452+
gen.send(None)
1453+
gen.throw(Exception)
1454+
run()
1455+
self.assertEqual(caught,"inner")
1456+
caught=None
1457+
try:
1458+
sys.monitoring.set_events(TEST_TOOL,E.PY_RESUME)
1459+
run()
1460+
self.assertEqual(caught,"inner")
1461+
finally:
1462+
sys.monitoring.set_events(TEST_TOOL,0)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed bug in generator.close()/throw() where an inner iterator would be
2+
ignored when the outer iterator was instrumented.

‎Objects/genobject.c‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,18 @@ gen_close_iter(PyObject *yf)
331331
return0;
332332
}
333333

334+
staticinlinebool
335+
is_resume(_Py_CODEUNIT*instr)
336+
{
337+
returninstr->op.code==RESUME||instr->op.code==INSTRUMENTED_RESUME;
338+
}
339+
340+
staticinlinebool
341+
is_yield(_Py_CODEUNIT*instr)
342+
{
343+
returninstr->op.code==YIELD_VALUE||instr->op.code==INSTRUMENTED_YIELD_VALUE;
344+
}
345+
334346
PyObject*
335347
_PyGen_yf(PyGenObject*gen)
336348
{
@@ -347,7 +359,7 @@ _PyGen_yf(PyGenObject *gen)
347359
returnNULL;
348360
}
349361
_Py_CODEUNITnext=frame->prev_instr[1];
350-
if (next.op.code!=RESUME||next.op.arg<2)
362+
if (!is_resume(&next)||next.op.arg<2)
351363
{
352364
/* Not in a yield from */
353365
returnNULL;
@@ -382,8 +394,8 @@ gen_close(PyGenObject *gen, PyObject *args)
382394
_PyInterpreterFrame*frame= (_PyInterpreterFrame*)gen->gi_iframe;
383395
/* It is possible for the previous instruction to not be a
384396
* YIELD_VALUE if the debugger has changed the lineno. */
385-
if (err==0&&frame->prev_instr[0].op.code==YIELD_VALUE) {
386-
assert(frame->prev_instr[1].op.code==RESUME);
397+
if (err==0&&is_yield(frame->prev_instr)) {
398+
assert(is_resume(frame->prev_instr+1));
387399
intexception_handler_depth=frame->prev_instr[0].op.code;
388400
assert(exception_handler_depth>0);
389401
/* We can safely ignore the outermost try block

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp