[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änner ä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