Author: Armin Rigo <[email protected]>
Branch: py3.5-newtext
Changeset: r90148:2d5c0f6653b6
Date: 2017-02-15 13:33 +0100
http://bitbucket.org/pypy/pypy/changeset/2d5c0f6653b6/
Log: CPython 3.x accepts both bytes or unicodes as the format
specification of the struct module
diff --git a/pypy/module/struct/interp_struct.py
b/pypy/module/struct/interp_struct.py
--- a/pypy/module/struct/interp_struct.py
+++ b/pypy/module/struct/interp_struct.py
@@ -32,8 +32,15 @@
return fmtiter.totalsize
-@unwrap_spec(format='text')
-def calcsize(space, format):
+def text_or_bytes_w(space, w_input):
+ # why does CPython do this??
+ if space.isinstance_w(w_input, space.w_bytes):
+ return space.bytes_w(w_input)
+ else:
+ return space.text_w(w_input)
+
+def calcsize(space, w_format):
+ format = text_or_bytes_w(space, w_format)
return space.newint(_calcsize(space, format))
@@ -52,14 +59,21 @@
return fmtiter.result.build()
-@unwrap_spec(format='text')
-def pack(space, format, args_w):
+def pack(space, w_format, args_w):
+ format = text_or_bytes_w(space, w_format)
+ return do_pack(space, format, args_w)
+
+def do_pack(space, format, args_w):
return space.newbytes(_pack(space, format, args_w))
+@unwrap_spec(offset=int)
+def pack_into(space, w_format, w_buffer, offset, args_w):
+ format = text_or_bytes_w(space, w_format)
+ return do_pack_into(space, format, w_buffer, offset, args_w)
+
# XXX inefficient
-@unwrap_spec(format='text', offset=int)
-def pack_into(space, format, w_buffer, offset, args_w):
+def do_pack_into(space, format, w_buffer, offset, args_w):
res = _pack(space, format, args_w)
buf = space.getarg_w('w*', w_buffer)
if offset < 0:
@@ -83,14 +97,21 @@
return space.newtuple(fmtiter.result_w[:])
-@unwrap_spec(format='text')
-def unpack(space, format, w_str):
+def unpack(space, w_format, w_str):
+ format = text_or_bytes_w(space, w_format)
+ return do_unpack(space, format, w_str)
+
+def do_unpack(space, format, w_str):
buf = space.getarg_w('s*', w_str)
return _unpack(space, format, buf)
-@unwrap_spec(format='text', offset=int)
-def unpack_from(space, format, w_buffer, offset=0):
+@unwrap_spec(offset=int)
+def unpack_from(space, w_format, w_buffer, offset=0):
+ format = text_or_bytes_w(space, w_format)
+ return do_unpack_from(space, format, w_buffer, offset)
+
+def do_unpack_from(space, format, w_buffer, offset=0):
size = _calcsize(space, format)
buf = space.buffer_w(w_buffer, space.BUF_SIMPLE)
if offset < 0:
@@ -146,25 +167,25 @@
self.format = format
self.size = _calcsize(space, format)
- @unwrap_spec(format='text')
- def descr__new__(space, w_subtype, format):
+ def descr__new__(space, w_subtype, w_format):
+ format = text_or_bytes_w(space, w_format)
self = space.allocate_instance(W_Struct, w_subtype)
W_Struct.__init__(self, space, format)
return self
def descr_pack(self, space, args_w):
- return pack(space, jit.promote_string(self.format), args_w)
+ return do_pack(space, jit.promote_string(self.format), args_w)
@unwrap_spec(offset=int)
def descr_pack_into(self, space, w_buffer, offset, args_w):
- return pack_into(space, jit.promote_string(self.format), w_buffer,
offset, args_w)
+ return do_pack_into(space, jit.promote_string(self.format), w_buffer,
offset, args_w)
def descr_unpack(self, space, w_str):
- return unpack(space, jit.promote_string(self.format), w_str)
+ return do_unpack(space, jit.promote_string(self.format), w_str)
@unwrap_spec(offset=int)
def descr_unpack_from(self, space, w_buffer, offset=0):
- return unpack_from(space, jit.promote_string(self.format), w_buffer,
offset)
+ return do_unpack_from(space, jit.promote_string(self.format),
w_buffer, offset)
def descr_iter_unpack(self, space, w_buffer):
return W_UnpackIter(space, self, w_buffer)
diff --git a/pypy/module/struct/test/test_struct.py
b/pypy/module/struct/test/test_struct.py
--- a/pypy/module/struct/test/test_struct.py
+++ b/pypy/module/struct/test/test_struct.py
@@ -530,6 +530,16 @@
format = byteorder+code
t = run_not_int_test(format)
+ def test_struct_with_bytes_as_format_string(self):
+ # why??
+ assert self.struct.calcsize(b'!ii') == 8
+ b = memoryview(bytearray(8))
+ self.struct.iter_unpack(b'ii', b)
+ self.struct.pack(b"ii", 45, 56)
+ self.struct.pack_into(b"ii", b, 0, 45, 56)
+ self.struct.unpack(b"ii", b"X" * 8)
+ assert self.struct.unpack_from(b"ii", b) == (45, 56)
+
class AppTestStructBuffer(object):
spaceconfig = dict(usemodules=['struct', '__pypy__'])
@@ -561,6 +571,7 @@
assert self.struct.unpack_from("ii", b, 2) == (17, 42)
b[:sz] = self.struct.pack("ii", 18, 43)
assert self.struct.unpack_from("ii", b) == (18, 43)
+ self.struct.Struct(b"ii")
class AppTestFastPath(object):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit