diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2020-03-10 16:52:34 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-10 16:52:34 (GMT) |
commit | 13d52c268699f199a8e917a0f1dc4c51e5346c42 (patch) | |
tree | d602c97d77e3222d38c6300ed822021e51bd9dce /Python | |
parent | e5e56328afac50aad6d8893185d8e7ba8928afe2 (diff) | |
download | cpython-13d52c268699f199a8e917a0f1dc4c51e5346c42.zip cpython-13d52c268699f199a8e917a0f1dc4c51e5346c42.tar.gz cpython-13d52c268699f199a8e917a0f1dc4c51e5346c42.tar.bz2 |
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.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/Python-ast.c | 387 | ||||
-rw-r--r-- | Python/ast.c | 88 | ||||
-rw-r--r-- | Python/ast_opt.c | 37 | ||||
-rw-r--r-- | Python/ast_unparse.c | 51 | ||||
-rw-r--r-- | Python/compile.c | 202 | ||||
-rw-r--r-- | Python/symtable.c | 33 |
6 files changed, 191 insertions, 607 deletions
diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 47c88b6..f58dd9c 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -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,83 +8576,6 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) if (*out == NULL) goto failed; return 0; } - - PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", obj); - failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) -{ - int isinstance; - - isinstance = PyObject_IsInstance(obj, astmodulestate_global->Load_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Load; - return 0; - } - isinstance = PyObject_IsInstance(obj, astmodulestate_global->Store_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Store; - return 0; - } - isinstance = PyObject_IsInstance(obj, astmodulestate_global->Del_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Del; - return 0; - } - isinstance = PyObject_IsInstance(obj, astmodulestate_global->AugLoad_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = AugLoad; - return 0; - } - isinstance = PyObject_IsInstance(obj, astmodulestate_global->AugStore_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = AugStore; - return 0; - } - isinstance = PyObject_IsInstance(obj, astmodulestate_global->Param_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Param; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj); - 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) { @@ -8794,84 +8625,73 @@ obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = Slice(lower, upper, step, arena); + *out = Slice(lower, upper, step, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } - tp = astmodulestate_global->ExtSlice_type; - isinstance = PyObject_IsInstance(obj, tp); + + PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", obj); + failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) +{ + int isinstance; + + isinstance = PyObject_IsInstance(obj, astmodulestate_global->Load_type); 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; + *out = Load; return 0; } - tp = astmodulestate_global->Index_type; - isinstance = PyObject_IsInstance(obj, tp); + isinstance = PyObject_IsInstance(obj, astmodulestate_global->Store_type); 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; + *out = Store; + return 0; + } + isinstance = PyObject_IsInstance(obj, astmodulestate_global->Del_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Del; + return 0; + } + isinstance = PyObject_IsInstance(obj, astmodulestate_global->AugLoad_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = AugLoad; + return 0; + } + isinstance = PyObject_IsInstance(obj, astmodulestate_global->AugStore_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = AugStore; + return 0; + } + isinstance = PyObject_IsInstance(obj, astmodulestate_global->Param_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Param; return 0; } - PyErr_Format(PyExc_TypeError, "expected some sort of slice, but got %R", obj); - failed: - Py_XDECREF(tmp); + PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj); return 1; } @@ -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; diff --git a/Python/ast.c b/Python/ast.c index 43b50c5..62ee60a 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -40,31 +40,6 @@ validate_comprehension(asdl_seq *gens) } 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) { Py_ssize_t i; @@ -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); } } } diff --git a/Python/ast_opt.c b/Python/ast_opt.c index 39e164a..7a2b6e6 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -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; @@ -573,27 +573,6 @@ astfold_expr(expr_ty node_, PyArena *ctx_, int optimize_) } 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_) { CALL(astfold_expr, expr_ty, node_->value); diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index bd9c139..5ecd1b0 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -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: diff --git a/Python/compile.c b/Python/compile.c index f228e16..55333b3 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -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) +check_ann_subscr(struct compiler *c, expr_ty e) { - switch(sl->kind) { - case Index_kind: - return check_ann_expr(c, sl->v.Index.value); + /* We check that everything in a subscript is defined at runtime. */ + switch (e->kind) { 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)) { + if (e->v.Slice.lower && !check_ann_expr(c, e->v.Slice.lower)) { return 0; } - if (sl->v.Slice.step && !check_ann_expr(c, sl->v.Slice.step)) { + if (e->v.Slice.upper && !check_ann_expr(c, e->v.Slice.upper)) { 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) -{ - /* We check that everything in a subscript is defined at runtime. */ - Py_ssize_t i, n; - - switch (sl->kind) { - case Index_kind: - case Slice_kind: - if (!check_ann_slice(c, sl)) { + if (e->v.Slice.step && !check_ann_expr(c, e->v.Slice.step)) { return 0; } - break; - case ExtSlice_kind: - n = asdl_seq_LEN(sl->v.ExtSlice.dims); + 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; + return 1; + } default: - PyErr_Format(PyExc_SystemError, - "invalid subscript kind %d", sl->kind); - return 0; + 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. diff --git a/Python/symtable.c b/Python/symtable.c index 290e41b..014570e 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -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)) @@ -1842,28 +1849,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, expr_ty elt, expr_ty value) |