[Jython-checkins] jython: Allow struct unpack and unpack_from bytearray and buffer (GH-121)
jeff.allen
jython-checkins at python.org
Tue Apr 9 01:15:01 EDT 2019
https://hg.python.org/jython/rev/66091cb89839
changeset: 8235:66091cb89839
user: Ray Ferguson <github.public at devendortech.com>
date: Mon Apr 08 22:22:35 2019 +0100
summary:
Allow struct unpack and unpack_from bytearray and buffer (GH-121)
struct module from CPython 2.7.6 supports unpack from a bytearray or buffer.
This patch adds support for unpack() and unpack_from() for the additional types
and adds test cases based on tests/test_struct.py which is not run in regrtest
by default.
Modified by Jeff from https://github.com/jythontools/jython/pull/121
files:
Lib/test/test_struct_jy.py | 158 +++++++++++++++
NEWS | 1 +
src/org/python/core/Py2kBuffer.java | 7 +-
src/org/python/core/PyByteArray.java | 11 +-
src/org/python/modules/struct.java | 27 ++
5 files changed, 200 insertions(+), 4 deletions(-)
diff --git a/Lib/test/test_struct_jy.py b/Lib/test/test_struct_jy.py
new file mode 100644
--- /dev/null
+++ b/Lib/test/test_struct_jy.py
@@ -0,0 +1,158 @@
+import unittest
+from test import test_support
+import struct
+
+import sys
+ISBIGENDIAN = sys.byteorder == "big"
+
+class StructTests(unittest.TestCase): # (format, argument, big-endian result, little-endian result, asymmetric)
+ _tests = [
+ ('c', 'a', 'a', 'a', 0),
+ ('xc', 'a', '\0a', '\0a', 0),
+ ('cx', 'a', 'a\0', 'a\0', 0),
+ ('s', 'a', 'a', 'a', 0),
+ ('0s', 'helloworld', '', '', 1),
+ ('1s', 'helloworld', 'h', 'h', 1),
+ ('9s', 'helloworld', 'helloworl', 'helloworl', 1),
+ ('10s', 'helloworld', 'helloworld', 'helloworld', 0),
+ ('11s', 'helloworld', 'helloworld\0', 'helloworld\0', 1),
+ ('20s', 'helloworld', 'helloworld'+10*'\0', 'helloworld'+10*'\0', 1),
+ ('b', 7, '\7', '\7', 0),
+ ('b', -7, '\371', '\371', 0),
+ ('B', 7, '\7', '\7', 0),
+ ('B', 249, '\371', '\371', 0),
+ ('h', 700, '\002\274', '\274\002', 0),
+ ('h', -700, '\375D', 'D\375', 0),
+ ('H', 700, '\002\274', '\274\002', 0),
+ ('H', 0x10000-700, '\375D', 'D\375', 0),
+ ('i', 70000000, '\004,\035\200', '\200\035,\004', 0),
+ ('i', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
+ ('I', 70000000L, '\004,\035\200', '\200\035,\004', 0),
+ ('I', 0x100000000L-70000000, '\373\323\342\200', '\200\342\323\373', 0),
+ ('l', 70000000, '\004,\035\200', '\200\035,\004', 0),
+ ('l', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
+ ('L', 70000000L, '\004,\035\200', '\200\035,\004', 0),
+ ('L', 0x100000000L-70000000, '\373\323\342\200', '\200\342\323\373', 0),
+ ('f', 2.0, '@\000\000\000', '\000\000\000@', 0),
+ ('d', 2.0, '@\000\000\000\000\000\000\000',
+ '\000\000\000\000\000\000\000@', 0),
+ ('f', -2.0, '\300\000\000\000', '\000\000\000\300', 0),
+ ('d', -2.0, '\300\000\000\000\000\000\000\000',
+ '\000\000\000\000\000\000\000\300', 0),
+ ]
+
+ def test_struct(self):
+ for fmt, arg, big, lil, asy in self._tests:
+ for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
+ ('='+fmt, ISBIGENDIAN and big or lil)]:
+ res = struct.pack(xfmt, arg)
+ self.assertEqual(res,exp,msg="pack(%r, %r) -> %r # expected %r" %
+ (fmt, arg, res, exp))
+ n=struct.calcsize(xfmt)
+ self.assertEqual(n, len(res),msg="calcsize(%r) -> %d # expected %d" %
+ (xfmt, n, len(res)))
+ rev = struct.unpack(xfmt, res)[0]
+ if asy:
+ self.assertNotEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, exp))
+ else:
+ self.assertEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, arg))
+
+ def test_struct_unpack_bytearray(self):
+ for fmt, arg, big, lil, asy in self._tests:
+ for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
+ ('='+fmt, ISBIGENDIAN and big or lil)]:
+ res = struct.pack(xfmt, arg)
+ self.assertEqual(res,exp,msg="pack(%r, %r) -> %r # expected %r" %
+ (fmt, arg, res, exp))
+ n=struct.calcsize(xfmt)
+ self.assertEqual(n, len(res),msg="calcsize(%r) -> %d # expected %d" %
+ (xfmt, n, len(res)))
+ rev = struct.unpack(xfmt, bytearray(res))[0]
+ if asy:
+ self.assertNotEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, exp))
+ else:
+ self.assertEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, arg))
+
+ def test_struct_unpack_buffer(self):
+ for fmt, arg, big, lil, asy in self._tests:
+ for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
+ ('='+fmt, ISBIGENDIAN and big or lil)]:
+ res = struct.pack(xfmt, arg)
+ self.assertEqual(res,exp,msg="pack(%r, %r) -> %r # expected %r" %
+ (fmt, arg, res, exp))
+ n=struct.calcsize(xfmt)
+ self.assertEqual(n, len(res),msg="calcsize(%r) -> %d # expected %d" %
+ (xfmt, n, len(res)))
+ rev = struct.unpack(xfmt, buffer(res))[0]
+ if asy:
+ self.assertNotEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, exp))
+ else:
+ self.assertEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, arg))
+ def test_struct_unpack_from(self):
+ for fmt, arg, big, lil, asy in self._tests:
+ for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
+ ('='+fmt, ISBIGENDIAN and big or lil)]:
+ res = struct.pack(xfmt, arg)
+ self.assertEqual(res,exp,msg="pack(%r, %r) -> %r # expected %r" %
+ (fmt, arg, res, exp))
+ n=struct.calcsize(xfmt)
+ self.assertEqual(n, len(res),msg="calcsize(%r) -> %d # expected %d" %
+ (xfmt, n, len(res)))
+ rev = struct.unpack_from(xfmt, res)[0]
+ if asy:
+ self.assertNotEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, exp))
+ else:
+ self.assertEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, arg))
+
+ def test_struct_unpack_from_bytearray(self):
+ for fmt, arg, big, lil, asy in self._tests:
+ for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
+ ('='+fmt, ISBIGENDIAN and big or lil)]:
+ res = struct.pack(xfmt, arg)
+ self.assertEqual(res,exp,msg="pack(%r, %r) -> %r # expected %r" %
+ (fmt, arg, res, exp))
+ n=struct.calcsize(xfmt)
+ self.assertEqual(n, len(res),msg="calcsize(%r) -> %d # expected %d" %
+ (xfmt, n, len(res)))
+ rev = struct.unpack_from(xfmt, bytearray(res))[0]
+ if asy:
+ self.assertNotEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, exp))
+ else:
+ self.assertEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, arg))
+
+ def test_struct_unpack_from_buffer(self):
+ for fmt, arg, big, lil, asy in self._tests:
+ for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
+ ('='+fmt, ISBIGENDIAN and big or lil)]:
+ res = struct.pack(xfmt, arg)
+ self.assertEqual(res,exp,msg="pack(%r, %r) -> %r # expected %r" %
+ (fmt, arg, res, exp))
+ n=struct.calcsize(xfmt)
+ self.assertEqual(n, len(res),msg="calcsize(%r) -> %d # expected %d" %
+ (xfmt, n, len(res)))
+ rev = struct.unpack_from(xfmt, buffer(res))[0]
+ if asy:
+ self.assertNotEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, exp))
+ else:
+ self.assertEqual(arg,rev,msg="unpack(%r, %r) -> (%r,) # expected (%r,)" %
+ (fmt, res, rev, arg))
+
+
+
+
+def test_main():
+ test_support.run_unittest(__name__)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/NEWS b/NEWS
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@
Development tip
Bugs fixed
+ - [ GH-121 ] Allow struct unpack and unpack_from bytearray and buffer
- [ 2635 ] AST.lineno ignored by compile
- [ 2744 ] Support buffer type in marshal.dump(s)
- [ 2077 ] marshal doesn't raise error when fed unmarshalable object
diff --git a/src/org/python/core/Py2kBuffer.java b/src/org/python/core/Py2kBuffer.java
--- a/src/org/python/core/Py2kBuffer.java
+++ b/src/org/python/core/Py2kBuffer.java
@@ -203,8 +203,13 @@
@ExposedMethod(doc = BuiltinDocs.buffer___str___doc)
final PyString buffer___str__() {
+ return new PyString(toString());
+ }
+
+ @Override
+ public String toString() {
try (PyBuffer buf = getBuffer()) {
- return new PyString(buf.toString());
+ return buf.toString();
}
}
diff --git a/src/org/python/core/PyByteArray.java b/src/org/python/core/PyByteArray.java
--- a/src/org/python/core/PyByteArray.java
+++ b/src/org/python/core/PyByteArray.java
@@ -2014,12 +2014,17 @@
*/
@Override
public String toString() {
- return bytearray_repr();
+ return this.asString();
+ }
+
+ @Override
+ public PyString __repr__(){
+ return bytearray___repr__();
}
@ExposedMethod(names = {"__repr__"}, doc = BuiltinDocs.bytearray___repr___doc)
- final synchronized String bytearray_repr() {
- return basebytes_repr("bytearray(b", ")");
+ final synchronized PyString bytearray___repr__() {
+ return new PyString(basebytes_repr("bytearray(b", ")"));
}
/**
diff --git a/src/org/python/modules/struct.java b/src/org/python/modules/struct.java
--- a/src/org/python/modules/struct.java
+++ b/src/org/python/modules/struct.java
@@ -21,6 +21,8 @@
import java.math.BigInteger;
import org.python.core.ClassDictInit;
import org.python.core.PyArray;
+import org.python.core.PyByteArray;
+import org.python.core.Py2kBuffer;
/**
* This module performs conversions between Python values and C
@@ -1097,6 +1099,31 @@
return unpack(f, size, format, new ByteStream(string));
}
+ public static PyTuple unpack(String format, Py2kBuffer buffer){
+ return unpack(format, buffer.toString());
+ }
+
+ public static PyTuple unpack(String format, PyByteArray bytearray) {
+ /* bytearray is added in 2.7.7 */
+ return unpack(format, bytearray.toString());
+ }
+
+ public static PyTuple unpack_from(String format, Py2kBuffer buffer) {
+ return unpack_from(format, buffer.toString(), 0);
+ }
+
+ public static PyTuple unpack_from(String format, PyByteArray bytearray) {
+ return unpack_from(format, bytearray.toString(), 0);
+ }
+
+ public static PyTuple unpack_from(String format, Py2kBuffer buffer, int offset) {
+ return unpack_from(format, buffer.toString(), offset);
+ }
+
+ public static PyTuple unpack_from(String format, PyByteArray bytearray, int offset) {
+ return unpack_from(format, bytearray.toString(), offset);
+ }
+
public static PyTuple unpack_from(String format, String string) {
return unpack_from(format, string, 0);
}
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list