bpo-36710: Add tstate parameter in ceval.c (GH-13547)
authorVictor Stinner <vstinner@redhat.com>
Fri, 24 May 2019 15:01:38 +0000 (17:01 +0200)
committerGitHub <noreply@github.com>
Fri, 24 May 2019 15:01:38 +0000 (17:01 +0200)
* Fix a possible reference leak in _PyErr_Print() if exception
  is NULL.
* PyErr_BadInternalCall(): replace PyErr_Format() with _PyErr_SetString().
* Add pycore_pyerrors.h header file.
* New functions:

  * _PyErr_Clear()
  * _PyErr_Fetch()
  * _PyErr_Print()
  * _PyErr_Restore()
  * _PyErr_SetObject()
  * _PyErr_SetString()

* Add 'tstate' parameter to _PyEval_AddPendingCall().

Include/internal/pycore_ceval.h
Include/internal/pycore_pyerrors.h [new file with mode: 0644]
Include/internal/pycore_pylifecycle.h
Include/internal/pycore_pymem.h
Makefile.pre.in
Modules/signalmodule.c
PCbuild/pythoncore.vcxproj
PCbuild/pythoncore.vcxproj.filters
Python/ceval.c
Python/errors.c
Python/pythonrun.c

index 7a3166e86dab7f115efeedc033040cd7f37e6402..37170ed438f8bb36f3456a40ca6988a317c91185 100644 (file)
@@ -19,6 +19,7 @@ PyAPI_FUNC(void) _PyEval_FiniThreads(
 PyAPI_FUNC(void) _PyEval_SignalReceived(
     struct _ceval_runtime_state *ceval);
 PyAPI_FUNC(int) _PyEval_AddPendingCall(
+    PyThreadState *tstate,
     struct _ceval_runtime_state *ceval,
     int (*func)(void *),
     void *arg);
diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h
new file mode 100644 (file)
index 0000000..23327ef
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef Py_INTERNAL_PYERRORS_H
+#define Py_INTERNAL_PYERRORS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
+{
+    return tstate == NULL ? NULL : tstate->curexc_type;
+}
+
+
+PyAPI_FUNC(void) _PyErr_Fetch(
+    PyThreadState *tstate,
+    PyObject **type,
+    PyObject **value,
+    PyObject **traceback);
+
+PyAPI_FUNC(int) _PyErr_ExceptionMatches(
+    PyThreadState *tstate,
+    PyObject *exc);
+
+PyAPI_FUNC(void) _PyErr_Restore(
+    PyThreadState *tstate,
+    PyObject *type,
+    PyObject *value,
+    PyObject *traceback);
+
+PyAPI_FUNC(void) _PyErr_SetObject(
+    PyThreadState *tstate,
+    PyObject *type,
+    PyObject *value);
+
+PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate);
+
+PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception);
+
+PyAPI_FUNC(void) _PyErr_SetString(
+    PyThreadState *tstate,
+    PyObject *exception,
+    const char *string);
+
+PyAPI_FUNC(PyObject *) _PyErr_Format(
+    PyThreadState *tstate,
+    PyObject *exception,
+    const char *format,
+    ...);
+
+PyAPI_FUNC(void) _PyErr_NormalizeException(
+    PyThreadState *tstate,
+    PyObject **exc,
+    PyObject **val,
+    PyObject **tb);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_PYERRORS_H */
index 07cf815363b779d079d1e6059a81aaf87d3b897a..13a31c262da8c40cfecdddbb96c73ec6a7b61740 100644 (file)
@@ -106,6 +106,8 @@ PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p);
 
 PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable);
 
+PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate);
+
 #ifdef __cplusplus
 }
 #endif
index dcc492af01702ce91a59f93c59dadeaceb340976..22677d373855ca9dfa18d0710cdeba4216a9c843 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef Py_INTERNAL_MEM_H
-#define Py_INTERNAL_MEM_H
+#ifndef Py_INTERNAL_PYMEM_H
+#define Py_INTERNAL_PYMEM_H
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -191,4 +191,4 @@ PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator);
 #ifdef __cplusplus
 }
 #endif
-#endif /* !Py_INTERNAL_MEM_H */
+#endif /* !Py_INTERNAL_PYMEM_H */
index 12891e938236a4bb308eca590e8398f8c23747bb..a149fdec4dcf40dcd8ea42a6fc6e1eac00346ed9 100644 (file)
@@ -1077,6 +1077,7 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/internal/pycore_hamt.h \
                $(srcdir)/Include/internal/pycore_object.h \
                $(srcdir)/Include/internal/pycore_pathconfig.h \
+               $(srcdir)/Include/internal/pycore_pyerrors.h \
                $(srcdir)/Include/internal/pycore_pyhash.h \
                $(srcdir)/Include/internal/pycore_pylifecycle.h \
                $(srcdir)/Include/internal/pycore_pymem.h \
index ed3852d444e80afd1f2ccce8b39669d73c7cf43b..7698984ff3afe16b5c58eefee67c51bd691c7d15 100644 (file)
@@ -258,6 +258,7 @@ trip_signal(int sig_num)
 
     /* Notify ceval.c */
     _PyRuntimeState *runtime = &_PyRuntime;
+    PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
     _PyEval_SignalReceived(&runtime->ceval);
 
     /* And then write to the wakeup fd *after* setting all the globals and
@@ -298,7 +299,7 @@ trip_signal(int sig_num)
                 {
                     /* Py_AddPendingCall() isn't signal-safe, but we
                        still use it for this exceptional case. */
-                    _PyEval_AddPendingCall(&runtime->ceval,
+                    _PyEval_AddPendingCall(tstate, &runtime->ceval,
                                            report_wakeup_send_error,
                                            (void *)(intptr_t) last_error);
                 }
@@ -317,7 +318,7 @@ trip_signal(int sig_num)
                 {
                     /* Py_AddPendingCall() isn't signal-safe, but we
                        still use it for this exceptional case. */
-                    _PyEval_AddPendingCall(&runtime->ceval,
+                    _PyEval_AddPendingCall(tstate, &runtime->ceval,
                                            report_wakeup_write_error,
                                            (void *)(intptr_t)errno);
                 }
index 681c4db65df0ac7f43445daef4a3ae0bdf7296f6..10f51dd431b7c1081baeeea190367c7d83128457 100644 (file)
     <ClInclude Include="..\Include\internal\pycore_hamt.h" />
     <ClInclude Include="..\Include\internal\pycore_object.h" />
     <ClInclude Include="..\Include\internal\pycore_pathconfig.h" />
+    <ClInclude Include="..\Include\internal\pycore_pyerrors.h" />
     <ClInclude Include="..\Include\internal\pycore_pyhash.h" />
     <ClInclude Include="..\Include\internal\pycore_pylifecycle.h" />
     <ClInclude Include="..\Include\internal\pycore_pymem.h" />
index 32964c008aa2579d5952a5c3682a75d96ed3c549..396d146513d799a6cd87000a607fe6ec0bc78cb8 100644 (file)
     <ClInclude Include="..\Include\internal\pycore_pathconfig.h">
       <Filter>Include</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_pyerrors.h">
+      <Filter>Include</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_pyhash.h">
       <Filter>Include</Filter>
     </ClInclude>
index 781b10dfac9aef794e8ba8cd12febb5479c64807..cb5a4beb2a663362321a06dad2b948a6a20655bd 100644 (file)
@@ -12,6 +12,8 @@
 #include "Python.h"
 #include "pycore_ceval.h"
 #include "pycore_object.h"
+#include "pycore_pyerrors.h"
+#include "pycore_pylifecycle.h"
 #include "pycore_pystate.h"
 #include "pycore_tupleobject.h"
 
@@ -50,7 +52,7 @@ static PyObject * do_call_core(
 
 #ifdef LLTRACE
 static int lltrace;
-static int prtrace(PyObject *, const char *);
+static int prtrace(PyThreadState *, PyObject *, const char *);
 #endif
 static int call_trace(Py_tracefunc, PyObject *,
                       PyThreadState *, PyFrameObject *,
@@ -67,19 +69,19 @@ static void maybe_dtrace_line(PyFrameObject *, int *, int *, int *);
 static void dtrace_function_entry(PyFrameObject *);
 static void dtrace_function_return(PyFrameObject *);
 
-static PyObject * cmp_outcome(int, PyObject *, PyObject *);
-static PyObject * import_name(PyFrameObject *, PyObject *, PyObject *,
-                              PyObject *);
-static PyObject * import_from(PyObject *, PyObject *);
-static int import_all_from(PyObject *, PyObject *);
-static void format_exc_check_arg(PyObject *, const char *, PyObject *);
-static void format_exc_unbound(PyCodeObject *co, int oparg);
-static PyObject * unicode_concatenate(PyObject *, PyObject *,
+static PyObject * cmp_outcome(PyThreadState *, int, PyObject *, PyObject *);
+static PyObject * import_name(PyThreadState *, PyFrameObject *,
+                              PyObject *, PyObject *, PyObject *);
+static PyObject * import_from(PyThreadState *, PyObject *, PyObject *);
+static int import_all_from(PyThreadState *, PyObject *, PyObject *);
+static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *);
+static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg);
+static PyObject * unicode_concatenate(PyThreadState *, PyObject *, PyObject *,
                                       PyFrameObject *, const _Py_CODEUNIT *);
-static PyObject * special_lookup(PyObject *, _Py_Identifier *);
-static int check_args_iterable(PyObject *func, PyObject *vararg);
-static void format_kwargs_error(PyObject *func, PyObject *kwargs);
-static void format_awaitable_error(PyTypeObject *, int);
+static PyObject * special_lookup(PyThreadState *, PyObject *, _Py_Identifier *);
+static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg);
+static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs);
+static void format_awaitable_error(PyThreadState *, PyTypeObject *, int);
 
 #define NAME_ERROR_MSG \
     "name '%.200s' is not defined"
@@ -420,7 +422,8 @@ _pop_pending_call(struct _pending_calls *pending,
  */
 
 int
-_PyEval_AddPendingCall(struct _ceval_runtime_state *ceval,
+_PyEval_AddPendingCall(PyThreadState *tstate,
+                       struct _ceval_runtime_state *ceval,
                        int (*func)(void *), void *arg)
 {
     struct _pending_calls *pending = &ceval->pending;
@@ -430,12 +433,12 @@ _PyEval_AddPendingCall(struct _ceval_runtime_state *ceval,
         PyThread_release_lock(pending->lock);
 
         PyObject *exc, *val, *tb;
-        PyErr_Fetch(&exc, &val, &tb);
-        PyErr_SetString(PyExc_SystemError,
+        _PyErr_Fetch(tstate, &exc, &val, &tb);
+        _PyErr_SetString(tstate, PyExc_SystemError,
                         "Py_AddPendingCall: cannot add pending calls "
                         "(Python shutting down)");
-        PyErr_Print();
-        PyErr_Restore(exc, val, tb);
+        _PyErr_Print(tstate);
+        _PyErr_Restore(tstate, exc, val, tb);
         return -1;
     }
     int result = _push_pending_call(pending, func, arg);
@@ -449,7 +452,9 @@ _PyEval_AddPendingCall(struct _ceval_runtime_state *ceval,
 int
 Py_AddPendingCall(int (*func)(void *), void *arg)
 {
-    return _PyEval_AddPendingCall(&_PyRuntime.ceval, func, arg);
+    _PyRuntimeState *runtime = &_PyRuntime;
+    PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
+    return _PyEval_AddPendingCall(tstate, &runtime->ceval, func, arg);
 }
 
 static int
@@ -535,6 +540,7 @@ _Py_FinishPendingCalls(_PyRuntimeState *runtime)
 {
     assert(PyGILState_Check());
 
+    PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
     struct _pending_calls *pending = &runtime->ceval.pending;
 
     PyThread_acquire_lock(pending->lock, WAIT_LOCK);
@@ -547,10 +553,10 @@ _Py_FinishPendingCalls(_PyRuntimeState *runtime)
 
     if (make_pending_calls(runtime) < 0) {
         PyObject *exc, *val, *tb;
-        PyErr_Fetch(&exc, &val, &tb);
+        _PyErr_Fetch(tstate, &exc, &val, &tb);
         PyErr_BadInternalCall();
         _PyErr_ChainExceptions(exc, val, tb);
-        PyErr_Print();
+        _PyErr_Print(tstate);
     }
 }
 
@@ -623,7 +629,7 @@ _Py_CheckRecursiveCall(const char *where)
     tstate->stackcheck_counter = 0;
     if (PyOS_CheckStack()) {
         --tstate->recursion_depth;
-        PyErr_SetString(PyExc_MemoryError, "Stack overflow");
+        _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow");
         return -1;
     }
     /* Needed for ABI backwards-compatibility (see bpo-31857) */
@@ -642,16 +648,16 @@ _Py_CheckRecursiveCall(const char *where)
     if (tstate->recursion_depth > recursion_limit) {
         --tstate->recursion_depth;
         tstate->overflowed = 1;
-        PyErr_Format(PyExc_RecursionError,
-                     "maximum recursion depth exceeded%s",
-                     where);
+        _PyErr_Format(tstate, PyExc_RecursionError,
+                      "maximum recursion depth exceeded%s",
+                      where);
         return -1;
     }
     return 0;
 }
 
 static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause);
-static int unpack_iterable(PyObject *, int, int, PyObject **);
+static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **);
 
 #define _Py_TracingPossible(ceval) ((ceval)->tracing_possible)
 
@@ -908,24 +914,24 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
 
 #ifdef LLTRACE
 #define PUSH(v)         { (void)(BASIC_PUSH(v), \
-                          lltrace && prtrace(TOP(), "push")); \
+                          lltrace && prtrace(tstate, TOP(), "push")); \
                           assert(STACK_LEVEL() <= co->co_stacksize); }
-#define POP()           ((void)(lltrace && prtrace(TOP(), "pop")), \
+#define POP()           ((void)(lltrace && prtrace(tstate, TOP(), "pop")), \
                          BASIC_POP())
 #define STACK_GROW(n)   do { \
                           assert(n >= 0); \
                           (void)(BASIC_STACKADJ(n), \
-                          lltrace && prtrace(TOP(), "stackadj")); \
+                          lltrace && prtrace(tstate, TOP(), "stackadj")); \
                           assert(STACK_LEVEL() <= co->co_stacksize); \
                         } while (0)
 #define STACK_SHRINK(n) do { \
                             assert(n >= 0); \
-                            (void)(lltrace && prtrace(TOP(), "stackadj")); \
+                            (void)(lltrace && prtrace(tstate, TOP(), "stackadj")); \
                             (void)(BASIC_STACKADJ(-n)); \
                             assert(STACK_LEVEL() <= co->co_stacksize); \
                         } while (0)
 #define EXT_POP(STACK_POINTER) ((void)(lltrace && \
-                                prtrace((STACK_POINTER)[-1], "ext_pop")), \
+                                prtrace(tstate, (STACK_POINTER)[-1], "ext_pop")), \
                                 *--(STACK_POINTER))
 #else
 #define PUSH(v)                BASIC_PUSH(v)
@@ -1070,14 +1076,14 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
     /* PyEval_EvalFrameEx() must not be called with an exception set,
        because it can clear it (directly or indirectly) and so the
        caller loses its exception */
-    assert(!PyErr_Occurred());
+    assert(!_PyErr_Occurred(tstate));
 #endif
 
 main_loop:
     for (;;) {
         assert(stack_pointer >= f->f_valuestack); /* else underflow */
         assert(STACK_LEVEL() <= co->co_stacksize);  /* else overflow */
-        assert(!PyErr_Occurred());
+        assert(!_PyErr_Occurred(tstate));
 
         /* Do periodic things.  Doing this every time through
            the loop would add too much overhead, so we do it
@@ -1146,7 +1152,7 @@ main_loop:
                 PyObject *exc = tstate->async_exc;
                 tstate->async_exc = NULL;
                 UNSIGNAL_ASYNC_EXC(ceval);
-                PyErr_SetNone(exc);
+                _PyErr_SetNone(tstate, exc);
                 Py_DECREF(exc);
                 goto error;
             }
@@ -1222,7 +1228,7 @@ main_loop:
         case TARGET(LOAD_FAST): {
             PyObject *value = GETLOCAL(oparg);
             if (value == NULL) {
-                format_exc_check_arg(PyExc_UnboundLocalError,
+                format_exc_check_arg(tstate, PyExc_UnboundLocalError,
                                      UNBOUNDLOCAL_ERROR_MSG,
                                      PyTuple_GetItem(co->co_varnames, oparg));
                 goto error;
@@ -1441,7 +1447,7 @@ main_loop:
                speedup on microbenchmarks. */
             if (PyUnicode_CheckExact(left) &&
                      PyUnicode_CheckExact(right)) {
-                sum = unicode_concatenate(left, right, f, next_instr);
+                sum = unicode_concatenate(tstate, left, right, f, next_instr);
                 /* unicode_concatenate consumed the ref to left */
             }
             else {
@@ -1640,7 +1646,7 @@ main_loop:
             PyObject *left = TOP();
             PyObject *sum;
             if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) {
-                sum = unicode_concatenate(left, right, f, next_instr);
+                sum = unicode_concatenate(tstate, left, right, f, next_instr);
                 /* unicode_concatenate consumed the ref to left */
             }
             else {
@@ -1762,8 +1768,8 @@ main_loop:
             PyObject *hook = _PySys_GetObjectId(&PyId_displayhook);
             PyObject *res;
             if (hook == NULL) {
-                PyErr_SetString(PyExc_RuntimeError,
-                                "lost sys.displayhook");
+                _PyErr_SetString(tstate, PyExc_RuntimeError,
+                                 "lost sys.displayhook");
                 Py_DECREF(value);
                 goto error;
             }
@@ -1790,8 +1796,8 @@ main_loop:
                 }
                 break;
             default:
-                PyErr_SetString(PyExc_SystemError,
-                           "bad RAISE_VARARGS oparg");
+                _PyErr_SetString(tstate, PyExc_SystemError,
+                                 "bad RAISE_VARARGS oparg");
                 break;
             }
             goto error;
@@ -1823,11 +1829,10 @@ main_loop:
             }
             else {
                 SET_TOP(NULL);
-                PyErr_Format(
-                    PyExc_TypeError,
-                    "'async for' requires an object with "
-                    "__aiter__ method, got %.100s",
-                    type->tp_name);
+                _PyErr_Format(tstate, PyExc_TypeError,
+                              "'async for' requires an object with "
+                              "__aiter__ method, got %.100s",
+                              type->tp_name);
                 Py_DECREF(obj);
                 goto error;
             }
@@ -1836,11 +1841,10 @@ main_loop:
                     Py_TYPE(iter)->tp_as_async->am_anext == NULL) {
 
                 SET_TOP(NULL);
-                PyErr_Format(
-                    PyExc_TypeError,
-                    "'async for' received an object from __aiter__ "
-                    "that does not implement __anext__: %.100s",
-                    Py_TYPE(iter)->tp_name);
+                _PyErr_Format(tstate, PyExc_TypeError,
+                              "'async for' received an object from __aiter__ "
+                              "that does not implement __anext__: %.100s",
+                              Py_TYPE(iter)->tp_name);
                 Py_DECREF(iter);
                 goto error;
             }
@@ -1873,11 +1877,10 @@ main_loop:
                     }
                 }
                 else {
-                    PyErr_Format(
-                        PyExc_TypeError,
-                        "'async for' requires an iterator with "
-                        "__anext__ method, got %.100s",
-                        type->tp_name);
+                    _PyErr_Format(tstate, PyExc_TypeError,
+                                  "'async for' requires an iterator with "
+                                  "__anext__ method, got %.100s",
+                                  type->tp_name);
                     goto error;
                 }
 
@@ -1907,7 +1910,7 @@ main_loop:
             PyObject *iter = _PyCoro_GetAwaitableIter(iterable);
 
             if (iter == NULL) {
-                format_awaitable_error(Py_TYPE(iterable),
+                format_awaitable_error(tstate, Py_TYPE(iterable),
                                        _Py_OPCODE(next_instr[-2]));
             }
 
@@ -1921,9 +1924,8 @@ main_loop:
                        being awaited on. */
                     Py_DECREF(yf);
                     Py_CLEAR(iter);
-                    PyErr_SetString(
-                        PyExc_RuntimeError,
-                        "coroutine is being awaited already");
+                    _PyErr_SetString(tstate, PyExc_RuntimeError,
+                                     "coroutine is being awaited already");
                     /* The code below jumps to `error` if `iter` is NULL. */
                 }
             }
@@ -1955,7 +1957,7 @@ main_loop:
             if (retval == NULL) {
                 PyObject *val;
                 if (tstate->c_tracefunc != NULL
-                        && PyErr_ExceptionMatches(PyExc_StopIteration))
+                        && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration))
                     call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f);
                 err = _PyGen_FetchStopIterationValue(&val);
                 if (err < 0)
@@ -1994,8 +1996,8 @@ main_loop:
             _PyErr_StackItem *exc_info;
             PyTryBlock *b = PyFrame_BlockPop(f);
             if (b->b_type != EXCEPT_HANDLER) {
-                PyErr_SetString(PyExc_SystemError,
-                                "popped block is not an except handler");
+                _PyErr_SetString(tstate, PyExc_SystemError,
+                                 "popped block is not an except handler");
                 goto error;
             }
             assert(STACK_LEVEL() >= (b)->b_level + 3 &&
@@ -2047,8 +2049,8 @@ main_loop:
                 _PyErr_StackItem *exc_info;
                 PyTryBlock *b = PyFrame_BlockPop(f);
                 if (b->b_type != EXCEPT_HANDLER) {
-                    PyErr_SetString(PyExc_SystemError,
-                                    "popped block is not an except handler");
+                    _PyErr_SetString(tstate, PyExc_SystemError,
+                                     "popped block is not an except handler");
                     Py_XDECREF(res);
                     goto error;
                 }
@@ -2104,7 +2106,7 @@ main_loop:
             else if (PyLong_CheckExact(exc)) {
                 int ret = _PyLong_AsInt(exc);
                 Py_DECREF(exc);
-                if (ret == -1 && PyErr_Occurred()) {
+                if (ret == -1 && _PyErr_Occurred(tstate)) {
                     goto error;
                 }
                 JUMPTO(ret);
@@ -2114,7 +2116,7 @@ main_loop:
                 assert(PyExceptionClass_Check(exc));
                 PyObject *val = POP();
                 PyObject *tb = POP();
-                PyErr_Restore(exc, val, tb);
+                _PyErr_Restore(tstate, exc, val, tb);
                 goto exception_unwind;
             }
         }
@@ -2134,7 +2136,7 @@ main_loop:
             else {
                 PyObject *val = POP();
                 PyObject *tb = POP();
-                PyErr_Restore(exc, val, tb);
+                _PyErr_Restore(tstate, exc, val, tb);
                 goto exception_unwind;
             }
         }
@@ -2146,9 +2148,9 @@ main_loop:
             if (PyDict_CheckExact(f->f_builtins)) {
                 bc = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___build_class__);
                 if (bc == NULL) {
-                    if (!PyErr_Occurred()) {
-                        PyErr_SetString(PyExc_NameError,
-                                        "__build_class__ not found");
+                    if (!_PyErr_Occurred(tstate)) {
+                        _PyErr_SetString(tstate, PyExc_NameError,
+                                         "__build_class__ not found");
                     }
                     goto error;
                 }
@@ -2160,9 +2162,9 @@ main_loop:
                     goto error;
                 bc = PyObject_GetItem(f->f_builtins, build_class_str);
                 if (bc == NULL) {
-                    if (PyErr_ExceptionMatches(PyExc_KeyError))
-                        PyErr_SetString(PyExc_NameError,
-                                        "__build_class__ not found");
+                    if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError))
+                        _PyErr_SetString(tstate, PyExc_NameError,
+                                         "__build_class__ not found");
                     goto error;
                 }
             }
@@ -2176,8 +2178,8 @@ main_loop:
             PyObject *ns = f->f_locals;
             int err;
             if (ns == NULL) {
-                PyErr_Format(PyExc_SystemError,
-                             "no locals found when storing %R", name);
+                _PyErr_Format(tstate, PyExc_SystemError,
+                              "no locals found when storing %R", name);
                 Py_DECREF(v);
                 goto error;
             }
@@ -2196,13 +2198,13 @@ main_loop:
             PyObject *ns = f->f_locals;
             int err;
             if (ns == NULL) {
-                PyErr_Format(PyExc_SystemError,
-                             "no locals when deleting %R", name);
+                _PyErr_Format(tstate, PyExc_SystemError,
+                              "no locals when deleting %R", name);
                 goto error;
             }
             err = PyObject_DelItem(ns, name);
             if (err != 0) {
-                format_exc_check_arg(PyExc_NameError,
+                format_exc_check_arg(tstate, PyExc_NameError,
                                      NAME_ERROR_MSG,
                                      name);
                 goto error;
@@ -2229,7 +2231,7 @@ main_loop:
                     Py_INCREF(item);
                     PUSH(item);
                 }
-            } else if (unpack_iterable(seq, oparg, -1,
+            } else if (unpack_iterable(tstate, seq, oparg, -1,
                                        stack_pointer + oparg)) {
                 STACK_GROW(oparg);
             } else {
@@ -2245,7 +2247,7 @@ main_loop:
             int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8);
             PyObject *seq = POP();
 
-            if (unpack_iterable(seq, oparg & 0xFF, oparg >> 8,
+            if (unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8,
                                 stack_pointer + totalargs)) {
                 stack_pointer += totalargs;
             } else {
@@ -2297,9 +2299,9 @@ main_loop:
             int err;
             err = PyDict_DelItem(f->f_globals, name);
             if (err != 0) {
-                if (PyErr_ExceptionMatches(PyExc_KeyError)) {
-                    format_exc_check_arg(
-                        PyExc_NameError, NAME_ERROR_MSG, name);
+                if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+                    format_exc_check_arg(tstate, PyExc_NameError,
+                                         NAME_ERROR_MSG, name);
                 }
                 goto error;
             }
@@ -2311,8 +2313,8 @@ main_loop:
             PyObject *locals = f->f_locals;
             PyObject *v;
             if (locals == NULL) {
-                PyErr_Format(PyExc_SystemError,
-                             "no locals when loading %R", name);
+                _PyErr_Format(tstate, PyExc_SystemError,
+                              "no locals when loading %R", name);
                 goto error;
             }
             if (PyDict_CheckExact(locals)) {
@@ -2320,16 +2322,16 @@ main_loop:
                 if (v != NULL) {
                     Py_INCREF(v);
                 }
-                else if (PyErr_Occurred()) {
+                else if (_PyErr_Occurred(tstate)) {
                     goto error;
                 }
             }
             else {
                 v = PyObject_GetItem(locals, name);
                 if (v == NULL) {
-                    if (!PyErr_ExceptionMatches(PyExc_KeyError))
+                    if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError))
                         goto error;
-                    PyErr_Clear();
+                    _PyErr_Clear(tstate);
                 }
             }
             if (v == NULL) {
@@ -2337,16 +2339,16 @@ main_loop:
                 if (v != NULL) {
                     Py_INCREF(v);
                 }
-                else if (PyErr_Occurred()) {
+                else if (_PyErr_Occurred(tstate)) {
                     goto error;
                 }
                 else {
                     if (PyDict_CheckExact(f->f_builtins)) {
                         v = PyDict_GetItemWithError(f->f_builtins, name);
                         if (v == NULL) {
-                            if (!PyErr_Occurred()) {
+                            if (!_PyErr_Occurred(tstate)) {
                                 format_exc_check_arg(
-                                        PyExc_NameError,
+                                        tstate, PyExc_NameError,
                                         NAME_ERROR_MSG, name);
                             }
                             goto error;
@@ -2356,10 +2358,11 @@ main_loop:
                     else {
                         v = PyObject_GetItem(f->f_builtins, name);
                         if (v == NULL) {
-                            if (PyErr_ExceptionMatches(PyExc_KeyError))
+                            if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
                                 format_exc_check_arg(
-                                            PyExc_NameError,
+                                            tstate, PyExc_NameError,
                                             NAME_ERROR_MSG, name);
+                            }
                             goto error;
                         }
                     }
@@ -2382,7 +2385,7 @@ main_loop:
                     if (!_PyErr_OCCURRED()) {
                         /* _PyDict_LoadGlobal() returns NULL without raising
                          * an exception if the key doesn't exist */
-                        format_exc_check_arg(PyExc_NameError,
+                        format_exc_check_arg(tstate, PyExc_NameError,
                                              NAME_ERROR_MSG, name);
                     }
                     goto error;
@@ -2395,17 +2398,19 @@ main_loop:
                 /* namespace 1: globals */
                 v = PyObject_GetItem(f->f_globals, name);
                 if (v == NULL) {
-                    if (!PyErr_ExceptionMatches(PyExc_KeyError))
+                    if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
                         goto error;
-                    PyErr_Clear();
+                    }
+                    _PyErr_Clear(tstate);
 
                     /* namespace 2: builtins */
                     v = PyObject_GetItem(f->f_builtins, name);
                     if (v == NULL) {
-                        if (PyErr_ExceptionMatches(PyExc_KeyError))
+                        if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
                             format_exc_check_arg(
-                                        PyExc_NameError,
+                                        tstate, PyExc_NameError,
                                         NAME_ERROR_MSG, name);
+                        }
                         goto error;
                     }
                 }
@@ -2421,7 +2426,7 @@ main_loop:
                 DISPATCH();
             }
             format_exc_check_arg(
-                PyExc_UnboundLocalError,
+                tstate, PyExc_UnboundLocalError,
                 UNBOUNDLOCAL_ERROR_MSG,
                 PyTuple_GetItem(co->co_varnames, oparg)
                 );
@@ -2436,7 +2441,7 @@ main_loop:
                 Py_DECREF(oldobj);
                 DISPATCH();
             }
-            format_exc_unbound(co, oparg);
+            format_exc_unbound(tstate, co, oparg);
             goto error;
         }
 
@@ -2460,23 +2465,24 @@ main_loop:
                 if (value != NULL) {
                     Py_INCREF(value);
                 }
-                else if (PyErr_Occurred()) {
+                else if (_PyErr_Occurred(tstate)) {
                     goto error;
                 }
             }
             else {
                 value = PyObject_GetItem(locals, name);
                 if (value == NULL) {
-                    if (!PyErr_ExceptionMatches(PyExc_KeyError))
+                    if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
                         goto error;
-                    PyErr_Clear();
+                    }
+                    _PyErr_Clear(tstate);
                 }
             }
             if (!value) {
                 PyObject *cell = freevars[oparg];
                 value = PyCell_GET(cell);
                 if (value == NULL) {
-                    format_exc_unbound(co, oparg);
+                    format_exc_unbound(tstate, co, oparg);
                     goto error;
                 }
                 Py_INCREF(value);
@@ -2489,7 +2495,7 @@ main_loop:
             PyObject *cell = freevars[oparg];
             PyObject *value = PyCell_GET(cell);
             if (value == NULL) {
-                format_exc_unbound(co, oparg);
+                format_exc_unbound(tstate, co, oparg);
                 goto error;
             }
             Py_INCREF(value);
@@ -2565,9 +2571,9 @@ main_loop:
                 none_val = _PyList_Extend((PyListObject *)sum, PEEK(i));
                 if (none_val == NULL) {
                     if (opcode == BUILD_TUPLE_UNPACK_WITH_CALL &&
-                        PyErr_ExceptionMatches(PyExc_TypeError))
+                        _PyErr_ExceptionMatches(tstate, PyExc_TypeError))
                     {
-                        check_args_iterable(PEEK(1 + oparg), PEEK(i));
+                        check_args_iterable(tstate, PEEK(1 + oparg), PEEK(i));
                     }
                     Py_DECREF(sum);
                     goto error;
@@ -2660,8 +2666,8 @@ main_loop:
             int err;
             PyObject *ann_dict;
             if (f->f_locals == NULL) {
-                PyErr_Format(PyExc_SystemError,
-                             "no locals found when setting up annotations");
+                _PyErr_Format(tstate, PyExc_SystemError,
+                              "no locals found when setting up annotations");
                 goto error;
             }
             /* check if __annotations__ in locals()... */
@@ -2669,7 +2675,7 @@ main_loop:
                 ann_dict = _PyDict_GetItemIdWithError(f->f_locals,
                                              &PyId___annotations__);
                 if (ann_dict == NULL) {
-                    if (PyErr_Occurred()) {
+                    if (_PyErr_Occurred(tstate)) {
                         goto error;
                     }
                     /* ...if not, create a new one */
@@ -2693,10 +2699,10 @@ main_loop:
                 }
                 ann_dict = PyObject_GetItem(f->f_locals, ann_str);
                 if (ann_dict == NULL) {
-                    if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
+                    if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
                         goto error;
                     }
-                    PyErr_Clear();
+                    _PyErr_Clear(tstate);
                     ann_dict = PyDict_New();
                     if (ann_dict == NULL) {
                         goto error;
@@ -2720,8 +2726,8 @@ main_loop:
             PyObject *keys = TOP();
             if (!PyTuple_CheckExact(keys) ||
                 PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) {
-                PyErr_SetString(PyExc_SystemError,
-                                "bad BUILD_CONST_KEY_MAP keys argument");
+                _PyErr_SetString(tstate, PyExc_SystemError,
+                                 "bad BUILD_CONST_KEY_MAP keys argument");
                 goto error;
             }
             map = _PyDict_NewPresized((Py_ssize_t)oparg);
@@ -2756,10 +2762,10 @@ main_loop:
             for (i = oparg; i > 0; i--) {
                 PyObject *arg = PEEK(i);
                 if (PyDict_Update(sum, arg) < 0) {
-                    if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
-                        PyErr_Format(PyExc_TypeError,
-                                "'%.200s' object is not a mapping",
-                                arg->ob_type->tp_name);
+                    if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
+                        _PyErr_Format(tstate, PyExc_TypeError,
+                                      "'%.200s' object is not a mapping",
+                                      arg->ob_type->tp_name);
                     }
                     Py_DECREF(sum);
                     goto error;
@@ -2782,7 +2788,7 @@ main_loop:
                 PyObject *arg = PEEK(i);
                 if (_PyDict_MergeEx(sum, arg, 2) < 0) {
                     Py_DECREF(sum);
-                    format_kwargs_error(PEEK(2 + oparg), arg);
+                    format_kwargs_error(tstate, PEEK(2 + oparg), arg);
                     goto error;
                 }
             }
@@ -2824,7 +2830,7 @@ main_loop:
         case TARGET(COMPARE_OP): {
             PyObject *right = POP();
             PyObject *left = TOP();
-            PyObject *res = cmp_outcome(oparg, left, right);
+            PyObject *res = cmp_outcome(tstate, oparg, left, right);
             Py_DECREF(left);
             Py_DECREF(right);
             SET_TOP(res);
@@ -2840,7 +2846,7 @@ main_loop:
             PyObject *fromlist = POP();
             PyObject *level = TOP();
             PyObject *res;
-            res = import_name(f, name, fromlist, level);
+            res = import_name(tstate, f, name, fromlist, level);
             Py_DECREF(level);
             Py_DECREF(fromlist);
             SET_TOP(res);
@@ -2859,12 +2865,12 @@ main_loop:
 
             locals = f->f_locals;
             if (locals == NULL) {
-                PyErr_SetString(PyExc_SystemError,
-                    "no locals found during 'import *'");
+                _PyErr_SetString(tstate, PyExc_SystemError,
+                                 "no locals found during 'import *'");
                 Py_DECREF(from);
                 goto error;
             }
-            err = import_all_from(locals, from);
+            err = import_all_from(tstate, locals, from);
             PyFrame_LocalsToFast(f, 0);
             Py_DECREF(from);
             if (err != 0)
@@ -2876,7 +2882,7 @@ main_loop:
             PyObject *name = GETITEM(names, oparg);
             PyObject *from = TOP();
             PyObject *res;
-            res = import_from(from, name);
+            res = import_from(tstate, from, name);
             PUSH(res);
             if (res == NULL)
                 goto error;
@@ -3027,9 +3033,9 @@ main_loop:
                        regular generator. */
                     Py_DECREF(iterable);
                     SET_TOP(NULL);
-                    PyErr_SetString(PyExc_TypeError,
-                                    "cannot 'yield from' a coroutine object "
-                                    "in a non-coroutine generator");
+                    _PyErr_SetString(tstate, PyExc_TypeError,
+                                     "cannot 'yield from' a coroutine object "
+                                     "in a non-coroutine generator");
                     goto error;
                 }
             }
@@ -3056,12 +3062,14 @@ main_loop:
                 PREDICT(UNPACK_SEQUENCE);
                 DISPATCH();
             }
-            if (PyErr_Occurred()) {
-                if (!PyErr_ExceptionMatches(PyExc_StopIteration))
+            if (_PyErr_Occurred(tstate)) {
+                if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) {
                     goto error;
-                else if (tstate->c_tracefunc != NULL)
+                }
+                else if (tstate->c_tracefunc != NULL) {
                     call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f);
-                PyErr_Clear();
+                }
+                _PyErr_Clear(tstate);
             }
             /* iterator ended normally */
             STACK_SHRINK(1);
@@ -3087,13 +3095,13 @@ main_loop:
             _Py_IDENTIFIER(__aenter__);
 
             PyObject *mgr = TOP();
-            PyObject *exit = special_lookup(mgr, &PyId___aexit__),
+            PyObject *exit = special_lookup(tstate, mgr, &PyId___aexit__),
                      *enter;
             PyObject *res;
             if (exit == NULL)
                 goto error;
             SET_TOP(exit);
-            enter = special_lookup(mgr, &PyId___aenter__);
+            enter = special_lookup(tstate, mgr, &PyId___aenter__);
             Py_DECREF(mgr);
             if (enter == NULL)
                 goto error;
@@ -3120,11 +3128,12 @@ main_loop:
             _Py_IDENTIFIER(__exit__);
             _Py_IDENTIFIER(__enter__);
             PyObject *mgr = TOP();
-            PyObject *enter = special_lookup(mgr, &PyId___enter__), *exit;
+            PyObject *enter = special_lookup(tstate, mgr, &PyId___enter__);
             PyObject *res;
-            if (enter == NULL)
+            if (enter == NULL) {
                 goto error;
-            exit = special_lookup(mgr, &PyId___exit__);
+            }
+            PyObject *exit = special_lookup(tstate, mgr, &PyId___exit__);
             if (exit == NULL) {
                 Py_DECREF(enter);
                 goto error;
@@ -3380,7 +3389,7 @@ main_loop:
                         goto error;
                     if (_PyDict_MergeEx(d, kwargs, 2) < 0) {
                         Py_DECREF(d);
-                        format_kwargs_error(SECOND(), kwargs);
+                        format_kwargs_error(tstate, SECOND(), kwargs);
                         Py_DECREF(kwargs);
                         goto error;
                     }
@@ -3392,7 +3401,7 @@ main_loop:
             callargs = POP();
             func = TOP();
             if (!PyTuple_CheckExact(callargs)) {
-                if (check_args_iterable(func, callargs) < 0) {
+                if (check_args_iterable(tstate, func, callargs) < 0) {
                     Py_DECREF(callargs);
                     goto error;
                 }
@@ -3485,9 +3494,9 @@ main_loop:
             case FVC_REPR:  conv_fn = PyObject_Repr;  break;
             case FVC_ASCII: conv_fn = PyObject_ASCII; break;
             default:
-                PyErr_Format(PyExc_SystemError,
-                             "unexpected conversion flag %d",
-                             which_conversion);
+                _PyErr_Format(tstate, PyExc_SystemError,
+                              "unexpected conversion flag %d",
+                              which_conversion);
                 goto error;
             }
 
@@ -3542,7 +3551,7 @@ main_loop:
                 "XXX lineno: %d, opcode: %d\n",
                 PyFrame_GetLineNumber(f),
                 opcode);
-            PyErr_SetString(PyExc_SystemError, "unknown opcode");
+            _PyErr_SetString(tstate, PyExc_SystemError, "unknown opcode");
             goto error;
 
         } /* switch */
@@ -3554,11 +3563,12 @@ main_loop:
 error:
         /* Double-check exception status. */
 #ifdef NDEBUG
-        if (!PyErr_Occurred())
-            PyErr_SetString(PyExc_SystemError,
-                            "error return without exception set");
+        if (!_PyErr_Occurred(tstate)) {
+            _PyErr_SetString(tstate, PyExc_SystemError,
+                             "error return without exception set");
+        }
 #else
-        assert(PyErr_Occurred());
+        assert(_PyErr_Occurred(tstate));
 #endif
 
         /* Log traceback info. */
@@ -3594,13 +3604,12 @@ exception_unwind:
                     Py_INCREF(Py_None);
                     PUSH(Py_None);
                 }
-                PyErr_Fetch(&exc, &val, &tb);
+                _PyErr_Fetch(tstate, &exc, &val, &tb);
                 /* Make the raw exception data
                    available to the handler,
                    so a program can emulate the
                    Python main loop. */
-                PyErr_NormalizeException(
-                    &exc, &val, &tb);
+                _PyErr_NormalizeException(tstate, &exc, &val, &tb);
                 if (tb != NULL)
                     PyException_SetTraceback(val, tb);
                 else
@@ -3627,7 +3636,7 @@ exception_unwind:
     } /* main loop */
 
     assert(retval == NULL);
-    assert(PyErr_Occurred());
+    assert(_PyErr_Occurred(tstate));
 
 exit_returning:
 
@@ -3665,7 +3674,8 @@ exit_eval_frame:
 }
 
 static void
-format_missing(const char *kind, PyCodeObject *co, PyObject *names)
+format_missing(PyThreadState *tstate, const char *kind,
+               PyCodeObject *co, PyObject *names)
 {
     int err;
     Py_ssize_t len = PyList_GET_SIZE(names);
@@ -3716,18 +3726,19 @@ format_missing(const char *kind, PyCodeObject *co, PyObject *names)
     }
     if (name_str == NULL)
         return;
-    PyErr_Format(PyExc_TypeError,
-                 "%U() missing %i required %s argument%s: %U",
-                 co->co_name,
-                 len,
-                 kind,
-                 len == 1 ? "" : "s",
-                 name_str);
+    _PyErr_Format(tstate, PyExc_TypeError,
+                  "%U() missing %i required %s argument%s: %U",
+                  co->co_name,
+                  len,
+                  kind,
+                  len == 1 ? "" : "s",
+                  name_str);
     Py_DECREF(name_str);
 }
 
 static void
-missing_arguments(PyCodeObject *co, Py_ssize_t missing, Py_ssize_t defcount,
+missing_arguments(PyThreadState *tstate, PyCodeObject *co,
+                  Py_ssize_t missing, Py_ssize_t defcount,
                   PyObject **fastlocals)
 {
     Py_ssize_t i, j = 0;
@@ -3760,12 +3771,13 @@ missing_arguments(PyCodeObject *co, Py_ssize_t missing, Py_ssize_t defcount,
         }
     }
     assert(j == missing);
-    format_missing(kind, co, missing_names);
+    format_missing(tstate, kind, co, missing_names);
     Py_DECREF(missing_names);
 }
 
 static void
-too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount,
+too_many_positional(PyThreadState *tstate, PyCodeObject *co,
+                    Py_ssize_t given, Py_ssize_t defcount,
                     PyObject **fastlocals)
 {
     int plural;
@@ -3810,21 +3822,21 @@ too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount,
         kwonly_sig = PyUnicode_FromString("");
         assert(kwonly_sig != NULL);
     }
-    PyErr_Format(PyExc_TypeError,
-                 "%U() takes %U positional argument%s but %zd%U %s given",
-                 co->co_name,
-                 sig,
-                 plural ? "s" : "",
-                 given,
-                 kwonly_sig,
-                 given == 1 && !kwonly_given ? "was" : "were");
+    _PyErr_Format(tstate, PyExc_TypeError,
+                  "%U() takes %U positional argument%s but %zd%U %s given",
+                  co->co_name,
+                  sig,
+                  plural ? "s" : "",
+                  given,
+                  kwonly_sig,
+                  given == 1 && !kwonly_given ? "was" : "were");
     Py_DECREF(sig);
     Py_DECREF(kwonly_sig);
 }
 
 static int
-positional_only_passed_as_keyword(PyCodeObject *co, Py_ssize_t kwcount,
-                                  PyObject* const* kwnames)
+positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co,
+                                  Py_ssize_t kwcount, PyObject* const* kwnames)
 {
     int posonly_conflicts = 0;
     PyObject* posonly_names = PyList_New(0);
@@ -3866,10 +3878,10 @@ positional_only_passed_as_keyword(PyCodeObject *co, Py_ssize_t kwcount,
         if (error_names == NULL) {
             goto fail;
         }
-        PyErr_Format(PyExc_TypeError,
-            "%U() got some positional-only arguments passed"
-            " as keyword arguments: '%U'",
-            co->co_name, error_names);
+        _PyErr_Format(tstate, PyExc_TypeError,
+                      "%U() got some positional-only arguments passed"
+                      " as keyword arguments: '%U'",
+                      co->co_name, error_names);
         Py_DECREF(error_names);
         goto fail;
     }
@@ -3905,15 +3917,16 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
     Py_ssize_t i, j, n;
     PyObject *kwdict;
 
+    PyThreadState *tstate = _PyThreadState_GET();
+    assert(tstate != NULL);
+
     if (globals == NULL) {
-        PyErr_SetString(PyExc_SystemError,
-                        "PyEval_EvalCodeEx: NULL globals");
+        _PyErr_SetString(tstate, PyExc_SystemError,
+                         "PyEval_EvalCodeEx: NULL globals");
         return NULL;
     }
 
     /* Create the frame */
-    PyThreadState *tstate = _PyThreadState_GET();
-    assert(tstate != NULL);
     f = _PyFrame_New_NoTrack(tstate, co, globals, locals);
     if (f == NULL) {
         return NULL;
@@ -3981,9 +3994,9 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
         Py_ssize_t j;
 
         if (keyword == NULL || !PyUnicode_Check(keyword)) {
-            PyErr_Format(PyExc_TypeError,
-                         "%U() keywords must be strings",
-                         co->co_name);
+            _PyErr_Format(tstate, PyExc_TypeError,
+                          "%U() keywords must be strings",
+                          co->co_name);
             goto fail;
         }
 
@@ -4012,13 +4025,16 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
         assert(j >= total_args);
         if (kwdict == NULL) {
 
-            if (co->co_posonlyargcount && positional_only_passed_as_keyword(co, kwcount, kwnames)) {
+            if (co->co_posonlyargcount
+                && positional_only_passed_as_keyword(tstate, co,
+                                                     kwcount, kwnames))
+            {
                 goto fail;
             }
 
-            PyErr_Format(PyExc_TypeError,
-                         "%U() got an unexpected keyword argument '%S'",
-                         co->co_name, keyword);
+            _PyErr_Format(tstate, PyExc_TypeError,
+                          "%U() got an unexpected keyword argument '%S'",
+                          co->co_name, keyword);
             goto fail;
         }
 
@@ -4029,9 +4045,9 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
 
       kw_found:
         if (GETLOCAL(j) != NULL) {
-            PyErr_Format(PyExc_TypeError,
-                         "%U() got multiple values for argument '%S'",
-                         co->co_name, keyword);
+            _PyErr_Format(tstate, PyExc_TypeError,
+                          "%U() got multiple values for argument '%S'",
+                          co->co_name, keyword);
             goto fail;
         }
         Py_INCREF(value);
@@ -4040,7 +4056,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
 
     /* Check the number of positional arguments */
     if ((argcount > co->co_argcount + co->co_posonlyargcount) && !(co->co_flags & CO_VARARGS)) {
-        too_many_positional(co, argcount, defcount, fastlocals);
+        too_many_positional(tstate, co, argcount, defcount, fastlocals);
         goto fail;
     }
 
@@ -4054,7 +4070,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
             }
         }
         if (missing) {
-            missing_arguments(co, missing, defcount, fastlocals);
+            missing_arguments(tstate, co, missing, defcount, fastlocals);
             goto fail;
         }
         if (n > m)
@@ -4085,14 +4101,14 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
                     SETLOCAL(i, def);
                     continue;
                 }
-                else if (PyErr_Occurred()) {
+                else if (_PyErr_Occurred(tstate)) {
                     goto fail;
                 }
             }
             missing++;
         }
         if (missing) {
-            missing_arguments(co, missing, -1, fastlocals);
+            missing_arguments(tstate, co, missing, -1, fastlocals);
             goto fail;
         }
     }
@@ -4132,11 +4148,11 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
 
         if (is_coro && tstate->in_coroutine_wrapper) {
             assert(coro_wrapper != NULL);
-            PyErr_Format(PyExc_RuntimeError,
-                         "coroutine wrapper %.200R attempted "
-                         "to recursively wrap %.200R",
-                         coro_wrapper,
-                         co);
+            _PyErr_Format(tstate, PyExc_RuntimeError,
+                          "coroutine wrapper %.200R attempted "
+                          "to recursively wrap %.200R",
+                          coro_wrapper,
+                          co);
             goto fail;
         }
 
@@ -4209,12 +4225,12 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
 }
 
 static PyObject *
-special_lookup(PyObject *o, _Py_Identifier *id)
+special_lookup(PyThreadState *tstate, PyObject *o, _Py_Identifier *id)
 {
     PyObject *res;
     res = _PyObject_LookupSpecial(o, id);
-    if (res == NULL && !PyErr_Occurred()) {
-        PyErr_SetObject(PyExc_AttributeError, id->object);
+    if (res == NULL && !_PyErr_Occurred(tstate)) {
+        _PyErr_SetObject(tstate, PyExc_AttributeError, id->object);
         return NULL;
     }
     return res;
@@ -4236,14 +4252,14 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
         value = exc_info->exc_value;
         tb = exc_info->exc_traceback;
         if (type == Py_None || type == NULL) {
-            PyErr_SetString(PyExc_RuntimeError,
-                            "No active exception to reraise");
+            _PyErr_SetString(tstate, PyExc_RuntimeError,
+                             "No active exception to reraise");
             return 0;
         }
         Py_XINCREF(type);
         Py_XINCREF(value);
         Py_XINCREF(tb);
-        PyErr_Restore(type, value, tb);
+        _PyErr_Restore(tstate, type, value, tb);
         return 1;
     }
 
@@ -4258,11 +4274,11 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
         if (value == NULL)
             goto raise_error;
         if (!PyExceptionInstance_Check(value)) {
-            PyErr_Format(PyExc_TypeError,
-                         "calling %R should have returned an instance of "
-                         "BaseException, not %R",
-                         type, Py_TYPE(value));
-            goto raise_error;
+            _PyErr_Format(tstate, PyExc_TypeError,
+                          "calling %R should have returned an instance of "
+                          "BaseException, not %R",
+                          type, Py_TYPE(value));
+             goto raise_error;
         }
     }
     else if (PyExceptionInstance_Check(exc)) {
@@ -4274,8 +4290,8 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
         /* Not something you can raise.  You get an exception
            anyway, just not what you specified :-) */
         Py_DECREF(exc);
-        PyErr_SetString(PyExc_TypeError,
-                        "exceptions must derive from BaseException");
+        _PyErr_SetString(tstate, PyExc_TypeError,
+                         "exceptions must derive from BaseException");
         goto raise_error;
     }
 
@@ -4298,15 +4314,15 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
             fixed_cause = NULL;
         }
         else {
-            PyErr_SetString(PyExc_TypeError,
-                            "exception causes must derive from "
-                            "BaseException");
+            _PyErr_SetString(tstate, PyExc_TypeError,
+                             "exception causes must derive from "
+                             "BaseException");
             goto raise_error;
         }
         PyException_SetCause(value, fixed_cause);
     }
 
-    PyErr_SetObject(type, value);
+    _PyErr_SetObject(tstate, type, value);
     /* PyErr_SetObject incref's its arguments */
     Py_DECREF(value);
     Py_DECREF(type);
@@ -4327,7 +4343,8 @@ raise_error:
 */
 
 static int
-unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)
+unpack_iterable(PyThreadState *tstate, PyObject *v,
+                int argcnt, int argcntafter, PyObject **sp)
 {
     int i = 0, j = 0;
     Py_ssize_t ll = 0;
@@ -4339,12 +4356,12 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)
 
     it = PyObject_GetIter(v);
     if (it == NULL) {
-        if (PyErr_ExceptionMatches(PyExc_TypeError) &&
+        if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) &&
             v->ob_type->tp_iter == NULL && !PySequence_Check(v))
         {
-            PyErr_Format(PyExc_TypeError,
-                         "cannot unpack non-iterable %.200s object",
-                         v->ob_type->tp_name);
+            _PyErr_Format(tstate, PyExc_TypeError,
+                          "cannot unpack non-iterable %.200s object",
+                          v->ob_type->tp_name);
         }
         return 0;
     }
@@ -4353,17 +4370,18 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)
         w = PyIter_Next(it);
         if (w == NULL) {
             /* Iterator done, via error or exhaustion. */
-            if (!PyErr_Occurred()) {
+            if (!_PyErr_Occurred(tstate)) {
                 if (argcntafter == -1) {
-                    PyErr_Format(PyExc_ValueError,
-                        "not enough values to unpack (expected %d, got %d)",
-                        argcnt, i);
+                    _PyErr_Format(tstate, PyExc_ValueError,
+                                  "not enough values to unpack "
+                                  "(expected %d, got %d)",
+                                  argcnt, i);
                 }
                 else {
-                    PyErr_Format(PyExc_ValueError,
-                        "not enough values to unpack "
-                        "(expected at least %d, got %d)",
-                        argcnt + argcntafter, i);
+                    _PyErr_Format(tstate, PyExc_ValueError,
+                                  "not enough values to unpack "
+                                  "(expected at least %d, got %d)",
+                                  argcnt + argcntafter, i);
                 }
             }
             goto Error;
@@ -4375,15 +4393,15 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)
         /* We better have exhausted the iterator now. */
         w = PyIter_Next(it);
         if (w == NULL) {
-            if (PyErr_Occurred())
+            if (_PyErr_Occurred(tstate))
                 goto Error;
             Py_DECREF(it);
             return 1;
         }
         Py_DECREF(w);
-        PyErr_Format(PyExc_ValueError,
-            "too many values to unpack (expected %d)",
-            argcnt);
+        _PyErr_Format(tstate, PyExc_ValueError,
+                      "too many values to unpack (expected %d)",
+                      argcnt);
         goto Error;
     }
 
@@ -4395,7 +4413,7 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)
 
     ll = PyList_GET_SIZE(l);
     if (ll < argcntafter) {
-        PyErr_Format(PyExc_ValueError,
+        _PyErr_Format(tstate, PyExc_ValueError,
             "not enough values to unpack (expected at least %d, got %zd)",
             argcnt + argcntafter, argcnt + ll);
         goto Error;
@@ -4420,11 +4438,13 @@ Error:
 
 #ifdef LLTRACE
 static int
-prtrace(PyObject *v, const char *str)
+prtrace(PyThreadState *tstate, PyObject *v, const char *str)
 {
     printf("%s ", str);
-    if (PyObject_Print(v, stdout, 0) != 0)
-        PyErr_Clear(); /* Don't know what else to do */
+    if (PyObject_Print(v, stdout, 0) != 0) {
+        /* Don't know what else to do */
+        _PyErr_Clear(tstate);
+    }
     printf("\n");
     return 1;
 }
@@ -4436,22 +4456,23 @@ call_exc_trace(Py_tracefunc func, PyObject *self,
 {
     PyObject *type, *value, *traceback, *orig_traceback, *arg;
     int err;
-    PyErr_Fetch(&type, &value, &orig_traceback);
+    _PyErr_Fetch(tstate, &type, &value, &orig_traceback);
     if (value == NULL) {
         value = Py_None;
         Py_INCREF(value);
     }
-    PyErr_NormalizeException(&type, &value, &orig_traceback);
+    _PyErr_NormalizeException(tstate, &type, &value, &orig_traceback);
     traceback = (orig_traceback != NULL) ? orig_traceback : Py_None;
     arg = PyTuple_Pack(3, type, value, traceback);
     if (arg == NULL) {
-        PyErr_Restore(type, value, orig_traceback);
+        _PyErr_Restore(tstate, type, value, orig_traceback);
         return;
     }
     err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg);
     Py_DECREF(arg);
-    if (err == 0)
-        PyErr_Restore(type, value, orig_traceback);
+    if (err == 0) {
+        _PyErr_Restore(tstate, type, value, orig_traceback);
+    }
     else {
         Py_XDECREF(type);
         Py_XDECREF(value);
@@ -4466,11 +4487,11 @@ call_trace_protected(Py_tracefunc func, PyObject *obj,
 {
     PyObject *type, *value, *traceback;
     int err;
-    PyErr_Fetch(&type, &value, &traceback);
+    _PyErr_Fetch(tstate, &type, &value, &traceback);
     err = call_trace(func, obj, tstate, frame, what, arg);
     if (err == 0)
     {
-        PyErr_Restore(type, value, traceback);
+        _PyErr_Restore(tstate, type, value, traceback);
         return 0;
     }
     else {
@@ -4672,12 +4693,26 @@ _PyEval_GetAsyncGenFinalizer(void)
     return tstate->async_gen_finalizer;
 }
 
+static PyFrameObject *
+_PyEval_GetFrame(PyThreadState *tstate)
+{
+    return _PyRuntime.gilstate.getframe(tstate);
+}
+
+PyFrameObject *
+PyEval_GetFrame(void)
+{
+    PyThreadState *tstate = _PyThreadState_GET();
+    return _PyEval_GetFrame(tstate);
+}
+
 PyObject *
 PyEval_GetBuiltins(void)
 {
-    PyFrameObject *current_frame = PyEval_GetFrame();
+    PyThreadState *tstate = _PyThreadState_GET();
+    PyFrameObject *current_frame = _PyEval_GetFrame(tstate);
     if (current_frame == NULL)
-        return _PyInterpreterState_GET_UNSAFE()->builtins;
+        return tstate->interp->builtins;
     else
         return current_frame->f_builtins;
 }
@@ -4686,12 +4721,13 @@ PyEval_GetBuiltins(void)
 PyObject *
 _PyEval_GetBuiltinId(_Py_Identifier *name)
 {
+    PyThreadState *tstate = _PyThreadState_GET();
     PyObject *attr = _PyDict_GetItemIdWithError(PyEval_GetBuiltins(), name);
     if (attr) {
         Py_INCREF(attr);
     }
-    else if (!PyErr_Occurred()) {
-        PyErr_SetObject(PyExc_AttributeError, _PyUnicode_FromId(name));
+    else if (!_PyErr_Occurred(tstate)) {
+        _PyErr_SetObject(tstate, PyExc_AttributeError, _PyUnicode_FromId(name));
     }
     return attr;
 }
@@ -4699,14 +4735,16 @@ _PyEval_GetBuiltinId(_Py_Identifier *name)
 PyObject *
 PyEval_GetLocals(void)
 {
-    PyFrameObject *current_frame = PyEval_GetFrame();
+    PyThreadState *tstate = _PyThreadState_GET();
+    PyFrameObject *current_frame = _PyEval_GetFrame(tstate);
     if (current_frame == NULL) {
-        PyErr_SetString(PyExc_SystemError, "frame does not exist");
+        _PyErr_SetString(tstate, PyExc_SystemError, "frame does not exist");
         return NULL;
     }
 
-    if (PyFrame_FastToLocalsWithError(current_frame) < 0)
+    if (PyFrame_FastToLocalsWithError(current_frame) < 0) {
         return NULL;
+    }
 
     assert(current_frame->f_locals != NULL);
     return current_frame->f_locals;
@@ -4715,26 +4753,21 @@ PyEval_GetLocals(void)
 PyObject *
 PyEval_GetGlobals(void)
 {
-    PyFrameObject *current_frame = PyEval_GetFrame();
-    if (current_frame == NULL)
+    PyThreadState *tstate = _PyThreadState_GET();
+    PyFrameObject *current_frame = _PyEval_GetFrame(tstate);
+    if (current_frame == NULL) {
         return NULL;
+    }
 
     assert(current_frame->f_globals != NULL);
     return current_frame->f_globals;
 }
 
-PyFrameObject *
-PyEval_GetFrame(void)
-{
-    _PyRuntimeState *runtime = &_PyRuntime;
-    PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
-    return runtime->gilstate.getframe(tstate);
-}
-
 int
 PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
 {
-    PyFrameObject *current_frame = PyEval_GetFrame();
+    PyThreadState *tstate = _PyThreadState_GET();
+    PyFrameObject *current_frame = _PyEval_GetFrame(tstate);
     int result = cf->cf_flags != 0;
 
     if (current_frame != NULL) {
@@ -4883,7 +4916,7 @@ call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyO
         Py_DECREF(func);
     }
 
-    assert((x != NULL) ^ (PyErr_Occurred() != NULL));
+    assert((x != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
 
     /* Clear the stack of the function object. */
     while ((*pp_stack) > pfunc) {
@@ -4939,17 +4972,18 @@ do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject
 int
 _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
 {
+    PyThreadState *tstate = _PyThreadState_GET();
     if (v != Py_None) {
         Py_ssize_t x;
         if (PyIndex_Check(v)) {
             x = PyNumber_AsSsize_t(v, NULL);
-            if (x == -1 && PyErr_Occurred())
+            if (x == -1 && _PyErr_Occurred(tstate))
                 return 0;
         }
         else {
-            PyErr_SetString(PyExc_TypeError,
-                            "slice indices must be integers or "
-                            "None or have an __index__ method");
+            _PyErr_SetString(tstate, PyExc_TypeError,
+                             "slice indices must be integers or "
+                             "None or have an __index__ method");
             return 0;
         }
         *pi = x;
@@ -4960,16 +4994,17 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
 int
 _PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi)
 {
+    PyThreadState *tstate = _PyThreadState_GET();
     Py_ssize_t x;
     if (PyIndex_Check(v)) {
         x = PyNumber_AsSsize_t(v, NULL);
-        if (x == -1 && PyErr_Occurred())
+        if (x == -1 && _PyErr_Occurred(tstate))
             return 0;
     }
     else {
-        PyErr_SetString(PyExc_TypeError,
-                        "slice indices must be integers or "
-                        "have an __index__ method");
+        _PyErr_SetString(tstate, PyExc_TypeError,
+                         "slice indices must be integers or "
+                         "have an __index__ method");
         return 0;
     }
     *pi = x;
@@ -4981,7 +5016,7 @@ _PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi)
                          "BaseException is not allowed"
 
 static PyObject *
-cmp_outcome(int op, PyObject *v, PyObject *w)
+cmp_outcome(PyThreadState *tstate, int op, PyObject *v, PyObject *w)
 {
     int res = 0;
     switch (op) {
@@ -5009,16 +5044,16 @@ cmp_outcome(int op, PyObject *v, PyObject *w)
             for (i = 0; i < length; i += 1) {
                 PyObject *exc = PyTuple_GET_ITEM(w, i);
                 if (!PyExceptionClass_Check(exc)) {
-                    PyErr_SetString(PyExc_TypeError,
-                                    CANNOT_CATCH_MSG);
+                    _PyErr_SetString(tstate, PyExc_TypeError,
+                                     CANNOT_CATCH_MSG);
                     return NULL;
                 }
             }
         }
         else {
             if (!PyExceptionClass_Check(w)) {
-                PyErr_SetString(PyExc_TypeError,
-                                CANNOT_CATCH_MSG);
+                _PyErr_SetString(tstate, PyExc_TypeError,
+                                 CANNOT_CATCH_MSG);
                 return NULL;
             }
         }
@@ -5033,7 +5068,8 @@ cmp_outcome(int op, PyObject *v, PyObject *w)
 }
 
 static PyObject *
-import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *level)
+import_name(PyThreadState *tstate, PyFrameObject *f,
+            PyObject *name, PyObject *fromlist, PyObject *level)
 {
     _Py_IDENTIFIER(__import__);
     PyObject *import_func, *res;
@@ -5041,16 +5077,16 @@ import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *leve
 
     import_func = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___import__);
     if (import_func == NULL) {
-        if (!PyErr_Occurred()) {
-            PyErr_SetString(PyExc_ImportError, "__import__ not found");
+        if (!_PyErr_Occurred(tstate)) {
+            _PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found");
         }
         return NULL;
     }
 
     /* Fast path for not overloaded __import__. */
-    if (import_func == _PyInterpreterState_GET_UNSAFE()->import_func) {
+    if (import_func == tstate->interp->import_func) {
         int ilevel = _PyLong_AsInt(level);
-        if (ilevel == -1 && PyErr_Occurred()) {
+        if (ilevel == -1 && _PyErr_Occurred(tstate)) {
             return NULL;
         }
         res = PyImport_ImportModuleLevelObject(
@@ -5075,7 +5111,7 @@ import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *leve
 }
 
 static PyObject *
-import_from(PyObject *v, PyObject *name)
+import_from(PyThreadState *tstate, PyObject *v, PyObject *name)
 {
     PyObject *x;
     _Py_IDENTIFIER(__name__);
@@ -5102,7 +5138,7 @@ import_from(PyObject *v, PyObject *name)
     }
     x = PyImport_GetModule(fullmodname);
     Py_DECREF(fullmodname);
-    if (x == NULL && !PyErr_Occurred()) {
+    if (x == NULL && !_PyErr_Occurred(tstate)) {
         goto error;
     }
     Py_DECREF(pkgname);
@@ -5120,7 +5156,7 @@ import_from(PyObject *v, PyObject *name)
     }
 
     if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) {
-        PyErr_Clear();
+        _PyErr_Clear(tstate);
         errmsg = PyUnicode_FromFormat(
             "cannot import name %R from %R (unknown location)",
             name, pkgname_or_unknown
@@ -5144,7 +5180,7 @@ import_from(PyObject *v, PyObject *name)
 }
 
 static int
-import_all_from(PyObject *locals, PyObject *v)
+import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v)
 {
     _Py_IDENTIFIER(__all__);
     _Py_IDENTIFIER(__dict__);
@@ -5161,7 +5197,7 @@ import_all_from(PyObject *locals, PyObject *v)
             return -1;
         }
         if (dict == NULL) {
-            PyErr_SetString(PyExc_ImportError,
+            _PyErr_SetString(tstate, PyExc_ImportError,
                     "from-import-* object has no __dict__ and no __all__");
             return -1;
         }
@@ -5175,10 +5211,12 @@ import_all_from(PyObject *locals, PyObject *v)
     for (pos = 0, err = 0; ; pos++) {
         name = PySequence_GetItem(all, pos);
         if (name == NULL) {
-            if (!PyErr_ExceptionMatches(PyExc_IndexError))
+            if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) {
                 err = -1;
-            else
-                PyErr_Clear();
+            }
+            else {
+                _PyErr_Clear(tstate);
+            }
             break;
         }
         if (!PyUnicode_Check(name)) {
@@ -5189,17 +5227,17 @@ import_all_from(PyObject *locals, PyObject *v)
                 break;
             }
             if (!PyUnicode_Check(modname)) {
-                PyErr_Format(PyExc_TypeError,
-                             "module __name__ must be a string, not %.100s",
-                             Py_TYPE(modname)->tp_name);
+                _PyErr_Format(tstate, PyExc_TypeError,
+                              "module __name__ must be a string, not %.100s",
+                              Py_TYPE(modname)->tp_name);
             }
             else {
-                PyErr_Format(PyExc_TypeError,
-                             "%s in %U.%s must be str, not %.100s",
-                             skip_leading_underscores ? "Key" : "Item",
-                             modname,
-                             skip_leading_underscores ? "__dict__" : "__all__",
-                             Py_TYPE(name)->tp_name);
+                _PyErr_Format(tstate, PyExc_TypeError,
+                              "%s in %U.%s must be str, not %.100s",
+                              skip_leading_underscores ? "Key" : "Item",
+                              modname,
+                              skip_leading_underscores ? "__dict__" : "__all__",
+                              Py_TYPE(name)->tp_name);
             }
             Py_DECREF(modname);
             Py_DECREF(name);
@@ -5234,22 +5272,22 @@ import_all_from(PyObject *locals, PyObject *v)
 }
 
 static int
-check_args_iterable(PyObject *func, PyObject *args)
+check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args)
 {
     if (args->ob_type->tp_iter == NULL && !PySequence_Check(args)) {
-        PyErr_Format(PyExc_TypeError,
-                     "%.200s%.200s argument after * "
-                     "must be an iterable, not %.200s",
-                     PyEval_GetFuncName(func),
-                     PyEval_GetFuncDesc(func),
-                     args->ob_type->tp_name);
+        _PyErr_Format(tstate, PyExc_TypeError,
+                      "%.200s%.200s argument after * "
+                      "must be an iterable, not %.200s",
+                      PyEval_GetFuncName(func),
+                      PyEval_GetFuncDesc(func),
+                      args->ob_type->tp_name);
         return -1;
     }
     return 0;
 }
 
 static void
-format_kwargs_error(PyObject *func, PyObject *kwargs)
+format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs)
 {
     /* _PyDict_MergeEx raises attribute
      * error (percolated from an attempt
@@ -5257,44 +5295,46 @@ format_kwargs_error(PyObject *func, PyObject *kwargs)
      * a type error if its second argument
      * is not a mapping.
      */
-    if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
-        PyErr_Format(PyExc_TypeError,
-                     "%.200s%.200s argument after ** "
-                     "must be a mapping, not %.200s",
-                     PyEval_GetFuncName(func),
-                     PyEval_GetFuncDesc(func),
-                     kwargs->ob_type->tp_name);
-    }
-    else if (PyErr_ExceptionMatches(PyExc_KeyError)) {
+    if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
+        _PyErr_Format(tstate, PyExc_TypeError,
+                      "%.200s%.200s argument after ** "
+                      "must be a mapping, not %.200s",
+                      PyEval_GetFuncName(func),
+                      PyEval_GetFuncDesc(func),
+                      kwargs->ob_type->tp_name);
+    }
+    else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
         PyObject *exc, *val, *tb;
-        PyErr_Fetch(&exc, &val, &tb);
+        _PyErr_Fetch(tstate, &exc, &val, &tb);
         if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) {
             PyObject *key = PyTuple_GET_ITEM(val, 0);
             if (!PyUnicode_Check(key)) {
-                PyErr_Format(PyExc_TypeError,
-                             "%.200s%.200s keywords must be strings",
-                             PyEval_GetFuncName(func),
-                             PyEval_GetFuncDesc(func));
-            } else {
-                PyErr_Format(PyExc_TypeError,
-                             "%.200s%.200s got multiple "
-                             "values for keyword argument '%U'",
-                             PyEval_GetFuncName(func),
-                             PyEval_GetFuncDesc(func),
-                             key);
+                _PyErr_Format(tstate, PyExc_TypeError,
+                              "%.200s%.200s keywords must be strings",
+                              PyEval_GetFuncName(func),
+                              PyEval_GetFuncDesc(func));
+            }
+            else {
+                _PyErr_Format(tstate, PyExc_TypeError,
+                              "%.200s%.200s got multiple "
+                              "values for keyword argument '%U'",
+                              PyEval_GetFuncName(func),
+                              PyEval_GetFuncDesc(func),
+                              key);
             }
             Py_XDECREF(exc);
             Py_XDECREF(val);
             Py_XDECREF(tb);
         }
         else {
-            PyErr_Restore(exc, val, tb);
+            _PyErr_Restore(tstate, exc, val, tb);
         }
     }
 }
 
 static void
-format_exc_check_arg(PyObject *exc, const char *format_str, PyObject *obj)
+format_exc_check_arg(PyThreadState *tstate, PyObject *exc,
+                     const char *format_str, PyObject *obj)
 {
     const char *obj_str;
 
@@ -5305,52 +5345,52 @@ format_exc_check_arg(PyObject *exc, const char *format_str, PyObject *obj)
     if (!obj_str)
         return;
 
-    PyErr_Format(exc, format_str, obj_str);
+    _PyErr_Format(tstate, exc, format_str, obj_str);
 }
 
 static void
-format_exc_unbound(PyCodeObject *co, int oparg)
+format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg)
 {
     PyObject *name;
     /* Don't stomp existing exception */
-    if (PyErr_Occurred())
+    if (_PyErr_Occurred(tstate))
         return;
     if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
         name = PyTuple_GET_ITEM(co->co_cellvars,
                                 oparg);
-        format_exc_check_arg(
+        format_exc_check_arg(tstate,
             PyExc_UnboundLocalError,
             UNBOUNDLOCAL_ERROR_MSG,
             name);
     } else {
         name = PyTuple_GET_ITEM(co->co_freevars, oparg -
                                 PyTuple_GET_SIZE(co->co_cellvars));
-        format_exc_check_arg(PyExc_NameError,
+        format_exc_check_arg(tstate, PyExc_NameError,
                              UNBOUNDFREE_ERROR_MSG, name);
     }
 }
 
 static void
-format_awaitable_error(PyTypeObject *type, int prevopcode)
+format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevopcode)
 {
     if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) {
         if (prevopcode == BEFORE_ASYNC_WITH) {
-            PyErr_Format(PyExc_TypeError,
-                         "'async with' received an object from __aenter__ "
-                         "that does not implement __await__: %.100s",
-                         type->tp_name);
+            _PyErr_Format(tstate, PyExc_TypeError,
+                          "'async with' received an object from __aenter__ "
+                          "that does not implement __await__: %.100s",
+                          type->tp_name);
         }
         else if (prevopcode == WITH_CLEANUP_START) {
-            PyErr_Format(PyExc_TypeError,
-                         "'async with' received an object from __aexit__ "
-                         "that does not implement __await__: %.100s",
-                         type->tp_name);
+            _PyErr_Format(tstate, PyExc_TypeError,
+                          "'async with' received an object from __aexit__ "
+                          "that does not implement __await__: %.100s",
+                          type->tp_name);
         }
     }
 }
 
 static PyObject *
-unicode_concatenate(PyObject *v, PyObject *w,
+unicode_concatenate(PyThreadState *tstate, PyObject *v, PyObject *w,
                     PyFrameObject *f, const _Py_CODEUNIT *next_instr)
 {
     PyObject *res;
@@ -5390,7 +5430,7 @@ unicode_concatenate(PyObject *v, PyObject *w,
             if (locals && PyDict_CheckExact(locals)) {
                 PyObject *w = PyDict_GetItemWithError(locals, name);
                 if ((w == v && PyDict_DelItem(locals, name) != 0) ||
-                    (w == NULL && PyErr_Occurred()))
+                    (w == NULL && _PyErr_Occurred(tstate)))
                 {
                     Py_DECREF(v);
                     return NULL;
index d9b69d9dc6ca52c1c61af7be558835dadb31ce0d..e721f1915da407a907bff84ed34a4939966fbdad 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "Python.h"
 #include "pycore_coreconfig.h"
+#include "pycore_pyerrors.h"
 #include "pycore_pystate.h"
 #include "pycore_traceback.h"
 
@@ -27,13 +28,13 @@ _Py_IDENTIFIER(builtins);
 _Py_IDENTIFIER(stderr);
 
 
-/* Forward declaration */
-static void _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type,
-                         PyObject **p_value, PyObject **p_traceback);
-static void _PyErr_Clear(PyThreadState *tstate);
+/* Forward declarations */
+static PyObject *
+_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
+               const char *format, va_list vargs);
 
 
-static void
+void
 _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
                PyObject *traceback)
 {
@@ -95,7 +96,7 @@ _PyErr_CreateException(PyObject *exception, PyObject *value)
     }
 }
 
-static void
+void
 _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
 {
     PyObject *exc_value;
@@ -103,9 +104,9 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
 
     if (exception != NULL &&
         !PyExceptionClass_Check(exception)) {
-        PyErr_Format(PyExc_SystemError,
-                     "exception %R not a BaseException subclass",
-                     exception);
+        _PyErr_Format(tstate, PyExc_SystemError,
+                      "exception %R not a BaseException subclass",
+                      exception);
         return;
     }
 
@@ -181,7 +182,7 @@ _PyErr_SetKeyError(PyObject *arg)
     Py_DECREF(tup);
 }
 
-static void
+void
 _PyErr_SetNone(PyThreadState *tstate, PyObject *exception)
 {
     _PyErr_SetObject(tstate, exception, (PyObject *)NULL);
@@ -196,7 +197,7 @@ PyErr_SetNone(PyObject *exception)
 }
 
 
-static void
+void
 _PyErr_SetString(PyThreadState *tstate, PyObject *exception,
                  const char *string)
 {
@@ -213,13 +214,6 @@ PyErr_SetString(PyObject *exception, const char *string)
 }
 
 
-static PyObject*
-_PyErr_Occurred(PyThreadState *tstate)
-{
-    return tstate == NULL ? NULL : tstate->curexc_type;
-}
-
-
 PyObject* _Py_HOT_FUNCTION
 PyErr_Occurred(void)
 {
@@ -260,11 +254,18 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
 }
 
 
+int
+_PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc)
+{
+    return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc);
+}
+
+
 int
 PyErr_ExceptionMatches(PyObject *exc)
 {
     PyThreadState *tstate = _PyThreadState_GET();
-    return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc);
+    return _PyErr_ExceptionMatches(tstate, exc);
 }
 
 
@@ -278,7 +279,7 @@ PyErr_ExceptionMatches(PyObject *exc)
    XXX: should PyErr_NormalizeException() also call
             PyException_SetTraceback() with the resulting value and tb?
 */
-static void
+void
 _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc,
                           PyObject **val, PyObject **tb)
 {
@@ -390,7 +391,7 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
 }
 
 
-static void
+void
 _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
              PyObject **p_traceback)
 {
@@ -412,7 +413,7 @@ PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
 }
 
 
-static void
+void
 _PyErr_Clear(PyThreadState *tstate)
 {
     _PyErr_Restore(tstate, NULL, NULL, NULL);
@@ -506,7 +507,7 @@ _PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception,
     Py_DECREF(exc);
     assert(!_PyErr_Occurred(tstate));
 
-    PyErr_FormatV(exception, format, vargs);
+    _PyErr_FormatV(tstate, exception, format, vargs);
 
     _PyErr_Fetch(tstate, &exc, &val2, &tb);
     _PyErr_NormalizeException(tstate, &exc, &val2, &tb);
@@ -895,9 +896,10 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
 void
 _PyErr_BadInternalCall(const char *filename, int lineno)
 {
-    PyErr_Format(PyExc_SystemError,
-                 "%s:%d: bad argument to internal function",
-                 filename, lineno);
+    PyThreadState *tstate = _PyThreadState_GET();
+    _PyErr_Format(tstate, PyExc_SystemError,
+                  "%s:%d: bad argument to internal function",
+                  filename, lineno);
 }
 
 /* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
@@ -907,16 +909,17 @@ void
 PyErr_BadInternalCall(void)
 {
     assert(0 && "bad argument to internal function");
-    PyErr_Format(PyExc_SystemError,
-                 "bad argument to internal function");
+    PyThreadState *tstate = _PyThreadState_GET();
+    _PyErr_SetString(tstate, PyExc_SystemError,
+                     "bad argument to internal function");
 }
 #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
 
 
-PyObject *
-PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
+static PyObject *
+_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
+               const char *format, va_list vargs)
 {
-    PyThreadState *tstate = _PyThreadState_GET();
     PyObject* string;
 
     /* Issue #23571: PyUnicode_FromFormatV() must not be called with an
@@ -931,16 +934,41 @@ PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
 }
 
 
+PyObject *
+PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
+{
+    PyThreadState *tstate = _PyThreadState_GET();
+    return _PyErr_FormatV(tstate, exception, format, vargs);
+}
+
+
+PyObject *
+_PyErr_Format(PyThreadState *tstate, PyObject *exception,
+              const char *format, ...)
+{
+    va_list vargs;
+#ifdef HAVE_STDARG_PROTOTYPES
+    va_start(vargs, format);
+#else
+    va_start(vargs);
+#endif
+    _PyErr_FormatV(tstate, exception, format, vargs);
+    va_end(vargs);
+    return NULL;
+}
+
+
 PyObject *
 PyErr_Format(PyObject *exception, const char *format, ...)
 {
+    PyThreadState *tstate = _PyThreadState_GET();
     va_list vargs;
 #ifdef HAVE_STDARG_PROTOTYPES
     va_start(vargs, format);
 #else
     va_start(vargs);
 #endif
-    PyErr_FormatV(exception, format, vargs);
+    _PyErr_FormatV(tstate, exception, format, vargs);
     va_end(vargs);
     return NULL;
 }
index 7219f548fd251e46a88838b9813f038aae011e81..26cb02aad5f1fb574e18c6938fb9b3d442135441 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "Python-ast.h"
 #undef Yield   /* undefine macro conflicting with <winbase.h> */
+#include "pycore_pyerrors.h"
 #include "pycore_pylifecycle.h"
 #include "pycore_pystate.h"
 #include "grammar.h"
@@ -542,12 +543,6 @@ finally:
     return 0;
 }
 
-void
-PyErr_Print(void)
-{
-    PyErr_PrintEx(1);
-}
-
 static void
 print_error_text(PyObject *f, int offset, PyObject *text_obj)
 {
@@ -667,34 +662,38 @@ handle_system_exit(void)
 }
 
 
-void
-PyErr_PrintEx(int set_sys_last_vars)
+static void
+_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
 {
     PyObject *exception, *v, *tb, *hook;
 
     handle_system_exit();
 
-    PyErr_Fetch(&exception, &v, &tb);
-    if (exception == NULL)
-        return;
-    PyErr_NormalizeException(&exception, &v, &tb);
+    _PyErr_Fetch(tstate, &exception, &v, &tb);
+    if (exception == NULL) {
+        goto done;
+    }
+
+    _PyErr_NormalizeException(tstate, &exception, &v, &tb);
     if (tb == NULL) {
         tb = Py_None;
         Py_INCREF(tb);
     }
     PyException_SetTraceback(v, tb);
-    if (exception == NULL)
-        return;
+    if (exception == NULL) {
+        goto done;
+    }
+
     /* Now we know v != NULL too */
     if (set_sys_last_vars) {
         if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) {
-            PyErr_Clear();
+            _PyErr_Clear(tstate);
         }
         if (_PySys_SetObjectId(&PyId_last_value, v) < 0) {
-            PyErr_Clear();
+            _PyErr_Clear(tstate);
         }
         if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) {
-            PyErr_Clear();
+            _PyErr_Clear(tstate);
         }
     }
     hook = _PySys_GetObjectId(&PyId_excepthook);
@@ -710,8 +709,8 @@ PyErr_PrintEx(int set_sys_last_vars)
             handle_system_exit();
 
             PyObject *exception2, *v2, *tb2;
-            PyErr_Fetch(&exception2, &v2, &tb2);
-            PyErr_NormalizeException(&exception2, &v2, &tb2);
+            _PyErr_Fetch(tstate, &exception2, &v2, &tb2);
+            _PyErr_NormalizeException(tstate, &exception2, &v2, &tb2);
             /* It should not be possible for exception2 or v2
                to be NULL. However PyErr_Display() can't
                tolerate NULLs, so just be safe. */
@@ -733,15 +732,37 @@ PyErr_PrintEx(int set_sys_last_vars)
             Py_XDECREF(tb2);
         }
         Py_XDECREF(result);
-    } else {
+    }
+    else {
         PySys_WriteStderr("sys.excepthook is missing\n");
         PyErr_Display(exception, v, tb);
     }
+
+done:
     Py_XDECREF(exception);
     Py_XDECREF(v);
     Py_XDECREF(tb);
 }
 
+void
+_PyErr_Print(PyThreadState *tstate)
+{
+    _PyErr_PrintEx(tstate, 1);
+}
+
+void
+PyErr_PrintEx(int set_sys_last_vars)
+{
+    PyThreadState *tstate = _PyThreadState_GET();
+    _PyErr_PrintEx(tstate, set_sys_last_vars);
+}
+
+void
+PyErr_Print(void)
+{
+    PyErr_PrintEx(1);
+}
+
 static void
 print_exception(PyObject *f, PyObject *value)
 {