Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit