8000 Use NULL in the exception stack to indicate an exception was handled · python/cpython@c62f8ae · GitHub
[go: up one dir, main page]

Skip to content

Commit c62f8ae

Browse files
committed
Use NULL in the exception stack to indicate an exception was handled
Previously, both `NULL` and `Py_None` would be used interchangeably to indicate that an exception is no longer being handled. By ensuring that only `NULL` is used, this opens up the possibility to use `Py_None` to indicate a cleared exception. The difference here would be that clearing would indicate that no exception is currently being handled vs. handling would indicate that the next exception in the stack is currently being handled. This functionality will be used to patch up some edge cases in how the exception context interacts with exceptions thrown into coroutines. This is implemented in this commit by changing code that could add `Py_None` to the exception stack to indicate that an exception is no longer being handled to add `NULL` instead. An assert was also added to ensure that `Py_None` is no longer added to the exception stack. See gh-111676 for context.
1 parent 4afa7be commit c62f8ae

File tree

6 files changed

+8
-5
lines changed

6 files changed

+8
-5
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Only use ``NULL`` in the exception stack to indicate an exception was
2+
handled. Patch by Carey Metcalfe.

Objects/frameobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
811811
PyObject *exc = _PyFrame_StackPop(f->f_frame);
812812
assert(PyExceptionInstance_Check(exc) || exc == Py_None);
813813
PyThreadState *tstate = _PyThreadState_GET();
814-
Py_XSETREF(tstate->exc_info->exc_value, exc);
814+
Py_XSETREF(tstate->exc_info->exc_value, exc == Py_None ? NULL : exc);
815815
}
816816
else {
817817
PyObject *v = _PyFrame_StackPop(f->f_frame);

Python/bytecodes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,7 @@ dummy_func(
11001100

11011101
inst(POP_EXCEPT, (exc_value -- )) {
11021102
_PyErr_StackItem *exc_info = tstate->exc_info;
1103-
Py_XSETREF(exc_info->exc_value, exc_value);
1103+
Py_XSETREF(exc_info->exc_value, exc_value == Py_None ? NULL : exc_value);
11041104
}
11051105

11061106
inst(RERAISE, (values[oparg], exc -- values[oparg])) {

Python/errors.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ _PyErr_GetTopmostException(PyThreadState *tstate)
126126
{
127127
exc_info = exc_info->previous_item;
128128
}
129+
assert(!Py_IsNone(exc_info->exc_value));
129130
return exc_info;
130131
}
131132

@@ -592,7 +593,7 @@ PyErr_GetHandledException(void)
592593
void
593594
_PyErr_SetHandledException(PyThreadState *tstate, PyObject *exc)
594595
{
595-
Py_XSETREF(tstate->exc_info->exc_value, Py_XNewRef(exc));
596+
Py_XSETREF(tstate->exc_info->exc_value, Py_XNewRef(exc == Py_None ? NULL : exc));
596597
}
597598

598599
void

Python/executor_cases.c.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
0