Commit d8b3a98c authored by Serhiy Storchaka's avatar Serhiy Storchaka Committed by GitHub

bpo-36187: Remove NamedStore. (GH-12167)

NamedStore has been replaced with Store. The difference between
NamedStore and Store is handled when precess the NamedExpr node
one level upper.
parent adfffc73
...@@ -17,7 +17,7 @@ typedef struct _stmt *stmt_ty; ...@@ -17,7 +17,7 @@ typedef struct _stmt *stmt_ty;
typedef struct _expr *expr_ty; typedef struct _expr *expr_ty;
typedef enum _expr_context { Load=1, Store=2, Del=3, AugLoad=4, AugStore=5, typedef enum _expr_context { Load=1, Store=2, Del=3, AugLoad=4, AugStore=5,
Param=6, NamedStore=7 } expr_context_ty; Param=6 } expr_context_ty;
typedef struct _slice *slice_ty; typedef struct _slice *slice_ty;
......
...@@ -43,6 +43,10 @@ SyntaxError: invalid syntax ...@@ -43,6 +43,10 @@ SyntaxError: invalid syntax
Traceback (most recent call last): Traceback (most recent call last):
SyntaxError: cannot assign to True SyntaxError: cannot assign to True
>>> (True := 1)
Traceback (most recent call last):
SyntaxError: cannot use named assignment with True
>>> obj.__debug__ = 1 >>> obj.__debug__ = 1
Traceback (most recent call last): Traceback (most recent call last):
SyntaxError: cannot assign to __debug__ SyntaxError: cannot assign to __debug__
......
...@@ -91,7 +91,7 @@ module Python ...@@ -91,7 +91,7 @@ module Python
-- col_offset is the byte offset in the utf8 string the parser uses -- col_offset is the byte offset in the utf8 string the parser uses
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset) attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
expr_context = Load | Store | Del | AugLoad | AugStore | Param | NamedStore expr_context = Load | Store | Del | AugLoad | AugStore | Param
slice = Slice(expr? lower, expr? upper, expr? step) slice = Slice(expr? lower, expr? upper, expr? step)
| ExtSlice(slice* dims) | ExtSlice(slice* dims)
......
...@@ -365,8 +365,7 @@ static char *Tuple_fields[]={ ...@@ -365,8 +365,7 @@ static char *Tuple_fields[]={
}; };
static PyTypeObject *expr_context_type; static PyTypeObject *expr_context_type;
static PyObject *Load_singleton, *Store_singleton, *Del_singleton, 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 PyObject* ast2obj_expr_context(expr_context_ty);
static PyTypeObject *Load_type; static PyTypeObject *Load_type;
static PyTypeObject *Store_type; static PyTypeObject *Store_type;
...@@ -374,7 +373,6 @@ static PyTypeObject *Del_type; ...@@ -374,7 +373,6 @@ static PyTypeObject *Del_type;
static PyTypeObject *AugLoad_type; static PyTypeObject *AugLoad_type;
static PyTypeObject *AugStore_type; static PyTypeObject *AugStore_type;
static PyTypeObject *Param_type; static PyTypeObject *Param_type;
static PyTypeObject *NamedStore_type;
static PyTypeObject *slice_type; static PyTypeObject *slice_type;
static PyObject* ast2obj_slice(void*); static PyObject* ast2obj_slice(void*);
static PyTypeObject *Slice_type; static PyTypeObject *Slice_type;
...@@ -993,10 +991,6 @@ static int init_types(void) ...@@ -993,10 +991,6 @@ static int init_types(void)
if (!Param_type) return 0; if (!Param_type) return 0;
Param_singleton = PyType_GenericNew(Param_type, NULL, NULL); Param_singleton = PyType_GenericNew(Param_type, NULL, NULL);
if (!Param_singleton) return 0; 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); slice_type = make_type("slice", &AST_type, NULL, 0);
if (!slice_type) return 0; if (!slice_type) return 0;
if (!add_attributes(slice_type, NULL, 0)) return 0; if (!add_attributes(slice_type, NULL, 0)) return 0;
...@@ -3657,9 +3651,6 @@ PyObject* ast2obj_expr_context(expr_context_ty o) ...@@ -3657,9 +3651,6 @@ PyObject* ast2obj_expr_context(expr_context_ty o)
case Param: case Param:
Py_INCREF(Param_singleton); Py_INCREF(Param_singleton);
return Param_singleton; return Param_singleton;
case NamedStore:
Py_INCREF(NamedStore_singleton);
return NamedStore_singleton;
default: default:
/* should never happen, but just in case ... */ /* should never happen, but just in case ... */
PyErr_Format(PyExc_SystemError, "unknown expr_context found"); PyErr_Format(PyExc_SystemError, "unknown expr_context found");
...@@ -7608,14 +7599,6 @@ obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) ...@@ -7608,14 +7599,6 @@ obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena)
*out = Param; *out = Param;
return 0; 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); PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj);
return 1; return 1;
...@@ -8828,8 +8811,6 @@ PyInit__ast(void) ...@@ -8828,8 +8811,6 @@ PyInit__ast(void)
return NULL; return NULL;
if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return
NULL; NULL;
if (PyDict_SetItemString(d, "NamedStore", (PyObject*)NamedStore_type) < 0)
return NULL;
if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return
NULL; NULL;
if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return
......
...@@ -94,8 +94,6 @@ expr_context_name(expr_context_ty ctx) ...@@ -94,8 +94,6 @@ expr_context_name(expr_context_ty ctx)
return "Load"; return "Load";
case Store: case Store:
return "Store"; return "Store";
case NamedStore:
return "NamedStore";
case Del: case Del:
return "Del"; return "Del";
case AugLoad: case AugLoad:
...@@ -1029,6 +1027,80 @@ copy_location(expr_ty e, const node *n) ...@@ -1029,6 +1027,80 @@ copy_location(expr_ty e, const node *n)
return e; return e;
} }
static const char *
get_expr_name(expr_ty e)
{
switch (e->kind) {
case Attribute_kind:
return "attribute";
case Subscript_kind:
return "subscript";
case Starred_kind:
return "starred";
case Name_kind:
return "name";
case List_kind:
return "list";
case Tuple_kind:
return "tuple";
case Lambda_kind:
return "lambda";
case Call_kind:
return "function call";
case BoolOp_kind:
case BinOp_kind:
case UnaryOp_kind:
return "operator";
case GeneratorExp_kind:
return "generator expression";
case Yield_kind:
case YieldFrom_kind:
return "yield expression";
case Await_kind:
return "await expression";
case ListComp_kind:
return "list comprehension";
case SetComp_kind:
return "set comprehension";
case DictComp_kind:
return "dict comprehension";
case Dict_kind:
return "dict display";
case Set_kind:
return "set display";
case JoinedStr_kind:
case FormattedValue_kind:
return "f-string expression";
case Constant_kind: {
PyObject *value = e->v.Constant.value;
if (value == Py_None) {
return "None";
}
if (value == Py_False) {
return "False";
}
if (value == Py_True) {
return "True";
}
if (value == Py_Ellipsis) {
return "Ellipsis";
}
return "literal";
}
case Compare_kind:
return "comparison";
case IfExp_kind:
return "conditional expression";
case NamedExpr_kind:
return "named expression";
default:
PyErr_Format(PyExc_SystemError,
"unexpected expression in assignment %d (line %d)",
e->kind, e->lineno);
return NULL;
}
}
/* Set the context ctx for expr_ty e, recursively traversing e. /* Set the context ctx for expr_ty e, recursively traversing e.
Only sets context for expr kinds that "can appear in assignment context" Only sets context for expr kinds that "can appear in assignment context"
...@@ -1040,10 +1112,6 @@ static int ...@@ -1040,10 +1112,6 @@ static int
set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
{ {
asdl_seq *s = NULL; asdl_seq *s = NULL;
/* If a particular expression type can't be used for assign / delete,
set expr_name to its name and an error message will be generated.
*/
const char* expr_name = NULL;
/* The ast defines augmented store and load contexts, but the /* The ast defines augmented store and load contexts, but the
implementation here doesn't actually use them. The code may be implementation here doesn't actually use them. The code may be
...@@ -1056,136 +1124,41 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) ...@@ -1056,136 +1124,41 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
switch (e->kind) { switch (e->kind) {
case Attribute_kind: case Attribute_kind:
if (ctx == NamedStore) {
expr_name = "attribute";
break;
}
e->v.Attribute.ctx = ctx; e->v.Attribute.ctx = ctx;
if (ctx == Store && forbidden_name(c, e->v.Attribute.attr, n, 1)) if (ctx == Store && forbidden_name(c, e->v.Attribute.attr, n, 1))
return 0; return 0;
break; break;
case Subscript_kind: case Subscript_kind:
if (ctx == NamedStore) {
expr_name = "subscript";
break;
}
e->v.Subscript.ctx = ctx; e->v.Subscript.ctx = ctx;
break; break;
case Starred_kind: case Starred_kind:
if (ctx == NamedStore) {
expr_name = "starred";
break;
}
e->v.Starred.ctx = ctx; e->v.Starred.ctx = ctx;
if (!set_context(c, e->v.Starred.value, ctx, n)) if (!set_context(c, e->v.Starred.value, ctx, n))
return 0; return 0;
break; break;
case Name_kind: case Name_kind:
if (ctx == Store || ctx == NamedStore) { if (ctx == Store) {
if (forbidden_name(c, e->v.Name.id, n, 0)) if (forbidden_name(c, e->v.Name.id, n, 0))
return 0; /* forbidden_name() calls ast_error() */ return 0; /* forbidden_name() calls ast_error() */
} }
e->v.Name.ctx = ctx; e->v.Name.ctx = ctx;
break; break;
case List_kind: case List_kind:
if (ctx == NamedStore) {
expr_name = "list";
break;
}
e->v.List.ctx = ctx; e->v.List.ctx = ctx;
s = e->v.List.elts; s = e->v.List.elts;
break; break;
case Tuple_kind: case Tuple_kind:
if (ctx == NamedStore) {
expr_name = "tuple";
break;
}
e->v.Tuple.ctx = ctx; e->v.Tuple.ctx = ctx;
s = e->v.Tuple.elts; s = e->v.Tuple.elts;
break; break;
case Lambda_kind: default: {
expr_name = "lambda"; const char *expr_name = get_expr_name(e);
break; if (expr_name != NULL) {
case Call_kind: ast_error(c, n, "cannot %s %s",
expr_name = "function call"; ctx == Store ? "assign to" : "delete",
break; expr_name);
case BoolOp_kind:
case BinOp_kind:
case UnaryOp_kind:
expr_name = "operator";
break;
case GeneratorExp_kind:
expr_name = "generator expression";
break;
case Yield_kind:
case YieldFrom_kind:
expr_name = "yield expression";
break;
case Await_kind:
expr_name = "await expression";
break;
case ListComp_kind:
expr_name = "list comprehension";
break;
case SetComp_kind:
expr_name = "set comprehension";
break;
case DictComp_kind:
expr_name = "dict comprehension";
break;
case Dict_kind:
expr_name = "dict display";
break;
case Set_kind:
expr_name = "set display";
break;
case JoinedStr_kind:
case FormattedValue_kind:
expr_name = "f-string expression";
break;
case Constant_kind: {
PyObject *value = e->v.Constant.value;
if (value == Py_None || value == Py_False || value == Py_True
|| value == Py_Ellipsis)
{
return ast_error(c, n, "cannot %s %R",
ctx == Store ? "assign to" : "delete",
value);
} }
expr_name = "literal";
break;
}
case Compare_kind:
expr_name = "comparison";
break;
case IfExp_kind:
expr_name = "conditional expression";
break;
case NamedExpr_kind:
expr_name = "named expression";
break;
default:
PyErr_Format(PyExc_SystemError,
"unexpected expression in %sassignment %d (line %d)",
ctx == NamedStore ? "named ": "",
e->kind, e->lineno);
return 0; return 0;
}
/* Check for error string set by switch */
if (expr_name) {
if (ctx == NamedStore) {
return ast_error(c, n, "cannot use named assignment with %s",
expr_name);
}
else {
return ast_error(c, n, "cannot %s %s",
ctx == Store ? "assign to" : "delete",
expr_name);
} }
} }
...@@ -1895,7 +1868,15 @@ ast_for_namedexpr(struct compiling *c, const node *n) ...@@ -1895,7 +1868,15 @@ ast_for_namedexpr(struct compiling *c, const node *n)
if (!value) if (!value)
return NULL; return NULL;
if (!set_context(c, target, NamedStore, n)) if (target->kind != Name_kind) {
const char *expr_name = get_expr_name(target);
if (expr_name != NULL) {
ast_error(c, n, "cannot use named assignment with %s", expr_name);
}
return NULL;
}
if (!set_context(c, target, Store, n))
return NULL; return NULL;
return NamedExpr(target, value, LINENO(n), n->n_col_offset, n->n_end_lineno, return NamedExpr(target, value, LINENO(n), n->n_col_offset, n->n_end_lineno,
......
...@@ -3429,7 +3429,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) ...@@ -3429,7 +3429,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF; op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF;
break; break;
case Store: case Store:
case NamedStore:
op = STORE_DEREF; op = STORE_DEREF;
break; break;
case AugLoad: case AugLoad:
...@@ -3447,7 +3446,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) ...@@ -3447,7 +3446,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
switch (ctx) { switch (ctx) {
case Load: op = LOAD_FAST; break; case Load: op = LOAD_FAST; break;
case Store: case Store:
case NamedStore:
op = STORE_FAST; op = STORE_FAST;
break; break;
case Del: op = DELETE_FAST; break; case Del: op = DELETE_FAST; break;
...@@ -3466,7 +3464,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) ...@@ -3466,7 +3464,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
switch (ctx) { switch (ctx) {
case Load: op = LOAD_GLOBAL; break; case Load: op = LOAD_GLOBAL; break;
case Store: case Store:
case NamedStore:
op = STORE_GLOBAL; op = STORE_GLOBAL;
break; break;
case Del: op = DELETE_GLOBAL; break; case Del: op = DELETE_GLOBAL; break;
...@@ -3484,7 +3481,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) ...@@ -3484,7 +3481,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
switch (ctx) { switch (ctx) {
case Load: op = LOAD_NAME; break; case Load: op = LOAD_NAME; break;
case Store: case Store:
case NamedStore:
op = STORE_NAME; op = STORE_NAME;
break; break;
case Del: op = DELETE_NAME; break; case Del: op = DELETE_NAME; break;
...@@ -3604,7 +3600,7 @@ static int ...@@ -3604,7 +3600,7 @@ static int
compiler_list(struct compiler *c, expr_ty e) compiler_list(struct compiler *c, expr_ty e)
{ {
asdl_seq *elts = e->v.List.elts; asdl_seq *elts = e->v.List.elts;
if (e->v.List.ctx == Store || e->v.List.ctx == NamedStore) { if (e->v.List.ctx == Store) {
return assignment_helper(c, elts); return assignment_helper(c, elts);
} }
else if (e->v.List.ctx == Load) { else if (e->v.List.ctx == Load) {
...@@ -3620,7 +3616,7 @@ static int ...@@ -3620,7 +3616,7 @@ static int
compiler_tuple(struct compiler *c, expr_ty e) compiler_tuple(struct compiler *c, expr_ty e)
{ {
asdl_seq *elts = e->v.Tuple.elts; asdl_seq *elts = e->v.Tuple.elts;
if (e->v.Tuple.ctx == Store || e->v.Tuple.ctx == NamedStore) { if (e->v.Tuple.ctx == Store) {
return assignment_helper(c, elts); return assignment_helper(c, elts);
} }
else if (e->v.Tuple.ctx == Load) { else if (e->v.Tuple.ctx == Load) {
...@@ -5154,7 +5150,6 @@ compiler_handle_subscr(struct compiler *c, const char *kind, ...@@ -5154,7 +5150,6 @@ compiler_handle_subscr(struct compiler *c, const char *kind,
case AugStore:/* fall through to Store */ case AugStore:/* fall through to Store */
case Store: op = STORE_SUBSCR; break; case Store: op = STORE_SUBSCR; break;
case Del: op = DELETE_SUBSCR; break; case Del: op = DELETE_SUBSCR; break;
case NamedStore:
case Param: case Param:
PyErr_Format(PyExc_SystemError, PyErr_Format(PyExc_SystemError,
"invalid %s kind %d in subscript\n", "invalid %s kind %d in subscript\n",
......
...@@ -1452,6 +1452,10 @@ symtable_visit_expr(struct symtable *st, expr_ty e) ...@@ -1452,6 +1452,10 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
} }
switch (e->kind) { switch (e->kind) {
case NamedExpr_kind: case NamedExpr_kind:
if (st->st_cur->ste_comprehension) {
if (!symtable_extend_namedexpr_scope(st, e->v.NamedExpr.target))
VISIT_QUIT(st, 0);
}
VISIT(st, expr, e->v.NamedExpr.value); VISIT(st, expr, e->v.NamedExpr.value);
VISIT(st, expr, e->v.NamedExpr.target); VISIT(st, expr, e->v.NamedExpr.target);
break; break;
...@@ -1555,11 +1559,6 @@ symtable_visit_expr(struct symtable *st, expr_ty e) ...@@ -1555,11 +1559,6 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
VISIT(st, expr, e->v.Starred.value); VISIT(st, expr, e->v.Starred.value);
break; break;
case Name_kind: case Name_kind:
/* Special-case: named expr */
if (e->v.Name.ctx == NamedStore && st->st_cur->ste_comprehension) {
if(!symtable_extend_namedexpr_scope(st, e))
VISIT_QUIT(st, 0);
}
if (!symtable_add_def(st, e->v.Name.id, if (!symtable_add_def(st, e->v.Name.id,
e->v.Name.ctx == Load ? USE : DEF_LOCAL)) e->v.Name.ctx == Load ? USE : DEF_LOCAL))
VISIT_QUIT(st, 0); VISIT_QUIT(st, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment