diff options
Diffstat (limited to 'Python/Python-ast.c')
-rw-r--r-- | Python/Python-ast.c | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/Python/Python-ast.c b/Python/Python-ast.c index e6c5bfe..a333ff9 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -203,6 +203,11 @@ static char *BoolOp_fields[]={ "op", "values", }; +static PyTypeObject *NamedExpr_type; +static char *NamedExpr_fields[]={ + "target", + "value", +}; static PyTypeObject *BinOp_type; _Py_IDENTIFIER(left); _Py_IDENTIFIER(right); @@ -344,7 +349,8 @@ static char *Tuple_fields[]={ }; static PyTypeObject *expr_context_type; static PyObject *Load_singleton, *Store_singleton, *Del_singleton, -*AugLoad_singleton, *AugStore_singleton, *Param_singleton; +*AugLoad_singleton, *AugStore_singleton, *Param_singleton, +*NamedStore_singleton; static PyObject* ast2obj_expr_context(expr_context_ty); static PyTypeObject *Load_type; static PyTypeObject *Store_type; @@ -352,6 +358,7 @@ static PyTypeObject *Del_type; static PyTypeObject *AugLoad_type; static PyTypeObject *AugStore_type; static PyTypeObject *Param_type; +static PyTypeObject *NamedStore_type; static PyTypeObject *slice_type; static PyObject* ast2obj_slice(void*); static PyTypeObject *Slice_type; @@ -872,6 +879,8 @@ static int init_types(void) if (!add_attributes(expr_type, expr_attributes, 4)) return 0; BoolOp_type = make_type("BoolOp", expr_type, BoolOp_fields, 2); if (!BoolOp_type) return 0; + NamedExpr_type = make_type("NamedExpr", expr_type, NamedExpr_fields, 2); + if (!NamedExpr_type) return 0; BinOp_type = make_type("BinOp", expr_type, BinOp_fields, 3); if (!BinOp_type) return 0; UnaryOp_type = make_type("UnaryOp", expr_type, UnaryOp_fields, 2); @@ -949,6 +958,10 @@ static int init_types(void) if (!Param_type) return 0; Param_singleton = PyType_GenericNew(Param_type, NULL, NULL); if (!Param_singleton) return 0; + NamedStore_type = make_type("NamedStore", expr_context_type, NULL, 0); + if (!NamedStore_type) return 0; + NamedStore_singleton = PyType_GenericNew(NamedStore_type, NULL, NULL); + if (!NamedStore_singleton) return 0; slice_type = make_type("slice", &AST_type, NULL, 0); if (!slice_type) return 0; if (!add_attributes(slice_type, NULL, 0)) return 0; @@ -1773,6 +1786,34 @@ BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, int } expr_ty +NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!target) { + PyErr_SetString(PyExc_ValueError, + "field target is required for NamedExpr"); + return NULL; + } + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for NamedExpr"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = NamedExpr_kind; + p->v.NamedExpr.target = target; + p->v.NamedExpr.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { @@ -3062,6 +3103,20 @@ ast2obj_expr(void* _o) goto failed; Py_DECREF(value); break; + case NamedExpr_kind: + result = PyType_GenericNew(NamedExpr_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.NamedExpr.target); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_target, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.NamedExpr.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + break; case BinOp_kind: result = PyType_GenericNew(BinOp_type, NULL, NULL); if (!result) goto failed; @@ -3464,6 +3519,9 @@ PyObject* ast2obj_expr_context(expr_context_ty o) case Param: Py_INCREF(Param_singleton); return Param_singleton; + case NamedStore: + Py_INCREF(NamedStore_singleton); + return NamedStore_singleton; default: /* should never happen, but just in case ... */ PyErr_Format(PyExc_SystemError, "unknown expr_context found"); @@ -5895,6 +5953,45 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) if (*out == NULL) goto failed; return 0; } + isinstance = PyObject_IsInstance(obj, (PyObject*)NamedExpr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty target; + expr_ty value; + + if (_PyObject_LookupAttrId(obj, &PyId_target, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from NamedExpr"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from NamedExpr"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = NamedExpr(target, value, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } isinstance = PyObject_IsInstance(obj, (PyObject*)BinOp_type); if (isinstance == -1) { return 1; @@ -7156,6 +7253,14 @@ obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) *out = Param; return 0; } + isinstance = PyObject_IsInstance(obj, (PyObject *)NamedStore_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = NamedStore; + return 0; + } PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj); return 1; @@ -8251,6 +8356,8 @@ PyInit__ast(void) if (PyDict_SetItemString(d, "expr", (PyObject*)expr_type) < 0) return NULL; if (PyDict_SetItemString(d, "BoolOp", (PyObject*)BoolOp_type) < 0) return NULL; + if (PyDict_SetItemString(d, "NamedExpr", (PyObject*)NamedExpr_type) < 0) + return NULL; if (PyDict_SetItemString(d, "BinOp", (PyObject*)BinOp_type) < 0) return NULL; if (PyDict_SetItemString(d, "UnaryOp", (PyObject*)UnaryOp_type) < 0) return @@ -8306,6 +8413,8 @@ PyInit__ast(void) return NULL; if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return NULL; + if (PyDict_SetItemString(d, "NamedStore", (PyObject*)NamedStore_type) < 0) + return NULL; if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return NULL; if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return |