[pypy-commit] pypy py3.3: Guess what, there were two different versions of the YieldFrom implementation.

amauryfa noreply at buildbot.pypy.org
Mon Apr 21 15:13:34 CEST 2014


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3.3
Changeset: r70806:ab33ccfe90fb
Date: 2014-04-14 22:28 +0200
http://bitbucket.org/pypy/pypy/changeset/ab33ccfe90fb/

Log:	Guess what, there were two different versions of the YieldFrom
	implementation.

diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -1468,11 +1468,10 @@
 
 class Yield(expr):
 
-    def __init__(self, is_from, value, lineno, col_offset):
-        self.is_from = is_from
+    def __init__(self, value, lineno, col_offset):
         self.value = value
         expr.__init__(self, lineno, col_offset)
-        self.initialization_state = 15
+        self.initialization_state = 7
 
     def walkabout(self, visitor):
         visitor.visit_Yield(self)
@@ -1483,15 +1482,37 @@
         return visitor.visit_Yield(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~8) ^ 7:
-            self.missing_field(space, ['lineno', 'col_offset', 'is_from', None], 'Yield')
+        if (self.initialization_state & ~4) ^ 3:
+            self.missing_field(space, ['lineno', 'col_offset', None], 'Yield')
         else:
-            if not self.initialization_state & 8:
+            if not self.initialization_state & 4:
                 self.value = None
         if self.value:
             self.value.sync_app_attrs(space)
 
 
+class YieldFrom(expr):
+
+    def __init__(self, value, lineno, col_offset):
+        self.value = value
+        expr.__init__(self, lineno, col_offset)
+        self.initialization_state = 7
+
+    def walkabout(self, visitor):
+        visitor.visit_YieldFrom(self)
+
+    def mutate_over(self, visitor):
+        self.value = self.value.mutate_over(visitor)
+        return visitor.visit_YieldFrom(self)
+
+    def sync_app_attrs(self, space):
+        if (self.initialization_state & ~0) ^ 7:
+            self.missing_field(space, ['lineno', 'col_offset', 'value'], 'YieldFrom')
+        else:
+            pass
+        self.value.sync_app_attrs(space)
+
+
 class Compare(expr):
 
     def __init__(self, left, ops, comparators, lineno, col_offset):
@@ -2582,6 +2603,8 @@
         return self.default_visitor(node)
     def visit_Yield(self, node):
         return self.default_visitor(node)
+    def visit_YieldFrom(self, node):
+        return self.default_visitor(node)
     def visit_Compare(self, node):
         return self.default_visitor(node)
     def visit_Call(self, node):
@@ -2786,6 +2809,9 @@
         if node.value:
             node.value.walkabout(self)
 
+    def visit_YieldFrom(self, node):
+        node.value.walkabout(self)
+
     def visit_Compare(self, node):
         node.left.walkabout(self)
         self.visit_sequence(node.comparators)
@@ -5919,40 +5945,12 @@
     __init__=interp2app(GeneratorExp_init),
 )
 
-def Yield_get_is_from(space, w_self):
-    if w_self.w_dict is not None:
-        w_obj = w_self.getdictvalue(space, 'is_from')
-        if w_obj is not None:
-            return w_obj
-    if not w_self.initialization_state & 4:
-        raise_attriberr(space, w_self, 'is_from')
-    return space.wrap(w_self.is_from)
-
-def Yield_set_is_from(space, w_self, w_new_value):
-    try:
-        w_self.is_from = space.int_w(w_new_value)
-    except OperationError, e:
-        if not e.match(space, space.w_TypeError):
-            raise
-        w_self.setdictvalue(space, 'is_from', w_new_value)
-        w_self.initialization_state &= ~4
-        return
-    # need to save the original object too
-    w_self.setdictvalue(space, 'is_from', w_new_value)
-    w_self.initialization_state |= 4
-
-def Yield_del_is_from(space, w_self):
-    # Check if the element exists, raise appropriate exceptions
-    Yield_get_is_from(space, w_self)
-    w_self.deldictvalue(space, 'is_from')
-    w_self.initialization_state &= ~4
-
 def Yield_get_value(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 8:
+    if not w_self.initialization_state & 4:
         raise_attriberr(space, w_self, 'value')
     return space.wrap(w_self.value)
 
@@ -5965,24 +5963,24 @@
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'value', w_new_value)
-        w_self.initialization_state &= ~8
+        w_self.initialization_state &= ~4
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 8
+    w_self.initialization_state |= 4
 
 def Yield_del_value(space, w_self):
     # Check if the element exists, raise appropriate exceptions
     Yield_get_value(space, w_self)
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state &= ~8
-
-_Yield_field_unroller = unrolling_iterable(['is_from', 'value'])
+    w_self.initialization_state &= ~4
+
+_Yield_field_unroller = unrolling_iterable(['value'])
 def Yield_init(space, w_self, __args__):
     w_self = space.descr_self_interp_w(Yield, w_self)
     args_w, kwargs_w = __args__.unpack()
     if args_w:
-        if len(args_w) != 2:
-            w_err = space.wrap("Yield constructor takes either 0 or 2 positional arguments")
+        if len(args_w) != 1:
+            w_err = space.wrap("Yield constructor takes either 0 or 1 positional argument")
             raise OperationError(space.w_TypeError, w_err)
         i = 0
         for field in _Yield_field_unroller:
@@ -5994,13 +5992,65 @@
 Yield.typedef = typedef.TypeDef("Yield",
     expr.typedef,
     __module__='_ast',
-    _fields=_FieldsWrapper(['is_from', 'value']),
-    is_from=typedef.GetSetProperty(Yield_get_is_from, Yield_set_is_from, Yield_del_is_from, cls=Yield),
+    _fields=_FieldsWrapper(['value']),
     value=typedef.GetSetProperty(Yield_get_value, Yield_set_value, Yield_del_value, cls=Yield),
     __new__=interp2app(get_AST_new(Yield)),
     __init__=interp2app(Yield_init),
 )
 
+def YieldFrom_get_value(space, w_self):
+    if w_self.w_dict is not None:
+        w_obj = w_self.getdictvalue(space, 'value')
+        if w_obj is not None:
+            return w_obj
+    if not w_self.initialization_state & 4:
+        raise_attriberr(space, w_self, 'value')
+    return space.wrap(w_self.value)
+
+def YieldFrom_set_value(space, w_self, w_new_value):
+    try:
+        w_self.value = space.interp_w(expr, w_new_value, False)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
+    except OperationError, e:
+        if not e.match(space, space.w_TypeError):
+            raise
+        w_self.setdictvalue(space, 'value', w_new_value)
+        w_self.initialization_state &= ~4
+        return
+    w_self.deldictvalue(space, 'value')
+    w_self.initialization_state |= 4
+
+def YieldFrom_del_value(space, w_self):
+    # Check if the element exists, raise appropriate exceptions
+    YieldFrom_get_value(space, w_self)
+    w_self.deldictvalue(space, 'value')
+    w_self.initialization_state &= ~4
+
+_YieldFrom_field_unroller = unrolling_iterable(['value'])
+def YieldFrom_init(space, w_self, __args__):
+    w_self = space.descr_self_interp_w(YieldFrom, w_self)
+    args_w, kwargs_w = __args__.unpack()
+    if args_w:
+        if len(args_w) != 1:
+            w_err = space.wrap("YieldFrom constructor takes either 0 or 1 positional argument")
+            raise OperationError(space.w_TypeError, w_err)
+        i = 0
+        for field in _YieldFrom_field_unroller:
+            space.setattr(w_self, space.wrap(field), args_w[i])
+            i += 1
+    for field, w_value in kwargs_w.iteritems():
+        space.setattr(w_self, space.wrap(field), w_value)
+
+YieldFrom.typedef = typedef.TypeDef("YieldFrom",
+    expr.typedef,
+    __module__='_ast',
+    _fields=_FieldsWrapper(['value']),
+    value=typedef.GetSetProperty(YieldFrom_get_value, YieldFrom_set_value, YieldFrom_del_value, cls=YieldFrom),
+    __new__=interp2app(get_AST_new(YieldFrom)),
+    __init__=interp2app(YieldFrom_init),
+)
+
 def Compare_get_left(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'left')
diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py
--- a/pypy/interpreter/astcompiler/astbuilder.py
+++ b/pypy/interpreter/astcompiler/astbuilder.py
@@ -821,7 +821,9 @@
                         expr = self.handle_testlist(arg_node.children[0])
                 else:
                     expr = None
-                return ast.Yield(is_from, expr, expr_node.lineno, expr_node.column)
+                if is_from:
+                    return ast.YieldFrom(expr, expr_node.lineno, expr_node.column)
+                return ast.Yield(expr, expr_node.lineno, expr_node.column)
             elif expr_node_type == syms.factor:
                 if len(expr_node.children) == 1:
                     expr_node = expr_node.children[0]
diff --git a/pypy/interpreter/astcompiler/tools/Python.asdl b/pypy/interpreter/astcompiler/tools/Python.asdl
--- a/pypy/interpreter/astcompiler/tools/Python.asdl
+++ b/pypy/interpreter/astcompiler/tools/Python.asdl
@@ -60,7 +60,8 @@
 	     | DictComp(expr key, expr value, comprehension* generators)
 	     | GeneratorExp(expr elt, comprehension* generators)
 	     -- the grammar constrains where yield expressions can occur
-	     | Yield(int is_from, expr? value)
+	     | Yield(expr? value)
+	     | YieldFrom(expr value)
 	     -- need sequences for compare to distinguish between
 	     -- x < 4 < 3 and (x < 4) < 3
 	     | Compare(expr left, cmpop* ops, expr* comparators)


More information about the pypy-commit mailing list