mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
adfffc7343
commit
d8b3a98c90
|
@ -17,7 +17,7 @@ typedef struct _stmt *stmt_ty;
|
|||
typedef struct _expr *expr_ty;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -43,6 +43,10 @@ SyntaxError: invalid syntax
|
|||
Traceback (most recent call last):
|
||||
SyntaxError: cannot assign to True
|
||||
|
||||
>>> (True := 1)
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: cannot use named assignment with True
|
||||
|
||||
>>> obj.__debug__ = 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: cannot assign to __debug__
|
||||
|
|
|
@ -91,7 +91,7 @@ module Python
|
|||
-- 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)
|
||||
|
||||
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)
|
||||
| ExtSlice(slice* dims)
|
||||
|
|
|
@ -365,8 +365,7 @@ static char *Tuple_fields[]={
|
|||
};
|
||||
static PyTypeObject *expr_context_type;
|
||||
static PyObject *Load_singleton, *Store_singleton, *Del_singleton,
|
||||
*AugLoad_singleton, *AugStore_singleton, *Param_singleton,
|
||||
*NamedStore_singleton;
|
||||
*AugLoad_singleton, *AugStore_singleton, *Param_singleton;
|
||||
static PyObject* ast2obj_expr_context(expr_context_ty);
|
||||
static PyTypeObject *Load_type;
|
||||
static PyTypeObject *Store_type;
|
||||
|
@ -374,7 +373,6 @@ static PyTypeObject *Del_type;
|
|||
static PyTypeObject *AugLoad_type;
|
||||
static PyTypeObject *AugStore_type;
|
||||
static PyTypeObject *Param_type;
|
||||
static PyTypeObject *NamedStore_type;
|
||||
static PyTypeObject *slice_type;
|
||||
static PyObject* ast2obj_slice(void*);
|
||||
static PyTypeObject *Slice_type;
|
||||
|
@ -993,10 +991,6 @@ static int init_types(void)
|
|||
if (!Param_type) return 0;
|
||||
Param_singleton = PyType_GenericNew(Param_type, NULL, NULL);
|
||||
if (!Param_singleton) return 0;
|
||||
NamedStore_type = make_type("NamedStore", expr_context_type, NULL, 0);
|
||||
if (!NamedStore_type) return 0;
|
||||
NamedStore_singleton = PyType_GenericNew(NamedStore_type, NULL, NULL);
|
||||
if (!NamedStore_singleton) return 0;
|
||||
slice_type = make_type("slice", &AST_type, NULL, 0);
|
||||
if (!slice_type) return 0;
|
||||
if (!add_attributes(slice_type, NULL, 0)) return 0;
|
||||
|
@ -3657,9 +3651,6 @@ PyObject* ast2obj_expr_context(expr_context_ty o)
|
|||
case Param:
|
||||
Py_INCREF(Param_singleton);
|
||||
return Param_singleton;
|
||||
case NamedStore:
|
||||
Py_INCREF(NamedStore_singleton);
|
||||
return NamedStore_singleton;
|
||||
default:
|
||||
/* should never happen, but just in case ... */
|
||||
PyErr_Format(PyExc_SystemError, "unknown expr_context found");
|
||||
|
@ -7608,14 +7599,6 @@ obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena)
|
|||
*out = Param;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject *)NamedStore_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
}
|
||||
if (isinstance) {
|
||||
*out = NamedStore;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj);
|
||||
return 1;
|
||||
|
@ -8828,8 +8811,6 @@ PyInit__ast(void)
|
|||
return NULL;
|
||||
if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return
|
||||
NULL;
|
||||
if (PyDict_SetItemString(d, "NamedStore", (PyObject*)NamedStore_type) < 0)
|
||||
return NULL;
|
||||
if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return
|
||||
NULL;
|
||||
if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return
|
||||
|
|
199
Python/ast.c
199
Python/ast.c
|
@ -94,8 +94,6 @@ expr_context_name(expr_context_ty ctx)
|
|||
return "Load";
|
||||
case Store:
|
||||
return "Store";
|
||||
case NamedStore:
|
||||
return "NamedStore";
|
||||
case Del:
|
||||
return "Del";
|
||||
case AugLoad:
|
||||
|
@ -1029,6 +1027,80 @@ copy_location(expr_ty e, const node *n)
|
|||
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.
|
||||
|
||||
Only sets context for expr kinds that "can appear in assignment context"
|
||||
|
@ -1040,10 +1112,6 @@ static int
|
|||
set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
|
||||
{
|
||||
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
|
||||
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)
|
|||
|
||||
switch (e->kind) {
|
||||
case Attribute_kind:
|
||||
if (ctx == NamedStore) {
|
||||
expr_name = "attribute";
|
||||
break;
|
||||
}
|
||||
|
||||
e->v.Attribute.ctx = ctx;
|
||||
if (ctx == Store && forbidden_name(c, e->v.Attribute.attr, n, 1))
|
||||
return 0;
|
||||
break;
|
||||
case Subscript_kind:
|
||||
if (ctx == NamedStore) {
|
||||
expr_name = "subscript";
|
||||
break;
|
||||
}
|
||||
|
||||
e->v.Subscript.ctx = ctx;
|
||||
break;
|
||||
case Starred_kind:
|
||||
if (ctx == NamedStore) {
|
||||
expr_name = "starred";
|
||||
break;
|
||||
}
|
||||
|
||||
e->v.Starred.ctx = ctx;
|
||||
if (!set_context(c, e->v.Starred.value, ctx, n))
|
||||
return 0;
|
||||
break;
|
||||
case Name_kind:
|
||||
if (ctx == Store || ctx == NamedStore) {
|
||||
if (ctx == Store) {
|
||||
if (forbidden_name(c, e->v.Name.id, n, 0))
|
||||
return 0; /* forbidden_name() calls ast_error() */
|
||||
}
|
||||
e->v.Name.ctx = ctx;
|
||||
break;
|
||||
case List_kind:
|
||||
if (ctx == NamedStore) {
|
||||
expr_name = "list";
|
||||
break;
|
||||
}
|
||||
|
||||
e->v.List.ctx = ctx;
|
||||
s = e->v.List.elts;
|
||||
break;
|
||||
case Tuple_kind:
|
||||
if (ctx == NamedStore) {
|
||||
expr_name = "tuple";
|
||||
break;
|
||||
}
|
||||
|
||||
e->v.Tuple.ctx = ctx;
|
||||
s = e->v.Tuple.elts;
|
||||
break;
|
||||
case Lambda_kind:
|
||||
expr_name = "lambda";
|
||||
break;
|
||||
case Call_kind:
|
||||
expr_name = "function call";
|
||||
break;
|
||||
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);
|
||||
default: {
|
||||
const char *expr_name = get_expr_name(e);
|
||||
if (expr_name != NULL) {
|
||||
ast_error(c, n, "cannot %s %s",
|
||||
ctx == Store ? "assign to" : "delete",
|
||||
expr_name);
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* 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)
|
|||
if (!value)
|
||||
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 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)
|
|||
op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF;
|
||||
break;
|
||||
case Store:
|
||||
case NamedStore:
|
||||
op = STORE_DEREF;
|
||||
break;
|
||||
case AugLoad:
|
||||
|
@ -3447,7 +3446,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
|
|||
switch (ctx) {
|
||||
case Load: op = LOAD_FAST; break;
|
||||
case Store:
|
||||
case NamedStore:
|
||||
op = STORE_FAST;
|
||||
break;
|
||||
case Del: op = DELETE_FAST; break;
|
||||
|
@ -3466,7 +3464,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
|
|||
switch (ctx) {
|
||||
case Load: op = LOAD_GLOBAL; break;
|
||||
case Store:
|
||||
case NamedStore:
|
||||
op = STORE_GLOBAL;
|
||||
break;
|
||||
case Del: op = DELETE_GLOBAL; break;
|
||||
|
@ -3484,7 +3481,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
|
|||
switch (ctx) {
|
||||
case Load: op = LOAD_NAME; break;
|
||||
case Store:
|
||||
case NamedStore:
|
||||
op = STORE_NAME;
|
||||
break;
|
||||
case Del: op = DELETE_NAME; break;
|
||||
|
@ -3604,7 +3600,7 @@ static int
|
|||
compiler_list(struct compiler *c, expr_ty e)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else if (e->v.List.ctx == Load) {
|
||||
|
@ -3620,7 +3616,7 @@ static int
|
|||
compiler_tuple(struct compiler *c, expr_ty e)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else if (e->v.Tuple.ctx == Load) {
|
||||
|
@ -5154,7 +5150,6 @@ compiler_handle_subscr(struct compiler *c, const char *kind,
|
|||
case AugStore:/* fall through to Store */
|
||||
case Store: op = STORE_SUBSCR; break;
|
||||
case Del: op = DELETE_SUBSCR; break;
|
||||
case NamedStore:
|
||||
case Param:
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"invalid %s kind %d in subscript\n",
|
||||
|
|
|
@ -1452,6 +1452,10 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
|||
}
|
||||
switch (e->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.target);
|
||||
break;
|
||||
|
@ -1555,11 +1559,6 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
|||
VISIT(st, expr, e->v.Starred.value);
|
||||
break;
|
||||
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,
|
||||
e->v.Name.ctx == Load ? USE : DEF_LOCAL))
|
||||
VISIT_QUIT(st, 0);
|
||||
|
|
Loading…
Reference in New Issue