summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorThomas Wouters <thomas@python.org>2007-02-23 19:56:57 (GMT)
committerThomas Wouters <thomas@python.org>2007-02-23 19:56:57 (GMT)
commit00e41defe8801ef37548fb60abacb3be13156d2a (patch)
tree863d072e568fee2b8f4959016b5954de457c7f4c /Lib
parentcf297e46b85257396560774e5492e9d71a40f32e (diff)
downloadcpython-00e41defe8801ef37548fb60abacb3be13156d2a.zip
cpython-00e41defe8801ef37548fb60abacb3be13156d2a.tar.gz
cpython-00e41defe8801ef37548fb60abacb3be13156d2a.tar.bz2
Bytes literal.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/compiler/ast.py14
-rw-r--r--Lib/compiler/pyassem.py1
-rw-r--r--Lib/compiler/pycodegen.py4
-rw-r--r--Lib/compiler/transformer.py6
-rw-r--r--Lib/opcode.py1
-rw-r--r--Lib/test/test_bytes.py14
-rw-r--r--Lib/test/test_compiler.py24
7 files changed, 61 insertions, 3 deletions
diff --git a/Lib/compiler/ast.py b/Lib/compiler/ast.py
index bc283c0..4794d66 100644
--- a/Lib/compiler/ast.py
+++ b/Lib/compiler/ast.py
@@ -267,6 +267,20 @@ class Break(Node):
def __repr__(self):
return "Break()"
+class Bytes(Node):
+ def __init__(self, value, lineno=None):
+ self.value = value
+ self.lineno = lineno
+
+ def getChildren(self):
+ return self.value,
+
+ def getChildNodes(self):
+ return ()
+
+ def __repr__(self):
+ return "Bytes(%s)" % (repr(self.value),)
+
class CallFunc(Node):
def __init__(self, node, args, star_args = None, dstar_args = None, lineno=None):
self.node = node
diff --git a/Lib/compiler/pyassem.py b/Lib/compiler/pyassem.py
index cac899d..f665c54 100644
--- a/Lib/compiler/pyassem.py
+++ b/Lib/compiler/pyassem.py
@@ -792,6 +792,7 @@ class StackDepthTracker:
'DELETE_ATTR': -1,
'STORE_GLOBAL': -1,
'BUILD_MAP': 1,
+ 'MAKE_BYTES': 0,
'COMPARE_OP': -1,
'STORE_FAST': -1,
'IMPORT_STAR': -1,
diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py
index 8db4e0d..83fbc17 100644
--- a/Lib/compiler/pycodegen.py
+++ b/Lib/compiler/pycodegen.py
@@ -930,6 +930,10 @@ class CodeGenerator:
def visitConst(self, node):
self.emit('LOAD_CONST', node.value)
+
+ def visitBytes(self, node):
+ self.emit('LOAD_CONST', node.value)
+ self.emit('MAKE_BYTES')
def visitKeyword(self, node):
self.emit('LOAD_CONST', node.name)
diff --git a/Lib/compiler/transformer.py b/Lib/compiler/transformer.py
index 5f2face..79b702c 100644
--- a/Lib/compiler/transformer.py
+++ b/Lib/compiler/transformer.py
@@ -745,9 +745,11 @@ class Transformer:
return eval(lit)
def atom_string(self, nodelist):
- k = ''
- for node in nodelist:
+ k = self.decode_literal(nodelist[0][1])
+ for node in nodelist[1:]:
k += self.decode_literal(node[1])
+ if isinstance(k, bytes):
+ return Bytes(str(k), lineno=nodelist[0][2])
return Const(k, lineno=nodelist[0][2])
def atom_ellipsis(self, nodelist):
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 1e15582..69982f2 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -111,6 +111,7 @@ def_op('WITH_CLEANUP', 81)
def_op('LOAD_LOCALS', 82)
def_op('RETURN_VALUE', 83)
def_op('IMPORT_STAR', 84)
+def_op('MAKE_BYTES', 85)
def_op('YIELD_VALUE', 86)
def_op('POP_BLOCK', 87)
def_op('END_FINALLY', 88)
diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py
index 997122b..4dee01b 100644
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -403,7 +403,19 @@ class BytesTest(unittest.TestCase):
self.assertEqual(bytes.join(tuple(lst)), bytes("abc"))
self.assertEqual(bytes.join(iter(lst)), bytes("abc"))
# XXX more...
-
+
+ def test_literal(self):
+ tests = [
+ (b"Wonderful spam", u"Wonderful spam"),
+ (br"Wonderful spam too", u"Wonderful spam too"),
+ (b"\xaa\x00\000\200", u"\xaa\x00\000\200"),
+ (br"\xaa\x00\000\200", ur"\xaa\x00\000\200"),
+ ]
+ for b, s in tests:
+ self.assertEqual(b, bytes(s, 'latin-1'))
+ for c in range(128, 256):
+ self.assertRaises(SyntaxError, eval,
+ 'b"%s"' % chr(c))
# Optimizations:
# __iter__? (optimization)
diff --git a/Lib/test/test_compiler.py b/Lib/test/test_compiler.py
index ab9a660..bbd7511 100644
--- a/Lib/test/test_compiler.py
+++ b/Lib/test/test_compiler.py
@@ -187,6 +187,30 @@ class CompilerTest(unittest.TestCase):
exec(c, dct)
self.assertEquals(dct.get('result'), 1)
+ def testBytesLiteral(self):
+ c = compiler.compile("b'foo'", '<string>', 'eval')
+ b = eval(c)
+
+ c = compiler.compile('def f(b=b"foo"):\n'
+ ' b[0] += 1\n'
+ ' return b\n'
+ 'f(); f(); result = f()\n',
+ '<string>',
+ 'exec')
+ dct = {}
+ exec(c, dct)
+ self.assertEquals(dct.get('result'), b"ioo")
+
+ c = compiler.compile('def f():\n'
+ ' b = b"foo"\n'
+ ' b[0] += 1\n'
+ ' return b\n'
+ 'f(); f(); result = f()\n',
+ '<string>',
+ 'exec')
+ dct = {}
+ exec(c, dct)
+ self.assertEquals(dct.get('result'), b"goo")
NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard)