summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 425a2a0..f1663ee 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -720,6 +720,7 @@ _PyObjectArray_Free(PyObject **array, PyObject **scratch)
}
}
+
/* _PyEval_EvalFrameDefault() is a *big* function,
* so consume 3 units of C stack */
#define PY_EVAL_C_STACK_UNITS 2
@@ -3031,3 +3032,137 @@ void Py_LeaveRecursiveCall(void)
{
_Py_LeaveRecursiveCall();
}
+
+PyObject *
+_PyEval_GetANext(PyObject *aiter)
+{
+ unaryfunc getter = NULL;
+ PyObject *next_iter = NULL;
+ PyTypeObject *type = Py_TYPE(aiter);
+ if (PyAsyncGen_CheckExact(aiter)) {
+ return type->tp_as_async->am_anext(aiter);
+ }
+ if (type->tp_as_async != NULL){
+ getter = type->tp_as_async->am_anext;
+ }
+
+ if (getter != NULL) {
+ next_iter = (*getter)(aiter);
+ if (next_iter == NULL) {
+ return NULL;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "'async for' requires an iterator with "
+ "__anext__ method, got %.100s",
+ type->tp_name);
+ return NULL;
+ }
+
+ PyObject *awaitable = _PyCoro_GetAwaitableIter(next_iter);
+ if (awaitable == NULL) {
+ _PyErr_FormatFromCause(
+ PyExc_TypeError,
+ "'async for' received an invalid object "
+ "from __anext__: %.100s",
+ Py_TYPE(next_iter)->tp_name);
+ }
+ Py_DECREF(next_iter);
+ return awaitable;
+}
+
+PyObject *
+_PyEval_LoadGlobal(PyObject *globals, PyObject *builtins, PyObject *name)
+{
+ PyObject *res;
+ if (PyDict_CheckExact(globals) && PyDict_CheckExact(builtins)) {
+ res = _PyDict_LoadGlobal((PyDictObject *)globals,
+ (PyDictObject *)builtins,
+ name);
+ if (res == NULL && !PyErr_Occurred()) {
+ /* _PyDict_LoadGlobal() returns NULL without raising
+ * an exception if the key doesn't exist */
+ _PyEval_FormatExcCheckArg(PyThreadState_GET(), PyExc_NameError,
+ NAME_ERROR_MSG, name);
+ }
+ }
+ else {
+ /* Slow-path if globals or builtins is not a dict */
+ /* namespace 1: globals */
+ if (PyMapping_GetOptionalItem(globals, name, &res) < 0) {
+ return NULL;
+ }
+ if (res == NULL) {
+ /* namespace 2: builtins */
+ if (PyMapping_GetOptionalItem(builtins, name, &res) < 0) {
+ return NULL;
+ }
+ if (res == NULL) {
+ _PyEval_FormatExcCheckArg(
+ PyThreadState_GET(), PyExc_NameError,
+ NAME_ERROR_MSG, name);
+ }
+ }
+ }
+ return res;
+}
+
+PyObject *
+_PyEval_GetAwaitable(PyObject *iterable, int oparg)
+{
+ PyObject *iter = _PyCoro_GetAwaitableIter(iterable);
+
+ if (iter == NULL) {
+ _PyEval_FormatAwaitableError(PyThreadState_GET(),
+ Py_TYPE(iterable), oparg);
+ }
+ else if (PyCoro_CheckExact(iter)) {
+ PyObject *yf = _PyGen_yf((PyGenObject*)iter);
+ if (yf != NULL) {
+ /* `iter` is a coroutine object that is being
+ awaited, `yf` is a pointer to the current awaitable
+ being awaited on. */
+ Py_DECREF(yf);
+ Py_CLEAR(iter);
+ _PyErr_SetString(PyThreadState_GET(), PyExc_RuntimeError,
+ "coroutine is being awaited already");
+ }
+ }
+ return iter;
+}
+
+PyObject *
+_PyEval_LoadName(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject *name)
+{
+
+ PyObject *value;
+ if (frame->f_locals == NULL) {
+ _PyErr_SetString(tstate, PyExc_SystemError,
+ "no locals found");
+ return NULL;
+ }
+ if (PyMapping_GetOptionalItem(frame->f_locals, name, &value) < 0) {
+ return NULL;
+ }
+ if (value != NULL) {
+ return value;
+ }
+ if (PyDict_GetItemRef(frame->f_globals, name, &value) < 0) {
+ return NULL;
+ }
+ if (value != NULL) {
+ return value;
+ }
+ if (PyMapping_GetOptionalItem(frame->f_builtins, name, &value) < 0) {
+ return NULL;
+ }
+ if (value == NULL) {
+ _PyEval_FormatExcCheckArg(
+ tstate, PyExc_NameError,
+ NAME_ERROR_MSG, name);
+ }
+ return value;
+}
+
+