[pypy-commit] pypy py3k: add ast.Bytes node

gutworth noreply at buildbot.pypy.org
Mon Mar 12 17:14:28 CET 2012


Author: Benjamin Peterson <benjamin at python.org>
Branch: py3k
Changeset: r53321:0d0286e32631
Date: 2012-03-12 09:14 -0700
http://bitbucket.org/pypy/pypy/changeset/0d0286e32631/

Log:	add ast.Bytes node

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
@@ -1611,6 +1611,26 @@
             pass
 
 
+class Bytes(expr):
+
+    def __init__(self, s, lineno, col_offset):
+        self.s = s
+        expr.__init__(self, lineno, col_offset)
+        self.initialization_state = 7
+
+    def walkabout(self, visitor):
+        visitor.visit_Bytes(self)
+
+    def mutate_over(self, visitor):
+        return visitor.visit_Bytes(self)
+
+    def sync_app_attrs(self, space):
+        if (self.initialization_state & ~0) ^ 7:
+            self.missing_field(space, ['lineno', 'col_offset', 's'], 'Bytes')
+        else:
+            pass
+
+
 class Attribute(expr):
 
     def __init__(self, value, attr, ctx, lineno, col_offset):
@@ -2481,6 +2501,8 @@
         return self.default_visitor(node)
     def visit_Str(self, node):
         return self.default_visitor(node)
+    def visit_Bytes(self, node):
+        return self.default_visitor(node)
     def visit_Attribute(self, node):
         return self.default_visitor(node)
     def visit_Subscript(self, node):
@@ -2690,6 +2712,9 @@
     def visit_Str(self, node):
         pass
 
+    def visit_Bytes(self, node):
+        pass
+
     def visit_Attribute(self, node):
         node.value.walkabout(self)
 
@@ -5664,6 +5689,51 @@
     __init__=interp2app(Str_init),
 )
 
+def Bytes_get_s(space, w_self):
+    if w_self.w_dict is not None:
+        w_obj = w_self.getdictvalue(space, 's')
+        if w_obj is not None:
+            return w_obj
+    if not w_self.initialization_state & 4:
+        typename = space.type(w_self).getname(space)
+        raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 's')
+    return w_self.s
+
+def Bytes_set_s(space, w_self, w_new_value):
+    try:
+        w_self.s = w_new_value
+    except OperationError, e:
+        if not e.match(space, space.w_TypeError):
+            raise
+        w_self.setdictvalue(space, 's', w_new_value)
+        return
+    w_self.deldictvalue(space, 's')
+    w_self.initialization_state |= 4
+
+_Bytes_field_unroller = unrolling_iterable(['s'])
+def Bytes_init(space, w_self, __args__):
+    w_self = space.descr_self_interp_w(Bytes, w_self)
+    args_w, kwargs_w = __args__.unpack()
+    if args_w:
+        if len(args_w) != 1:
+            w_err = space.wrap("Bytes constructor takes either 0 or 1 positional argument")
+            raise OperationError(space.w_TypeError, w_err)
+        i = 0
+        for field in _Bytes_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)
+
+Bytes.typedef = typedef.TypeDef("Bytes",
+    expr.typedef,
+    __module__='_ast',
+    _fields=_FieldsWrapper(['s']),
+    s=typedef.GetSetProperty(Bytes_get_s, Bytes_set_s, cls=Bytes),
+    __new__=interp2app(get_AST_new(Bytes)),
+    __init__=interp2app(Bytes_init),
+)
+
 def Attribute_get_value(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'value')
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
@@ -1097,7 +1097,9 @@
                     self.error("cannot mix bytes and nonbytes literals",
                               atom_node)
                 # UnicodeError in literal: turn into SyntaxError
-            return ast.Str(w_string, atom_node.lineno, atom_node.column)
+            strdata = space.isinstance_w(w_string, space.w_unicode)
+            node = ast.Str if strdata else ast.Bytes
+            return node(w_string, atom_node.lineno, atom_node.column)
         elif first_child_type == tokens.NUMBER:
             num_value = self.parse_number(first_child.value)
             return ast.Num(num_value, atom_node.lineno, atom_node.column)
diff --git a/pypy/interpreter/astcompiler/asthelpers.py b/pypy/interpreter/astcompiler/asthelpers.py
--- a/pypy/interpreter/astcompiler/asthelpers.py
+++ b/pypy/interpreter/astcompiler/asthelpers.py
@@ -124,7 +124,7 @@
     _description = "dict comprehension"
 
 
-class __extend__(ast.Dict, ast.Set, ast.Str, ast.Num, ast.Const):
+class __extend__(ast.Dict, ast.Set, ast.Str, ast.Bytes, ast.Num, ast.Const):
 
     _description = "literal"
 
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -769,6 +769,10 @@
         self.update_position(string.lineno)
         self.load_const(string.s)
 
+    def visit_Bytes(self, b):
+        self.update_position(b.lineno)
+        self.load_const(b.s)
+
     def visit_Const(self, const):
         self.update_position(const.lineno)
         space = self.space
diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py
--- a/pypy/interpreter/astcompiler/test/test_astbuilder.py
+++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py
@@ -1051,7 +1051,7 @@
         assert isinstance(s, ast.Str)
         assert space.eq_w(s.s, space.wrap("hi implicitly extra"))
         s = self.get_first_expr("b'hi' b' implicitly' b' extra'")
-        assert isinstance(s, ast.Str)
+        assert isinstance(s, ast.Bytes)
         assert space.eq_w(s.s, space.wrapbytes("hi implicitly extra"))
         raises(SyntaxError, self.get_first_expr, "b'hello' 'world'")
         sentence = u"Die M&#228;nner &#228;rgen sich!"
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
@@ -68,6 +68,7 @@
 			 expr? starargs, expr? kwargs)
 	     | Num(object n) -- a number as a PyObject.
 	     | Str(string s) -- need to specify raw, unicode, etc?
+             | Bytes(string s)
 	     -- other literals? bools?
 
 	     -- the following expression can appear in assignment context


More information about the pypy-commit mailing list