diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2023-11-06 16:42:49 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-06 16:42:49 -0800 |
commit | 3e99c9cbf67225ec1d3bb6af812e883f19ef53de (patch) | |
tree | c838f4942faae9d6e8baa43159f4828b1cde5746 /Python/executor_cases.c.h | |
parent | d4426e8d001cfb4590911e2e7de6963e12529faf (diff) | |
download | cpython-3e99c9cbf67225ec1d3bb6af812e883f19ef53de.tar.gz cpython-3e99c9cbf67225ec1d3bb6af812e883f19ef53de.zip |
GH-111485: Make BEFORE_WITH a uop (GH-111812)
Diffstat (limited to 'Python/executor_cases.c.h')
-rw-r--r-- | Python/executor_cases.c.h | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index eb56c34b432..df7ddf2ded1 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -2304,7 +2304,50 @@ GOTO_ERROR(error); } Py_DECREF(mgr); - res = _PyObject_CallNoArgs(enter); + res = _PyObject_CallNoArgsTstate(tstate, enter); + Py_DECREF(enter); + if (res == NULL) { + Py_DECREF(exit); + if (true) goto pop_1_error_tier_two; + } + STACK_GROW(1); + stack_pointer[-2] = exit; + stack_pointer[-1] = res; + break; + } + + case BEFORE_WITH: { + PyObject *mgr; + PyObject *exit; + PyObject *res; + mgr = stack_pointer[-1]; + /* pop the context manager, push its __exit__ and the + * value returned from calling its __enter__ + */ + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol", + Py_TYPE(mgr)->tp_name); + } + GOTO_ERROR(error); + } + exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol " + "(missed __exit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + GOTO_ERROR(error); + } + Py_DECREF(mgr); + res = _PyObject_CallNoArgsTstate(tstate, enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); |