On Fri, Nov 15, 2013 at 5:43 PM, Benjamin Peterson <benja...@python.org> wrote:
> 2013/11/15 anatoly techtonik <techto...@gmail.com>:
>> On Tue, Nov 12, 2013 at 5:08 PM, Benjamin Peterson <benja...@python.org> 
>> wrote:
>>> 2013/11/12 anatoly techtonik <techto...@gmail.com>:
>>>> On Sun, Nov 10, 2013 at 8:34 AM, Benjamin Peterson <benja...@python.org> 
>>>> wrote:
>>>>> 2013/11/10 anatoly techtonik <techto...@gmail.com>:
>>>>>> http://hg.python.org/cpython/file/1ee45eb6aab9/Parser/Python.asdl
>>>>>>
>>>>>> In Assign(expr* targets, expr value), why the first argument is a list?
>>>>>
>>>>> x = y = 42
>>>>
>>>> Thanks.
>>>>
>>>> Speaking of this ASDL. `expr* targets` means that multiple entities of
>>>> `expr` under the name 'targets' can be passed to Assign statement.
>>>> Assign uses them as left value. But `expr` definition contains things
>>>> that can not be used as left side assignment targets:
>>>>
>>>>     expr = BoolOp(boolop op, expr* values)
>>>>          | BinOp(expr left, operator op, expr right)
>>>>          ...
>>>>          | Str(string s) -- need to specify raw, unicode, etc?
>>>>          | Bytes(bytes s)
>>>>          | NameConstant(singleton value)
>>>>          | Ellipsis
>>>>
>>>>          -- the following expression can appear in assignment context
>>>>          | Attribute(expr value, identifier attr, expr_context ctx)
>>>>          | Subscript(expr value, slice slice, expr_context ctx)
>>>>          | Starred(expr value, expr_context ctx)
>>>>          | Name(identifier id, expr_context ctx)
>>>>          | List(expr* elts, expr_context ctx)
>>>>          | Tuple(expr* elts, expr_context ctx)
>>>>
>>>> If I understand correctly, this is compiled into C struct definitions
>>>> (Python-ast.c), and there is a code to traverse the structure, but
>>>> where is code that validates that the structure is correct? Is it done
>>>> on the first level - text file parsing, before ASDL is built? If so,
>>>> then what is the role of this ADSL exactly that the first step is
>>>> unable to solve?
>>>
>>> Only valid expression targets are allowed during AST construction. See
>>> set_expr_context in ast.c.
>>
>> Oh my. Now there is also CST in addition to AST. This stuff -
>> http://docs.python.org/devguide/ - badly needs diagrams about data
>> transformation toolchain from Python source code to machine
>> execution instructions. I'd like some pretty stuff, but raw blogdiag
>> hack will do the job http://blockdiag.com/en/blockdiag/index.html
>>
>> There is no set_expr_context in my copy of CPython code, which
>> seems to be some alpha of Python 3.4
>
> It's actually called set_context.

Ok. So what is the process?

 SOURCE --> TOKEN STREAM --> SENTENCE STREAM --> CST -->
--> AST --> BYTECODE

Is that right?

>>>> Is it possible to fix ADSL to move `expr` that are allowed in Assign
>>>> into `expr` subset? What effect will it achieve? I mean - will ADSL
>>>> compiler complain about wrong stuff on the left side, or it will still
>>>> be a role of some other component. Which one?
>>>
>>> I'm not sure what you mean by an `expr` subset.
>>
>> Transform this:
>>
>>     expr = BoolOp(boolop op, expr* values)
>>          | BinOp(expr left, operator op, expr right)
>>          ...
>>          | Str(string s) -- need to specify raw, unicode, etc?
>>          | Bytes(bytes s)
>>          | NameConstant(singleton value)
>>          | Ellipsis
>>
>>          -- the following expression can appear in assignment context
>>          | Attribute(expr value, identifier attr, expr_context ctx)
>>          | Subscript(expr value, slice slice, expr_context ctx)
>>          | Starred(expr value, expr_context ctx)
>>          | Name(identifier id, expr_context ctx)
>>          | List(expr* elts, expr_context ctx)
>>          | Tuple(expr* elts, expr_context ctx)
>>
>> to this:
>>
>>     expr = BoolOp(boolop op, expr* values)
>>          | BinOp(expr left, operator op, expr right)
>>          ...
>>          | Str(string s) -- need to specify raw, unicode, etc?
>>          | Bytes(bytes s)
>>          | NameConstant(singleton value)
>>          | Ellipsis
>>
>>          -- the following expression can appear in assignment context
>>          | expr_asgn
>>
>>      expr_asgn =
>>            Attribute(expr value, identifier attr, expr_context ctx)
>>          | Subscript(expr value, slice slice, expr_context ctx)
>>          | Starred(expr value, expr_context ctx)
>>          | Name(identifier id, expr_context ctx)
>>          | List(expr* elts, expr_context ctx)
>>          | Tuple(expr* elts, expr_context ctx)
>
> I doubt ASDL will let you do that.

asdl.py  is plain broken - wrong number of arguments passed to
            output function
asdl_c.py worked ok with fixed ASDL and generated - diff attached.
I don't know what to check further - on Windows without Visual Studio.
--
anatoly t.
--- C:/__py/_pydotorg/devinabox/cpython/Parser/Python-ast.c     Fri Nov 22 
14:19:30 2013
+++ C:/__py/_pydotorg/devinabox/cpython/Parser/Python-ast.c-patched     Fri Nov 
22 14:19:11 2013
@@ -161,10 +161,6 @@
 static PyTypeObject *Break_type;
 static PyTypeObject *Continue_type;
 static PyTypeObject *expr_type;
-static char *expr_attributes[] = {
-    "lineno",
-    "col_offset",
-};
 static PyObject* ast2obj_expr(void*);
 static PyTypeObject *BoolOp_type;
 _Py_IDENTIFIER(values);
@@ -276,6 +272,13 @@
     "value",
 };
 static PyTypeObject *Ellipsis_type;
+static PyTypeObject *expr_asgn_type;
+static PyTypeObject *expr_asgn_type;
+static char *expr_asgn_attributes[] = {
+    "lineno",
+    "col_offset",
+};
+static PyObject* ast2obj_expr_asgn(void*);
 static PyTypeObject *Attribute_type;
 _Py_IDENTIFIER(attr);
 _Py_IDENTIFIER(ctx);
@@ -853,7 +856,7 @@
     if (!Continue_type) return 0;
     expr_type = make_type("expr", &AST_type, NULL, 0);
     if (!expr_type) return 0;
-    if (!add_attributes(expr_type, expr_attributes, 2)) return 0;
+    if (!add_attributes(expr_type, NULL, 0)) return 0;
     BoolOp_type = make_type("BoolOp", expr_type, BoolOp_fields, 2);
     if (!BoolOp_type) return 0;
     BinOp_type = make_type("BinOp", expr_type, BinOp_fields, 3);
@@ -896,17 +899,24 @@
     if (!NameConstant_type) return 0;
     Ellipsis_type = make_type("Ellipsis", expr_type, NULL, 0);
     if (!Ellipsis_type) return 0;
-    Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3);
+    expr_asgn_type = make_type("expr_asgn", expr_type, NULL, 0);
+    if (!expr_asgn_type) return 0;
+    expr_asgn_type = make_type("expr_asgn", &AST_type, NULL, 0);
+    if (!expr_asgn_type) return 0;
+    if (!add_attributes(expr_asgn_type, expr_asgn_attributes, 2)) return 0;
+    Attribute_type = make_type("Attribute", expr_asgn_type, Attribute_fields,
+                               3);
     if (!Attribute_type) return 0;
-    Subscript_type = make_type("Subscript", expr_type, Subscript_fields, 3);
+    Subscript_type = make_type("Subscript", expr_asgn_type, Subscript_fields,
+                               3);
     if (!Subscript_type) return 0;
-    Starred_type = make_type("Starred", expr_type, Starred_fields, 2);
+    Starred_type = make_type("Starred", expr_asgn_type, Starred_fields, 2);
     if (!Starred_type) return 0;
-    Name_type = make_type("Name", expr_type, Name_fields, 2);
+    Name_type = make_type("Name", expr_asgn_type, Name_fields, 2);
     if (!Name_type) return 0;
-    List_type = make_type("List", expr_type, List_fields, 2);
+    List_type = make_type("List", expr_asgn_type, List_fields, 2);
     if (!List_type) return 0;
-    Tuple_type = make_type("Tuple", expr_type, Tuple_fields, 2);
+    Tuple_type = make_type("Tuple", expr_asgn_type, Tuple_fields, 2);
     if (!Tuple_type) return 0;
     expr_context_type = make_type("expr_context", &AST_type, NULL, 0);
     if (!expr_context_type) return 0;
@@ -1101,6 +1111,7 @@
 static int obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena);
 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_asgn(PyObject* obj, expr_asgn_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);
@@ -1568,8 +1579,7 @@
 }
 
 expr_ty
-BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, PyArena
-       *arena)
+BoolOp(boolop_ty op, asdl_seq * values, PyArena *arena)
 {
     expr_ty p;
     if (!op) {
@@ -1583,14 +1593,11 @@
     p->kind = BoolOp_kind;
     p->v.BoolOp.op = op;
     p->v.BoolOp.values = values;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset,
-      PyArena *arena)
+BinOp(expr_ty left, operator_ty op, expr_ty right, PyArena *arena)
 {
     expr_ty p;
     if (!left) {
@@ -1615,14 +1622,11 @@
     p->v.BinOp.left = left;
     p->v.BinOp.op = op;
     p->v.BinOp.right = right;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, PyArena
-        *arena)
+UnaryOp(unaryop_ty op, expr_ty operand, PyArena *arena)
 {
     expr_ty p;
     if (!op) {
@@ -1641,14 +1645,11 @@
     p->kind = UnaryOp_kind;
     p->v.UnaryOp.op = op;
     p->v.UnaryOp.operand = operand;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, PyArena
-       *arena)
+Lambda(arguments_ty args, expr_ty body, PyArena *arena)
 {
     expr_ty p;
     if (!args) {
@@ -1667,14 +1668,11 @@
     p->kind = Lambda_kind;
     p->v.Lambda.args = args;
     p->v.Lambda.body = body;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset,
-      PyArena *arena)
+IfExp(expr_ty test, expr_ty body, expr_ty orelse, PyArena *arena)
 {
     expr_ty p;
     if (!test) {
@@ -1699,14 +1697,11 @@
     p->v.IfExp.test = test;
     p->v.IfExp.body = body;
     p->v.IfExp.orelse = orelse;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, PyArena
-     *arena)
+Dict(asdl_seq * keys, asdl_seq * values, PyArena *arena)
 {
     expr_ty p;
     p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
@@ -1715,13 +1710,11 @@
     p->kind = Dict_kind;
     p->v.Dict.keys = keys;
     p->v.Dict.values = values;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-Set(asdl_seq * elts, int lineno, int col_offset, PyArena *arena)
+Set(asdl_seq * elts, PyArena *arena)
 {
     expr_ty p;
     p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
@@ -1729,14 +1722,11 @@
         return NULL;
     p->kind = Set_kind;
     p->v.Set.elts = elts;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
-         PyArena *arena)
+ListComp(expr_ty elt, asdl_seq * generators, PyArena *arena)
 {
     expr_ty p;
     if (!elt) {
@@ -1750,14 +1740,11 @@
     p->kind = ListComp_kind;
     p->v.ListComp.elt = elt;
     p->v.ListComp.generators = generators;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-SetComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, PyArena
-        *arena)
+SetComp(expr_ty elt, asdl_seq * generators, PyArena *arena)
 {
     expr_ty p;
     if (!elt) {
@@ -1771,14 +1758,11 @@
     p->kind = SetComp_kind;
     p->v.SetComp.elt = elt;
     p->v.SetComp.generators = generators;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int lineno, int
-         col_offset, PyArena *arena)
+DictComp(expr_ty key, expr_ty value, asdl_seq * generators, PyArena *arena)
 {
     expr_ty p;
     if (!key) {
@@ -1798,14 +1782,11 @@
     p->v.DictComp.key = key;
     p->v.DictComp.value = value;
     p->v.DictComp.generators = generators;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
-             PyArena *arena)
+GeneratorExp(expr_ty elt, asdl_seq * generators, PyArena *arena)
 {
     expr_ty p;
     if (!elt) {
@@ -1819,13 +1800,11 @@
     p->kind = GeneratorExp_kind;
     p->v.GeneratorExp.elt = elt;
     p->v.GeneratorExp.generators = generators;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-Yield(expr_ty value, int lineno, int col_offset, PyArena *arena)
+Yield(expr_ty value, PyArena *arena)
 {
     expr_ty p;
     p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
@@ -1833,13 +1812,11 @@
         return NULL;
     p->kind = Yield_kind;
     p->v.Yield.value = value;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-YieldFrom(expr_ty value, int lineno, int col_offset, PyArena *arena)
+YieldFrom(expr_ty value, PyArena *arena)
 {
     expr_ty p;
     if (!value) {
@@ -1852,14 +1829,12 @@
         return NULL;
     p->kind = YieldFrom_kind;
     p->v.YieldFrom.value = value;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno,
-        int col_offset, PyArena *arena)
+Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, PyArena
+        *arena)
 {
     expr_ty p;
     if (!left) {
@@ -1874,14 +1849,12 @@
     p->v.Compare.left = left;
     p->v.Compare.ops = ops;
     p->v.Compare.comparators = comparators;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
 Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs,
-     expr_ty kwargs, int lineno, int col_offset, PyArena *arena)
+     expr_ty kwargs, PyArena *arena)
 {
     expr_ty p;
     if (!func) {
@@ -1898,13 +1871,11 @@
     p->v.Call.keywords = keywords;
     p->v.Call.starargs = starargs;
     p->v.Call.kwargs = kwargs;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-Num(object n, int lineno, int col_offset, PyArena *arena)
+Num(object n, PyArena *arena)
 {
     expr_ty p;
     if (!n) {
@@ -1917,13 +1888,11 @@
         return NULL;
     p->kind = Num_kind;
     p->v.Num.n = n;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-Str(string s, int lineno, int col_offset, PyArena *arena)
+Str(string s, PyArena *arena)
 {
     expr_ty p;
     if (!s) {
@@ -1936,13 +1905,11 @@
         return NULL;
     p->kind = Str_kind;
     p->v.Str.s = s;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-Bytes(bytes s, int lineno, int col_offset, PyArena *arena)
+Bytes(bytes s, PyArena *arena)
 {
     expr_ty p;
     if (!s) {
@@ -1955,13 +1922,11 @@
         return NULL;
     p->kind = Bytes_kind;
     p->v.Bytes.s = s;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-NameConstant(singleton value, int lineno, int col_offset, PyArena *arena)
+NameConstant(singleton value, PyArena *arena)
 {
     expr_ty p;
     if (!value) {
@@ -1974,29 +1939,36 @@
         return NULL;
     p->kind = NameConstant_kind;
     p->v.NameConstant.value = value;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
-Ellipsis(int lineno, int col_offset, PyArena *arena)
+Ellipsis(PyArena *arena)
 {
     expr_ty p;
     p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
     if (!p)
         return NULL;
     p->kind = Ellipsis_kind;
-    p->lineno = lineno;
-    p->col_offset = col_offset;
     return p;
 }
 
 expr_ty
+expr_asgn(PyArena *arena)
+{
+    expr_ty p;
+    p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+    if (!p)
+        return NULL;
+    p->kind = expr_asgn_kind;
+    return p;
+}
+
+expr_asgn_ty
 Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int
           col_offset, PyArena *arena)
 {
-    expr_ty p;
+    expr_asgn_ty p;
     if (!value) {
         PyErr_SetString(PyExc_ValueError,
                         "field value is required for Attribute");
@@ -2012,7 +1984,7 @@
                         "field ctx is required for Attribute");
         return NULL;
     }
-    p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+    p = (expr_asgn_ty)PyArena_Malloc(arena, sizeof(*p));
     if (!p)
         return NULL;
     p->kind = Attribute_kind;
@@ -2024,11 +1996,11 @@
     return p;
 }
 
-expr_ty
+expr_asgn_ty
 Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno, int
           col_offset, PyArena *arena)
 {
-    expr_ty p;
+    expr_asgn_ty p;
     if (!value) {
         PyErr_SetString(PyExc_ValueError,
                         "field value is required for Subscript");
@@ -2044,7 +2016,7 @@
                         "field ctx is required for Subscript");
         return NULL;
     }
-    p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+    p = (expr_asgn_ty)PyArena_Malloc(arena, sizeof(*p));
     if (!p)
         return NULL;
     p->kind = Subscript_kind;
@@ -2056,11 +2028,11 @@
     return p;
 }
 
-expr_ty
+expr_asgn_ty
 Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset, PyArena
         *arena)
 {
-    expr_ty p;
+    expr_asgn_ty p;
     if (!value) {
         PyErr_SetString(PyExc_ValueError,
                         "field value is required for Starred");
@@ -2071,7 +2043,7 @@
                         "field ctx is required for Starred");
         return NULL;
     }
-    p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+    p = (expr_asgn_ty)PyArena_Malloc(arena, sizeof(*p));
     if (!p)
         return NULL;
     p->kind = Starred_kind;
@@ -2082,11 +2054,11 @@
     return p;
 }
 
-expr_ty
+expr_asgn_ty
 Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, PyArena
      *arena)
 {
-    expr_ty p;
+    expr_asgn_ty p;
     if (!id) {
         PyErr_SetString(PyExc_ValueError,
                         "field id is required for Name");
@@ -2097,7 +2069,7 @@
                         "field ctx is required for Name");
         return NULL;
     }
-    p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+    p = (expr_asgn_ty)PyArena_Malloc(arena, sizeof(*p));
     if (!p)
         return NULL;
     p->kind = Name_kind;
@@ -2108,17 +2080,17 @@
     return p;
 }
 
-expr_ty
+expr_asgn_ty
 List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, PyArena
      *arena)
 {
-    expr_ty p;
+    expr_asgn_ty p;
     if (!ctx) {
         PyErr_SetString(PyExc_ValueError,
                         "field ctx is required for List");
         return NULL;
     }
-    p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+    p = (expr_asgn_ty)PyArena_Malloc(arena, sizeof(*p));
     if (!p)
         return NULL;
     p->kind = List_kind;
@@ -2129,17 +2101,17 @@
     return p;
 }
 
-expr_ty
+expr_asgn_ty
 Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, PyArena
       *arena)
 {
-    expr_ty p;
+    expr_asgn_ty p;
     if (!ctx) {
         PyErr_SetString(PyExc_ValueError,
                         "field ctx is required for Tuple");
         return NULL;
     }
-    p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+    p = (expr_asgn_ty)PyArena_Malloc(arena, sizeof(*p));
     if (!p)
         return NULL;
     p->kind = Tuple_kind;
@@ -2479,7 +2451,7 @@
     case Assign_kind:
         result = PyType_GenericNew(Assign_type, NULL, NULL);
         if (!result) goto failed;
-        value = ast2obj_list(o->v.Assign.targets, ast2obj_expr);
+        value = ast2obj_list(o->v.Assign.targets, ast2obj_expr_asgn);
         if (!value) goto failed;
         if (_PyObject_SetAttrId(result, &PyId_targets, value) == -1)
             goto failed;
@@ -3010,6 +2982,29 @@
         result = PyType_GenericNew(Ellipsis_type, NULL, NULL);
         if (!result) goto failed;
         break;
+    case expr_asgn_kind:
+        result = PyType_GenericNew(expr_asgn_type, NULL, NULL);
+        if (!result) goto failed;
+        break;
+    }
+    return result;
+failed:
+    Py_XDECREF(value);
+    Py_XDECREF(result);
+    return NULL;
+}
+
+PyObject*
+ast2obj_expr_asgn(void* _o)
+{
+    expr_asgn_ty o = (expr_asgn_ty)_o;
+    PyObject *result = NULL, *value = NULL;
+    if (!o) {
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+
+    switch (o->kind) {
     case Attribute_kind:
         result = PyType_GenericNew(Attribute_type, NULL, NULL);
         if (!result) goto failed;
@@ -4082,8 +4077,8 @@
             targets = asdl_seq_new(len, arena);
             if (targets == NULL) goto failed;
             for (i = 0; i < len; i++) {
-                expr_ty value;
-                res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &value, arena);
+                expr_asgn_ty value;
+                res = obj2ast_expr_asgn(PyList_GET_ITEM(tmp, i), &value, 
arena);
                 if (res != 0) goto failed;
                 asdl_seq_SET(targets, i, value);
             }
@@ -4844,35 +4839,11 @@
     int isinstance;
 
     PyObject *tmp = NULL;
-    int lineno;
-    int col_offset;
 
     if (obj == Py_None) {
         *out = NULL;
         return 0;
     }
-    if (_PyObject_HasAttrId(obj, &PyId_lineno)) {
-        int res;
-        tmp = _PyObject_GetAttrId(obj, &PyId_lineno);
-        if (tmp == NULL) goto failed;
-        res = obj2ast_int(tmp, &lineno, arena);
-        if (res != 0) goto failed;
-        Py_CLEAR(tmp);
-    } else {
-        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing 
from expr");
-        return 1;
-    }
-    if (_PyObject_HasAttrId(obj, &PyId_col_offset)) {
-        int res;
-        tmp = _PyObject_GetAttrId(obj, &PyId_col_offset);
-        if (tmp == NULL) goto failed;
-        res = obj2ast_int(tmp, &col_offset, arena);
-        if (res != 0) goto failed;
-        Py_CLEAR(tmp);
-    } else {
-        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" 
missing from expr");
-        return 1;
-    }
     isinstance = PyObject_IsInstance(obj, (PyObject*)BoolOp_type);
     if (isinstance == -1) {
         return 1;
@@ -4916,7 +4887,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"values\" 
missing from BoolOp");
             return 1;
         }
-        *out = BoolOp(op, values, lineno, col_offset, arena);
+        *out = BoolOp(op, values, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -4962,7 +4933,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"right\" missing 
from BinOp");
             return 1;
         }
-        *out = BinOp(left, op, right, lineno, col_offset, arena);
+        *out = BinOp(left, op, right, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -4996,7 +4967,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"operand\" 
missing from UnaryOp");
             return 1;
         }
-        *out = UnaryOp(op, operand, lineno, col_offset, arena);
+        *out = UnaryOp(op, operand, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5030,7 +5001,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"body\" missing 
from Lambda");
             return 1;
         }
-        *out = Lambda(args, body, lineno, col_offset, arena);
+        *out = Lambda(args, body, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5076,7 +5047,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"orelse\" 
missing from IfExp");
             return 1;
         }
-        *out = IfExp(test, body, orelse, lineno, col_offset, arena);
+        *out = IfExp(test, body, orelse, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5136,7 +5107,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"values\" 
missing from Dict");
             return 1;
         }
-        *out = Dict(keys, values, lineno, col_offset, arena);
+        *out = Dict(keys, values, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5171,7 +5142,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing 
from Set");
             return 1;
         }
-        *out = Set(elts, lineno, col_offset, arena);
+        *out = Set(elts, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5218,7 +5189,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"generators\" 
missing from ListComp");
             return 1;
         }
-        *out = ListComp(elt, generators, lineno, col_offset, arena);
+        *out = ListComp(elt, generators, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5265,7 +5236,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"generators\" 
missing from SetComp");
             return 1;
         }
-        *out = SetComp(elt, generators, lineno, col_offset, arena);
+        *out = SetComp(elt, generators, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5324,7 +5295,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"generators\" 
missing from DictComp");
             return 1;
         }
-        *out = DictComp(key, value, generators, lineno, col_offset, arena);
+        *out = DictComp(key, value, generators, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5371,7 +5342,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"generators\" 
missing from GeneratorExp");
             return 1;
         }
-        *out = GeneratorExp(elt, generators, lineno, col_offset, arena);
+        *out = GeneratorExp(elt, generators, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5392,7 +5363,7 @@
         } else {
             value = NULL;
         }
-        *out = Yield(value, lineno, col_offset, arena);
+        *out = Yield(value, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5414,7 +5385,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"value\" missing 
from YieldFrom");
             return 1;
         }
-        *out = YieldFrom(value, lineno, col_offset, arena);
+        *out = YieldFrom(value, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5486,7 +5457,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"comparators\" 
missing from Compare");
             return 1;
         }
-        *out = Compare(left, ops, comparators, lineno, col_offset, arena);
+        *out = Compare(left, ops, comparators, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5580,8 +5551,7 @@
         } else {
             kwargs = NULL;
         }
-        *out = Call(func, args, keywords, starargs, kwargs, lineno, col_offset,
-                    arena);
+        *out = Call(func, args, keywords, starargs, kwargs, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5603,7 +5573,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"n\" missing 
from Num");
             return 1;
         }
-        *out = Num(n, lineno, col_offset, arena);
+        *out = Num(n, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5625,7 +5595,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"s\" missing 
from Str");
             return 1;
         }
-        *out = Str(s, lineno, col_offset, arena);
+        *out = Str(s, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5647,7 +5617,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"s\" missing 
from Bytes");
             return 1;
         }
-        *out = Bytes(s, lineno, col_offset, arena);
+        *out = Bytes(s, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5669,7 +5639,7 @@
             PyErr_SetString(PyExc_TypeError, "required field \"value\" missing 
from NameConstant");
             return 1;
         }
-        *out = NameConstant(value, lineno, col_offset, arena);
+        *out = NameConstant(value, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5679,10 +5649,62 @@
     }
     if (isinstance) {
 
-        *out = Ellipsis(lineno, col_offset, arena);
+        *out = Ellipsis(arena);
+        if (*out == NULL) goto failed;
+        return 0;
+    }
+    isinstance = PyObject_IsInstance(obj, (PyObject*)expr_asgn_type);
+    if (isinstance == -1) {
+        return 1;
+    }
+    if (isinstance) {
+
+        *out = expr_asgn(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_asgn(PyObject* obj, expr_asgn_ty* out, PyArena* arena)
+{
+    int isinstance;
+
+    PyObject *tmp = NULL;
+    int lineno;
+    int col_offset;
+
+    if (obj == Py_None) {
+        *out = NULL;
+        return 0;
+    }
+    if (_PyObject_HasAttrId(obj, &PyId_lineno)) {
+        int res;
+        tmp = _PyObject_GetAttrId(obj, &PyId_lineno);
+        if (tmp == NULL) goto failed;
+        res = obj2ast_int(tmp, &lineno, arena);
+        if (res != 0) goto failed;
+        Py_CLEAR(tmp);
+    } else {
+        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing 
from expr_asgn");
+        return 1;
+    }
+    if (_PyObject_HasAttrId(obj, &PyId_col_offset)) {
+        int res;
+        tmp = _PyObject_GetAttrId(obj, &PyId_col_offset);
+        if (tmp == NULL) goto failed;
+        res = obj2ast_int(tmp, &col_offset, arena);
+        if (res != 0) goto failed;
+        Py_CLEAR(tmp);
+    } else {
+        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" 
missing from expr_asgn");
+        return 1;
+    }
     isinstance = PyObject_IsInstance(obj, (PyObject*)Attribute_type);
     if (isinstance == -1) {
         return 1;
@@ -5938,7 +5960,7 @@
         return 0;
     }
 
-    PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", 
obj);
+    PyErr_Format(PyExc_TypeError, "expected some sort of expr_asgn, but got 
%R", obj);
     failed:
     Py_XDECREF(tmp);
     return 1;
@@ -6916,6 +6938,10 @@
     if (PyDict_SetItemString(d, "NameConstant", (PyObject*)NameConstant_type) <
         0) return NULL;
     if (PyDict_SetItemString(d, "Ellipsis", (PyObject*)Ellipsis_type) < 0)
+        return NULL;
+    if (PyDict_SetItemString(d, "expr_asgn", (PyObject*)expr_asgn_type) < 0)
+        return NULL;
+    if (PyDict_SetItemString(d, "expr_asgn", (PyObject*)expr_asgn_type) < 0)
         return NULL;
     if (PyDict_SetItemString(d, "Attribute", (PyObject*)Attribute_type) < 0)
         return NULL;
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to