bpo-34822: Simplify AST for subscription. (GH-9605)

* Remove the slice type.
* Make Slice a kind of the expr type instead of the slice type.
* Replace ExtSlice(slices) with Tuple(slices, Load()).
* Replace Index(value) with a value itself.

All non-terminal nodes in AST for expressions are now of the expr type.
This commit is contained in:
Serhiy Storchaka 2020-03-10 18:52:34 +02:00 committed by GitHub
parent e5e56328af
commit 13d52c2686
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 300 additions and 709 deletions

393
Python/Python-ast.c generated
View file

@ -52,7 +52,6 @@ typedef struct {
PyObject *ExceptHandler_type;
PyObject *Expr_type;
PyObject *Expression_type;
PyObject *ExtSlice_type;
PyObject *FloorDiv_singleton;
PyObject *FloorDiv_type;
PyObject *For_type;
@ -71,7 +70,6 @@ typedef struct {
PyObject *Import_type;
PyObject *In_singleton;
PyObject *In_type;
PyObject *Index_type;
PyObject *Interactive_type;
PyObject *Invert_singleton;
PyObject *Invert_type;
@ -166,7 +164,6 @@ typedef struct {
PyObject *ctx;
PyObject *decorator_list;
PyObject *defaults;
PyObject *dims;
PyObject *elt;
PyObject *elts;
PyObject *end_col_offset;
@ -213,7 +210,6 @@ typedef struct {
PyObject *right;
PyObject *simple;
PyObject *slice;
PyObject *slice_type;
PyObject *step;
PyObject *stmt_type;
PyObject *tag;
@ -281,7 +277,6 @@ static int astmodule_clear(PyObject *module)
Py_CLEAR(astmodulestate(module)->ExceptHandler_type);
Py_CLEAR(astmodulestate(module)->Expr_type);
Py_CLEAR(astmodulestate(module)->Expression_type);
Py_CLEAR(astmodulestate(module)->ExtSlice_type);
Py_CLEAR(astmodulestate(module)->FloorDiv_singleton);
Py_CLEAR(astmodulestate(module)->FloorDiv_type);
Py_CLEAR(astmodulestate(module)->For_type);
@ -300,7 +295,6 @@ static int astmodule_clear(PyObject *module)
Py_CLEAR(astmodulestate(module)->Import_type);
Py_CLEAR(astmodulestate(module)->In_singleton);
Py_CLEAR(astmodulestate(module)->In_type);
Py_CLEAR(astmodulestate(module)->Index_type);
Py_CLEAR(astmodulestate(module)->Interactive_type);
Py_CLEAR(astmodulestate(module)->Invert_singleton);
Py_CLEAR(astmodulestate(module)->Invert_type);
@ -395,7 +389,6 @@ static int astmodule_clear(PyObject *module)
Py_CLEAR(astmodulestate(module)->ctx);
Py_CLEAR(astmodulestate(module)->decorator_list);
Py_CLEAR(astmodulestate(module)->defaults);
Py_CLEAR(astmodulestate(module)->dims);
Py_CLEAR(astmodulestate(module)->elt);
Py_CLEAR(astmodulestate(module)->elts);
Py_CLEAR(astmodulestate(module)->end_col_offset);
@ -442,7 +435,6 @@ static int astmodule_clear(PyObject *module)
Py_CLEAR(astmodulestate(module)->right);
Py_CLEAR(astmodulestate(module)->simple);
Py_CLEAR(astmodulestate(module)->slice);
Py_CLEAR(astmodulestate(module)->slice_type);
Py_CLEAR(astmodulestate(module)->step);
Py_CLEAR(astmodulestate(module)->stmt_type);
Py_CLEAR(astmodulestate(module)->tag);
@ -509,7 +501,6 @@ static int astmodule_traverse(PyObject *module, visitproc visit, void* arg)
Py_VISIT(astmodulestate(module)->ExceptHandler_type);
Py_VISIT(astmodulestate(module)->Expr_type);
Py_VISIT(astmodulestate(module)->Expression_type);
Py_VISIT(astmodulestate(module)->ExtSlice_type);
Py_VISIT(astmodulestate(module)->FloorDiv_singleton);
Py_VISIT(astmodulestate(module)->FloorDiv_type);
Py_VISIT(astmodulestate(module)->For_type);
@ -528,7 +519,6 @@ static int astmodule_traverse(PyObject *module, visitproc visit, void* arg)
Py_VISIT(astmodulestate(module)->Import_type);
Py_VISIT(astmodulestate(module)->In_singleton);
Py_VISIT(astmodulestate(module)->In_type);
Py_VISIT(astmodulestate(module)->Index_type);
Py_VISIT(astmodulestate(module)->Interactive_type);
Py_VISIT(astmodulestate(module)->Invert_singleton);
Py_VISIT(astmodulestate(module)->Invert_type);
@ -623,7 +613,6 @@ static int astmodule_traverse(PyObject *module, visitproc visit, void* arg)
Py_VISIT(astmodulestate(module)->ctx);
Py_VISIT(astmodulestate(module)->decorator_list);
Py_VISIT(astmodulestate(module)->defaults);
Py_VISIT(astmodulestate(module)->dims);
Py_VISIT(astmodulestate(module)->elt);
Py_VISIT(astmodulestate(module)->elts);
Py_VISIT(astmodulestate(module)->end_col_offset);
@ -670,7 +659,6 @@ static int astmodule_traverse(PyObject *module, visitproc visit, void* arg)
Py_VISIT(astmodulestate(module)->right);
Py_VISIT(astmodulestate(module)->simple);
Py_VISIT(astmodulestate(module)->slice);
Py_VISIT(astmodulestate(module)->slice_type);
Py_VISIT(astmodulestate(module)->step);
Py_VISIT(astmodulestate(module)->stmt_type);
Py_VISIT(astmodulestate(module)->tag);
@ -733,7 +721,6 @@ static int init_identifiers(void)
if ((state->ctx = PyUnicode_InternFromString("ctx")) == NULL) return 0;
if ((state->decorator_list = PyUnicode_InternFromString("decorator_list")) == NULL) return 0;
if ((state->defaults = PyUnicode_InternFromString("defaults")) == NULL) return 0;
if ((state->dims = PyUnicode_InternFromString("dims")) == NULL) return 0;
if ((state->elt = PyUnicode_InternFromString("elt")) == NULL) return 0;
if ((state->elts = PyUnicode_InternFromString("elts")) == NULL) return 0;
if ((state->end_col_offset = PyUnicode_InternFromString("end_col_offset")) == NULL) return 0;
@ -1035,19 +1022,12 @@ static const char * const Tuple_fields[]={
"elts",
"ctx",
};
static PyObject* ast2obj_expr_context(expr_context_ty);
static PyObject* ast2obj_slice(void*);
static const char * const Slice_fields[]={
"lower",
"upper",
"step",
};
static const char * const ExtSlice_fields[]={
"dims",
};
static const char * const Index_fields[]={
"value",
};
static PyObject* ast2obj_expr_context(expr_context_ty);
static PyObject* ast2obj_boolop(boolop_ty);
static PyObject* ast2obj_operator(operator_ty);
static PyObject* ast2obj_unaryop(unaryop_ty);
@ -1635,6 +1615,14 @@ static int init_types(void)
if (!state->List_type) return 0;
state->Tuple_type = make_type("Tuple", state->expr_type, Tuple_fields, 2);
if (!state->Tuple_type) return 0;
state->Slice_type = make_type("Slice", state->expr_type, Slice_fields, 3);
if (!state->Slice_type) return 0;
if (PyObject_SetAttr(state->Slice_type, state->lower, Py_None) == -1)
return 0;
if (PyObject_SetAttr(state->Slice_type, state->upper, Py_None) == -1)
return 0;
if (PyObject_SetAttr(state->Slice_type, state->step, Py_None) == -1)
return 0;
state->expr_context_type = make_type("expr_context", state->AST_type, NULL,
0);
if (!state->expr_context_type) return 0;
@ -1673,22 +1661,6 @@ static int init_types(void)
state->Param_singleton = PyType_GenericNew((PyTypeObject
*)state->Param_type, NULL, NULL);
if (!state->Param_singleton) return 0;
state->slice_type = make_type("slice", state->AST_type, NULL, 0);
if (!state->slice_type) return 0;
if (!add_attributes(state->slice_type, NULL, 0)) return 0;
state->Slice_type = make_type("Slice", state->slice_type, Slice_fields, 3);
if (!state->Slice_type) return 0;
if (PyObject_SetAttr(state->Slice_type, state->lower, Py_None) == -1)
return 0;
if (PyObject_SetAttr(state->Slice_type, state->upper, Py_None) == -1)
return 0;
if (PyObject_SetAttr(state->Slice_type, state->step, Py_None) == -1)
return 0;
state->ExtSlice_type = make_type("ExtSlice", state->slice_type,
ExtSlice_fields, 1);
if (!state->ExtSlice_type) return 0;
state->Index_type = make_type("Index", state->slice_type, Index_fields, 1);
if (!state->Index_type) return 0;
state->boolop_type = make_type("boolop", state->AST_type, NULL, 0);
if (!state->boolop_type) return 0;
if (!add_attributes(state->boolop_type, NULL, 0)) return 0;
@ -1929,7 +1901,6 @@ static int obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena);
static int obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena);
static int obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena*
arena);
static int obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena);
static int obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena);
static int obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena);
static int obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena);
@ -3092,7 +3063,7 @@ Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int
}
expr_ty
Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno, int
Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno, int
col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
expr_ty p;
@ -3227,46 +3198,22 @@ Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int
return p;
}
slice_ty
Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena)
expr_ty
Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int col_offset,
int end_lineno, int end_col_offset, PyArena *arena)
{
slice_ty p;
p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
expr_ty p;
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
if (!p)
return NULL;
p->kind = Slice_kind;
p->v.Slice.lower = lower;
p->v.Slice.upper = upper;
p->v.Slice.step = step;
return p;
}
slice_ty
ExtSlice(asdl_seq * dims, PyArena *arena)
{
slice_ty p;
p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
if (!p)
return NULL;
p->kind = ExtSlice_kind;
p->v.ExtSlice.dims = dims;
return p;
}
slice_ty
Index(expr_ty value, PyArena *arena)
{
slice_ty p;
if (!value) {
PyErr_SetString(PyExc_ValueError,
"field value is required for Index");
return NULL;
}
p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
if (!p)
return NULL;
p->kind = Index_kind;
p->v.Index.value = value;
p->lineno = lineno;
p->col_offset = col_offset;
p->end_lineno = end_lineno;
p->end_col_offset = end_col_offset;
return p;
}
@ -4389,7 +4336,7 @@ ast2obj_expr(void* _o)
if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_slice(o->v.Subscript.slice);
value = ast2obj_expr(o->v.Subscript.slice);
if (!value) goto failed;
if (PyObject_SetAttr(result, astmodulestate_global->slice, value) == -1)
goto failed;
@ -4460,6 +4407,26 @@ ast2obj_expr(void* _o)
goto failed;
Py_DECREF(value);
break;
case Slice_kind:
tp = (PyTypeObject *)astmodulestate_global->Slice_type;
result = PyType_GenericNew(tp, NULL, NULL);
if (!result) goto failed;
value = ast2obj_expr(o->v.Slice.lower);
if (!value) goto failed;
if (PyObject_SetAttr(result, astmodulestate_global->lower, value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_expr(o->v.Slice.upper);
if (!value) goto failed;
if (PyObject_SetAttr(result, astmodulestate_global->upper, value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_expr(o->v.Slice.step);
if (!value) goto failed;
if (PyObject_SetAttr(result, astmodulestate_global->step, value) == -1)
goto failed;
Py_DECREF(value);
break;
}
value = ast2obj_int(o->lineno);
if (!value) goto failed;
@ -4516,65 +4483,6 @@ PyObject* ast2obj_expr_context(expr_context_ty o)
return NULL;
}
}
PyObject*
ast2obj_slice(void* _o)
{
slice_ty o = (slice_ty)_o;
PyObject *result = NULL, *value = NULL;
PyTypeObject *tp;
if (!o) {
Py_RETURN_NONE;
}
switch (o->kind) {
case Slice_kind:
tp = (PyTypeObject *)astmodulestate_global->Slice_type;
result = PyType_GenericNew(tp, NULL, NULL);
if (!result) goto failed;
value = ast2obj_expr(o->v.Slice.lower);
if (!value) goto failed;
if (PyObject_SetAttr(result, astmodulestate_global->lower, value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_expr(o->v.Slice.upper);
if (!value) goto failed;
if (PyObject_SetAttr(result, astmodulestate_global->upper, value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_expr(o->v.Slice.step);
if (!value) goto failed;
if (PyObject_SetAttr(result, astmodulestate_global->step, value) == -1)
goto failed;
Py_DECREF(value);
break;
case ExtSlice_kind:
tp = (PyTypeObject *)astmodulestate_global->ExtSlice_type;
result = PyType_GenericNew(tp, NULL, NULL);
if (!result) goto failed;
value = ast2obj_list(o->v.ExtSlice.dims, ast2obj_slice);
if (!value) goto failed;
if (PyObject_SetAttr(result, astmodulestate_global->dims, value) == -1)
goto failed;
Py_DECREF(value);
break;
case Index_kind:
tp = (PyTypeObject *)astmodulestate_global->Index_type;
result = PyType_GenericNew(tp, NULL, NULL);
if (!result) goto failed;
value = ast2obj_expr(o->v.Index.value);
if (!value) goto failed;
if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
goto failed;
Py_DECREF(value);
break;
}
return result;
failed:
Py_XDECREF(value);
Py_XDECREF(result);
return NULL;
}
PyObject* ast2obj_boolop(boolop_ty o)
{
switch(o) {
@ -8421,7 +8329,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
}
if (isinstance) {
expr_ty value;
slice_ty slice;
expr_ty slice;
expr_context_ty ctx;
if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
@ -8446,7 +8354,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
}
else {
int res;
res = obj2ast_slice(tmp, &slice, arena);
res = obj2ast_expr(tmp, &slice, arena);
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
@ -8668,6 +8576,60 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
if (*out == NULL) goto failed;
return 0;
}
tp = astmodulestate_global->Slice_type;
isinstance = PyObject_IsInstance(obj, tp);
if (isinstance == -1) {
return 1;
}
if (isinstance) {
expr_ty lower;
expr_ty upper;
expr_ty step;
if (_PyObject_LookupAttr(obj, astmodulestate_global->lower, &tmp) < 0) {
return 1;
}
if (tmp == NULL || tmp == Py_None) {
Py_CLEAR(tmp);
lower = NULL;
}
else {
int res;
res = obj2ast_expr(tmp, &lower, arena);
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
if (_PyObject_LookupAttr(obj, astmodulestate_global->upper, &tmp) < 0) {
return 1;
}
if (tmp == NULL || tmp == Py_None) {
Py_CLEAR(tmp);
upper = NULL;
}
else {
int res;
res = obj2ast_expr(tmp, &upper, arena);
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
if (_PyObject_LookupAttr(obj, astmodulestate_global->step, &tmp) < 0) {
return 1;
}
if (tmp == NULL || tmp == Py_None) {
Py_CLEAR(tmp);
step = NULL;
}
else {
int res;
res = obj2ast_expr(tmp, &step, arena);
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
*out = Slice(lower, upper, step, lineno, col_offset, end_lineno,
end_col_offset, arena);
if (*out == NULL) goto failed;
return 0;
}
PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", obj);
failed:
@ -8733,148 +8695,6 @@ obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena)
return 1;
}
int
obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena)
{
int isinstance;
PyObject *tmp = NULL;
PyObject *tp;
if (obj == Py_None) {
*out = NULL;
return 0;
}
tp = astmodulestate_global->Slice_type;
isinstance = PyObject_IsInstance(obj, tp);
if (isinstance == -1) {
return 1;
}
if (isinstance) {
expr_ty lower;
expr_ty upper;
expr_ty step;
if (_PyObject_LookupAttr(obj, astmodulestate_global->lower, &tmp) < 0) {
return 1;
}
if (tmp == NULL || tmp == Py_None) {
Py_CLEAR(tmp);
lower = NULL;
}
else {
int res;
res = obj2ast_expr(tmp, &lower, arena);
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
if (_PyObject_LookupAttr(obj, astmodulestate_global->upper, &tmp) < 0) {
return 1;
}
if (tmp == NULL || tmp == Py_None) {
Py_CLEAR(tmp);
upper = NULL;
}
else {
int res;
res = obj2ast_expr(tmp, &upper, arena);
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
if (_PyObject_LookupAttr(obj, astmodulestate_global->step, &tmp) < 0) {
return 1;
}
if (tmp == NULL || tmp == Py_None) {
Py_CLEAR(tmp);
step = NULL;
}
else {
int res;
res = obj2ast_expr(tmp, &step, arena);
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
*out = Slice(lower, upper, step, arena);
if (*out == NULL) goto failed;
return 0;
}
tp = astmodulestate_global->ExtSlice_type;
isinstance = PyObject_IsInstance(obj, tp);
if (isinstance == -1) {
return 1;
}
if (isinstance) {
asdl_seq* dims;
if (_PyObject_LookupAttr(obj, astmodulestate_global->dims, &tmp) < 0) {
return 1;
}
if (tmp == NULL) {
PyErr_SetString(PyExc_TypeError, "required field \"dims\" missing from ExtSlice");
return 1;
}
else {
int res;
Py_ssize_t len;
Py_ssize_t i;
if (!PyList_Check(tmp)) {
PyErr_Format(PyExc_TypeError, "ExtSlice field \"dims\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
goto failed;
}
len = PyList_GET_SIZE(tmp);
dims = _Py_asdl_seq_new(len, arena);
if (dims == NULL) goto failed;
for (i = 0; i < len; i++) {
slice_ty val;
PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
Py_INCREF(tmp2);
res = obj2ast_slice(tmp2, &val, arena);
Py_DECREF(tmp2);
if (res != 0) goto failed;
if (len != PyList_GET_SIZE(tmp)) {
PyErr_SetString(PyExc_RuntimeError, "ExtSlice field \"dims\" changed size during iteration");
goto failed;
}
asdl_seq_SET(dims, i, val);
}
Py_CLEAR(tmp);
}
*out = ExtSlice(dims, arena);
if (*out == NULL) goto failed;
return 0;
}
tp = astmodulestate_global->Index_type;
isinstance = PyObject_IsInstance(obj, tp);
if (isinstance == -1) {
return 1;
}
if (isinstance) {
expr_ty value;
if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
return 1;
}
if (tmp == NULL) {
PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Index");
return 1;
}
else {
int res;
res = obj2ast_expr(tmp, &value, arena);
if (res != 0) goto failed;
Py_CLEAR(tmp);
}
*out = Index(value, arena);
if (*out == NULL) goto failed;
return 0;
}
PyErr_Format(PyExc_TypeError, "expected some sort of slice, but got %R", obj);
failed:
Py_XDECREF(tmp);
return 1;
}
int
obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena)
{
@ -10187,6 +10007,10 @@ PyInit__ast(void)
goto error;
}
Py_INCREF(astmodulestate(m)->Tuple_type);
if (PyModule_AddObject(m, "Slice", astmodulestate_global->Slice_type) < 0) {
goto error;
}
Py_INCREF(astmodulestate(m)->Slice_type);
if (PyModule_AddObject(m, "expr_context",
astmodulestate_global->expr_context_type) < 0) {
goto error;
@ -10218,23 +10042,6 @@ PyInit__ast(void)
goto error;
}
Py_INCREF(astmodulestate(m)->Param_type);
if (PyModule_AddObject(m, "slice", astmodulestate_global->slice_type) < 0) {
goto error;
}
Py_INCREF(astmodulestate(m)->slice_type);
if (PyModule_AddObject(m, "Slice", astmodulestate_global->Slice_type) < 0) {
goto error;
}
Py_INCREF(astmodulestate(m)->Slice_type);
if (PyModule_AddObject(m, "ExtSlice", astmodulestate_global->ExtSlice_type)
< 0) {
goto error;
}
Py_INCREF(astmodulestate(m)->ExtSlice_type);
if (PyModule_AddObject(m, "Index", astmodulestate_global->Index_type) < 0) {
goto error;
}
Py_INCREF(astmodulestate(m)->Index_type);
if (PyModule_AddObject(m, "boolop", astmodulestate_global->boolop_type) <
0) {
goto error;

View file

@ -39,31 +39,6 @@ validate_comprehension(asdl_seq *gens)
return 1;
}
static int
validate_slice(slice_ty slice)
{
switch (slice->kind) {
case Slice_kind:
return (!slice->v.Slice.lower || validate_expr(slice->v.Slice.lower, Load)) &&
(!slice->v.Slice.upper || validate_expr(slice->v.Slice.upper, Load)) &&
(!slice->v.Slice.step || validate_expr(slice->v.Slice.step, Load));
case ExtSlice_kind: {
Py_ssize_t i;
if (!validate_nonempty_seq(slice->v.ExtSlice.dims, "dims", "ExtSlice"))
return 0;
for (i = 0; i < asdl_seq_LEN(slice->v.ExtSlice.dims); i++)
if (!validate_slice(asdl_seq_GET(slice->v.ExtSlice.dims, i)))
return 0;
return 1;
}
case Index_kind:
return validate_expr(slice->v.Index.value, Load);
default:
PyErr_SetString(PyExc_SystemError, "unknown slice node");
return 0;
}
}
static int
validate_keywords(asdl_seq *keywords)
{
@ -309,10 +284,14 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
case Attribute_kind:
return validate_expr(exp->v.Attribute.value, Load);
case Subscript_kind:
return validate_slice(exp->v.Subscript.slice) &&
return validate_expr(exp->v.Subscript.slice, Load) &&
validate_expr(exp->v.Subscript.value, Load);
case Starred_kind:
return validate_expr(exp->v.Starred.value, ctx);
case Slice_kind:
return (!exp->v.Slice.lower || validate_expr(exp->v.Slice.lower, Load)) &&
(!exp->v.Slice.upper || validate_expr(exp->v.Slice.upper, Load)) &&
(!exp->v.Slice.step || validate_expr(exp->v.Slice.step, Load));
case List_kind:
return validate_exprs(exp->v.List.elts, ctx, 0);
case Tuple_kind:
@ -2471,7 +2450,7 @@ ast_for_atom(struct compiling *c, const node *n)
}
}
static slice_ty
static expr_ty
ast_for_slice(struct compiling *c, const node *n)
{
node *ch;
@ -2485,13 +2464,7 @@ ast_for_slice(struct compiling *c, const node *n)
*/
ch = CHILD(n, 0);
if (NCH(n) == 1 && TYPE(ch) == test) {
/* 'step' variable hold no significance in terms of being used over
other vars */
step = ast_for_expr(c, ch);
if (!step)
return NULL;
return Index(step, c->c_arena);
return ast_for_expr(c, ch);
}
if (TYPE(ch) == test) {
@ -2533,7 +2506,8 @@ ast_for_slice(struct compiling *c, const node *n)
}
}
return Slice(lower, upper, step, c->c_arena);
return Slice(lower, upper, step, LINENO(n), n->n_col_offset,
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
}
static expr_ty
@ -2621,7 +2595,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr, const nod
REQ(CHILD(n, 2), RSQB);
n = CHILD(n, 1);
if (NCH(n) == 1) {
slice_ty slc = ast_for_slice(c, CHILD(n, 0));
expr_ty slc = ast_for_slice(c, CHILD(n, 0));
if (!slc)
return NULL;
return Subscript(left_expr, slc, Load, LINENO(start), start->n_col_offset,
@ -2629,47 +2603,27 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr, const nod
c->c_arena);
}
else {
/* The grammar is ambiguous here. The ambiguity is resolved
by treating the sequence as a tuple literal if there are
no slice features.
*/
Py_ssize_t j;
slice_ty slc;
expr_ty e;
int simple = 1;
asdl_seq *slices, *elts;
slices = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
if (!slices)
int j;
expr_ty slc, e;
asdl_seq *elts;
elts = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
if (!elts)
return NULL;
for (j = 0; j < NCH(n); j += 2) {
slc = ast_for_slice(c, CHILD(n, j));
if (!slc)
return NULL;
if (slc->kind != Index_kind)
simple = 0;
asdl_seq_SET(slices, j / 2, slc);
}
if (!simple) {
return Subscript(left_expr, ExtSlice(slices, c->c_arena),
Load, LINENO(start), start->n_col_offset,
n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena);
}
/* extract Index values and put them in a Tuple */
elts = _Py_asdl_seq_new(asdl_seq_LEN(slices), c->c_arena);
if (!elts)
return NULL;
for (j = 0; j < asdl_seq_LEN(slices); ++j) {
slc = (slice_ty)asdl_seq_GET(slices, j);
assert(slc->kind == Index_kind && slc->v.Index.value);
asdl_seq_SET(elts, j, slc->v.Index.value);
asdl_seq_SET(elts, j / 2, slc);
}
e = Tuple(elts, Load, LINENO(n), n->n_col_offset,
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
n->n_end_lineno, n->n_end_col_offset,
c->c_arena);
if (!e)
return NULL;
return Subscript(left_expr, Index(e, c->c_arena),
return Subscript(left_expr, e,
Load, LINENO(start), start->n_col_offset,
n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena);
n_copy->n_end_lineno, n_copy->n_end_col_offset,
c->c_arena);
}
}
}

View file

@ -310,20 +310,16 @@ fold_subscr(expr_ty node, PyArena *arena, int optimize)
{
PyObject *newval;
expr_ty arg, idx;
slice_ty slice;
arg = node->v.Subscript.value;
slice = node->v.Subscript.slice;
idx = node->v.Subscript.slice;
if (node->v.Subscript.ctx != Load ||
arg->kind != Constant_kind ||
/* TODO: handle other types of slices */
slice->kind != Index_kind ||
slice->v.Index.value->kind != Constant_kind)
idx->kind != Constant_kind)
{
return 1;
}
idx = slice->v.Index.value;
newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value);
return make_const(node, newval, arena);
}
@ -395,7 +391,6 @@ static int astfold_expr(expr_ty node_, PyArena *ctx_, int optimize_);
static int astfold_arguments(arguments_ty node_, PyArena *ctx_, int optimize_);
static int astfold_comprehension(comprehension_ty node_, PyArena *ctx_, int optimize_);
static int astfold_keyword(keyword_ty node_, PyArena *ctx_, int optimize_);
static int astfold_slice(slice_ty node_, PyArena *ctx_, int optimize_);
static int astfold_arg(arg_ty node_, PyArena *ctx_, int optimize_);
static int astfold_withitem(withitem_ty node_, PyArena *ctx_, int optimize_);
static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, int optimize_);
@ -548,12 +543,17 @@ astfold_expr(expr_ty node_, PyArena *ctx_, int optimize_)
break;
case Subscript_kind:
CALL(astfold_expr, expr_ty, node_->v.Subscript.value);
CALL(astfold_slice, slice_ty, node_->v.Subscript.slice);
CALL(astfold_expr, expr_ty, node_->v.Subscript.slice);
CALL(fold_subscr, expr_ty, node_);
break;
case Starred_kind:
CALL(astfold_expr, expr_ty, node_->v.Starred.value);
break;
case Slice_kind:
CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower);
CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper);
CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step);
break;
case List_kind:
CALL_SEQ(astfold_expr, expr_ty, node_->v.List.elts);
break;
@ -572,27 +572,6 @@ astfold_expr(expr_ty node_, PyArena *ctx_, int optimize_)
return 1;
}
static int
astfold_slice(slice_ty node_, PyArena *ctx_, int optimize_)
{
switch (node_->kind) {
case Slice_kind:
CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower);
CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper);
CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step);
break;
case ExtSlice_kind:
CALL_SEQ(astfold_slice, slice_ty, node_->v.ExtSlice.dims);
break;
case Index_kind:
CALL(astfold_expr, expr_ty, node_->v.Index.value);
break;
default:
break;
}
return 1;
}
static int
astfold_keyword(keyword_ty node_, PyArena *ctx_, int optimize_)
{

View file

@ -17,7 +17,7 @@ append_joinedstr(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec);
static int
append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e);
static int
append_ast_slice(_PyUnicodeWriter *writer, slice_ty slice);
append_ast_slice(_PyUnicodeWriter *writer, expr_ty e);
static int
append_charp(_PyUnicodeWriter *writer, const char *charp)
@ -718,62 +718,31 @@ append_ast_attribute(_PyUnicodeWriter *writer, expr_ty e)
}
static int
append_ast_simple_slice(_PyUnicodeWriter *writer, slice_ty slice)
append_ast_slice(_PyUnicodeWriter *writer, expr_ty e)
{
if (slice->v.Slice.lower) {
APPEND_EXPR(slice->v.Slice.lower, PR_TEST);
if (e->v.Slice.lower) {
APPEND_EXPR(e->v.Slice.lower, PR_TEST);
}
APPEND_STR(":");
if (slice->v.Slice.upper) {
APPEND_EXPR(slice->v.Slice.upper, PR_TEST);
if (e->v.Slice.upper) {
APPEND_EXPR(e->v.Slice.upper, PR_TEST);
}
if (slice->v.Slice.step) {
if (e->v.Slice.step) {
APPEND_STR(":");
APPEND_EXPR(slice->v.Slice.step, PR_TEST);
APPEND_EXPR(e->v.Slice.step, PR_TEST);
}
return 0;
}
static int
append_ast_ext_slice(_PyUnicodeWriter *writer, slice_ty slice)
{
Py_ssize_t i, dims_count;
dims_count = asdl_seq_LEN(slice->v.ExtSlice.dims);
for (i = 0; i < dims_count; i++) {
APPEND_STR_IF(i > 0, ", ");
APPEND(slice, (slice_ty)asdl_seq_GET(slice->v.ExtSlice.dims, i));
}
APPEND_STR_IF(dims_count == 1, ",");
return 0;
}
static int
append_ast_slice(_PyUnicodeWriter *writer, slice_ty slice)
{
switch (slice->kind) {
case Slice_kind:
return append_ast_simple_slice(writer, slice);
case ExtSlice_kind:
return append_ast_ext_slice(writer, slice);
case Index_kind:
APPEND_EXPR(slice->v.Index.value, PR_TUPLE);
return 0;
default:
PyErr_SetString(PyExc_SystemError,
"unexpected slice kind");
return -1;
}
}
static int
append_ast_subscript(_PyUnicodeWriter *writer, expr_ty e)
{
APPEND_EXPR(e->v.Subscript.value, PR_ATOM);
APPEND_STR("[");
APPEND(slice, e->v.Subscript.slice);
APPEND_EXPR(e->v.Subscript.slice, PR_TUPLE);
APPEND_STR_FINISH("]");
}
@ -878,6 +847,8 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
return append_ast_subscript(writer, e);
case Starred_kind:
return append_ast_starred(writer, e);
case Slice_kind:
return append_ast_slice(writer, e);
case Name_kind:
return _PyUnicodeWriter_WriteStr(writer, e->v.Name.id);
case List_kind:

View file

@ -193,8 +193,8 @@ static int compiler_visit_keyword(struct compiler *, keyword_ty);
static int compiler_visit_expr(struct compiler *, expr_ty);
static int compiler_augassign(struct compiler *, stmt_ty);
static int compiler_annassign(struct compiler *, stmt_ty);
static int compiler_visit_slice(struct compiler *, slice_ty,
expr_context_ty);
static int compiler_subscript(struct compiler *, expr_ty);
static int compiler_slice(struct compiler *, expr_ty);
static int inplace_binop(struct compiler *, operator_ty);
static int are_all_items_const(asdl_seq *, Py_ssize_t, Py_ssize_t);
@ -4045,14 +4045,11 @@ check_subscripter(struct compiler *c, expr_ty e)
}
static int
check_index(struct compiler *c, expr_ty e, slice_ty s)
check_index(struct compiler *c, expr_ty e, expr_ty s)
{
PyObject *v;
if (s->kind != Index_kind) {
return 1;
}
PyTypeObject *index_type = infer_type(s->v.Index.value);
PyTypeObject *index_type = infer_type(s);
if (index_type == NULL
|| PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
|| index_type == &PySlice_Type) {
@ -5065,39 +5062,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
}
break;
case Subscript_kind:
switch (e->v.Subscript.ctx) {
case AugLoad:
VISIT(c, expr, e->v.Subscript.value);
VISIT_SLICE(c, e->v.Subscript.slice, AugLoad);
break;
case Load:
if (!check_subscripter(c, e->v.Subscript.value)) {
return 0;
}
if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) {
return 0;
}
VISIT(c, expr, e->v.Subscript.value);
VISIT_SLICE(c, e->v.Subscript.slice, Load);
break;
case AugStore:
VISIT_SLICE(c, e->v.Subscript.slice, AugStore);
break;
case Store:
VISIT(c, expr, e->v.Subscript.value);
VISIT_SLICE(c, e->v.Subscript.slice, Store);
break;
case Del:
VISIT(c, expr, e->v.Subscript.value);
VISIT_SLICE(c, e->v.Subscript.slice, Del);
break;
case Param:
default:
PyErr_SetString(PyExc_SystemError,
"param invalid in subscript expression");
return 0;
}
break;
return compiler_subscript(c, e);
case Starred_kind:
switch (e->v.Starred.ctx) {
case Store:
@ -5109,6 +5074,9 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
return compiler_error(c,
"can't use starred expression here");
}
break;
case Slice_kind:
return compiler_slice(c, e);
case Name_kind:
return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);
/* child nodes of List and Tuple will have expr_context set */
@ -5213,68 +5181,35 @@ check_annotation(struct compiler *c, stmt_ty s)
}
static int
check_ann_slice(struct compiler *c, slice_ty sl)
{
switch(sl->kind) {
case Index_kind:
return check_ann_expr(c, sl->v.Index.value);
case Slice_kind:
if (sl->v.Slice.lower && !check_ann_expr(c, sl->v.Slice.lower)) {
return 0;
}
if (sl->v.Slice.upper && !check_ann_expr(c, sl->v.Slice.upper)) {
return 0;
}
if (sl->v.Slice.step && !check_ann_expr(c, sl->v.Slice.step)) {
return 0;
}
break;
default:
PyErr_SetString(PyExc_SystemError,
"unexpected slice kind");
return 0;
}
return 1;
}
static int
check_ann_subscr(struct compiler *c, slice_ty sl)
check_ann_subscr(struct compiler *c, expr_ty e)
{
/* We check that everything in a subscript is defined at runtime. */
Py_ssize_t i, n;
switch (sl->kind) {
case Index_kind:
switch (e->kind) {
case Slice_kind:
if (!check_ann_slice(c, sl)) {
if (e->v.Slice.lower && !check_ann_expr(c, e->v.Slice.lower)) {
return 0;
}
break;
case ExtSlice_kind:
n = asdl_seq_LEN(sl->v.ExtSlice.dims);
if (e->v.Slice.upper && !check_ann_expr(c, e->v.Slice.upper)) {
return 0;
}
if (e->v.Slice.step && !check_ann_expr(c, e->v.Slice.step)) {
return 0;
}
return 1;
case Tuple_kind: {
/* extended slice */
asdl_seq *elts = e->v.Tuple.elts;
Py_ssize_t i, n = asdl_seq_LEN(elts);
for (i = 0; i < n; i++) {
slice_ty subsl = (slice_ty)asdl_seq_GET(sl->v.ExtSlice.dims, i);
switch (subsl->kind) {
case Index_kind:
case Slice_kind:
if (!check_ann_slice(c, subsl)) {
return 0;
}
break;
case ExtSlice_kind:
default:
PyErr_SetString(PyExc_SystemError,
"extended slice invalid in nested slice");
if (!check_ann_subscr(c, asdl_seq_GET(elts, i))) {
return 0;
}
}
break;
default:
PyErr_Format(PyExc_SystemError,
"invalid subscript kind %d", sl->kind);
return 0;
return 1;
}
default:
return check_ann_expr(c, e);
}
return 1;
}
static int
@ -5400,12 +5335,20 @@ compiler_warn(struct compiler *c, const char *format, ...)
}
static int
compiler_handle_subscr(struct compiler *c, const char *kind,
expr_context_ty ctx)
compiler_subscript(struct compiler *c, expr_ty e)
{
expr_context_ty ctx = e->v.Subscript.ctx;
int op = 0;
/* XXX this code is duplicated */
if (ctx == Load) {
if (!check_subscripter(c, e->v.Subscript.value)) {
return 0;
}
if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) {
return 0;
}
}
switch (ctx) {
case AugLoad: /* fall through to Load */
case Load: op = BINARY_SUBSCR; break;
@ -5413,23 +5356,26 @@ compiler_handle_subscr(struct compiler *c, const char *kind,
case Store: op = STORE_SUBSCR; break;
case Del: op = DELETE_SUBSCR; break;
case Param:
PyErr_Format(PyExc_SystemError,
"invalid %s kind %d in subscript\n",
kind, ctx);
PyErr_SetString(PyExc_SystemError,
"param invalid in subscript expression");
return 0;
}
if (ctx == AugLoad) {
ADDOP(c, DUP_TOP_TWO);
}
else if (ctx == AugStore) {
if (ctx == AugStore) {
ADDOP(c, ROT_THREE);
}
else {
VISIT(c, expr, e->v.Subscript.value);
VISIT(c, expr, e->v.Subscript.slice);
if (ctx == AugLoad) {
ADDOP(c, DUP_TOP_TWO);
}
}
ADDOP(c, op);
return 1;
}
static int
compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
compiler_slice(struct compiler *c, expr_ty s)
{
int n = 2;
assert(s->kind == Slice_kind);
@ -5457,64 +5403,6 @@ compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
return 1;
}
static int
compiler_visit_nested_slice(struct compiler *c, slice_ty s,
expr_context_ty ctx)
{
switch (s->kind) {
case Slice_kind:
return compiler_slice(c, s, ctx);
case Index_kind:
VISIT(c, expr, s->v.Index.value);
break;
case ExtSlice_kind:
default:
PyErr_SetString(PyExc_SystemError,
"extended slice invalid in nested slice");
return 0;
}
return 1;
}
static int
compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
{
const char * kindname = NULL;
switch (s->kind) {
case Index_kind:
kindname = "index";
if (ctx != AugStore) {
VISIT(c, expr, s->v.Index.value);
}
break;
case Slice_kind:
kindname = "slice";
if (ctx != AugStore) {
if (!compiler_slice(c, s, ctx))
return 0;
}
break;
case ExtSlice_kind:
kindname = "extended slice";
if (ctx != AugStore) {
Py_ssize_t i, n = asdl_seq_LEN(s->v.ExtSlice.dims);
for (i = 0; i < n; i++) {
slice_ty sub = (slice_ty)asdl_seq_GET(
s->v.ExtSlice.dims, i);
if (!compiler_visit_nested_slice(c, sub, ctx))
return 0;
}
ADDOP_I(c, BUILD_TUPLE, n);
}
break;
default:
PyErr_Format(PyExc_SystemError,
"invalid subscript kind %d", s->kind);
return 0;
}
return compiler_handle_subscr(c, kindname, ctx);
}
/* End of the compiler section, beginning of the assembler section */
/* do depth-first search of basic block graph, starting with block.

View file

@ -202,7 +202,6 @@ static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty);
static int symtable_visit_alias(struct symtable *st, alias_ty);
static int symtable_visit_comprehension(struct symtable *st, comprehension_ty);
static int symtable_visit_keyword(struct symtable *st, keyword_ty);
static int symtable_visit_slice(struct symtable *st, slice_ty);
static int symtable_visit_params(struct symtable *st, asdl_seq *args);
static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args);
static int symtable_implicit_arg(struct symtable *st, int pos);
@ -1632,11 +1631,19 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
break;
case Subscript_kind:
VISIT(st, expr, e->v.Subscript.value);
VISIT(st, slice, e->v.Subscript.slice);
VISIT(st, expr, e->v.Subscript.slice);
break;
case Starred_kind:
VISIT(st, expr, e->v.Starred.value);
break;
case Slice_kind:
if (e->v.Slice.lower)
VISIT(st, expr, e->v.Slice.lower)
if (e->v.Slice.upper)
VISIT(st, expr, e->v.Slice.upper)
if (e->v.Slice.step)
VISIT(st, expr, e->v.Slice.step)
break;
case Name_kind:
if (!symtable_add_def(st, e->v.Name.id,
e->v.Name.ctx == Load ? USE : DEF_LOCAL))
@ -1841,28 +1848,6 @@ symtable_visit_keyword(struct symtable *st, keyword_ty k)
}
static int
symtable_visit_slice(struct symtable *st, slice_ty s)
{
switch (s->kind) {
case Slice_kind:
if (s->v.Slice.lower)
VISIT(st, expr, s->v.Slice.lower)
if (s->v.Slice.upper)
VISIT(st, expr, s->v.Slice.upper)
if (s->v.Slice.step)
VISIT(st, expr, s->v.Slice.step)
break;
case ExtSlice_kind:
VISIT_SEQ(st, slice, s->v.ExtSlice.dims)
break;
case Index_kind:
VISIT(st, expr, s->v.Index.value)
break;
}
return 1;
}
static int
symtable_handle_comprehension(struct symtable *st, expr_ty e,
identifier scope_name, asdl_seq *generators,