summaryrefslogtreecommitdiff
path: root/Python/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 23fd088098..302070bbda 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1064,9 +1064,20 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
Py_MakePendingCalls() above. */
if (_Py_atomic_load_relaxed(&eval_breaker)) {
- if (_Py_OPCODE(*next_instr) == SETUP_FINALLY) {
- /* Make the last opcode before
- a try: finally: block uninterruptible. */
+ if (_Py_OPCODE(*next_instr) == SETUP_FINALLY ||
+ _Py_OPCODE(*next_instr) == YIELD_FROM) {
+ /* Two cases where we skip running signal handlers and other
+ pending calls:
+ - If we're about to enter the try: of a try/finally (not
+ *very* useful, but might help in some cases and it's
+ traditional)
+ - If we're resuming a chain of nested 'yield from' or
+ 'await' calls, then each frame is parked with YIELD_FROM
+ as its next opcode. If the user hit control-C we want to
+ wait until we've reached the innermost frame before
+ running the signal handler and raising KeyboardInterrupt
+ (see bpo-30039).
+ */
goto fast_next_opcode;
}
if (_Py_atomic_load_relaxed(&pendingcalls_to_do)) {