Skip to content

Commit 6778028

Browse files
committed
[GR-22297] Add more support for _struct in general.
PullRequest: graalpython/998
2 parents 3612c85 + 3e8b442 commit 6778028

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed

graalpython/com.oracle.graal.python.test/src/graalpytest.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ def assertGreater(self, expected, actual, msg=None):
229229
msg = "Expected '%r' to be greater than '%r'" % (actual, expected)
230230
assert expected > actual, msg
231231

232+
def assertGreaterEqual(self, expected, actual, msg=None):
233+
if not msg:
234+
msg = "Expected '%r' to be greater than or equal to '%r'" % (actual, expected)
235+
assert expected >= actual, msg
236+
232237
def assertSequenceEqual(self, expected, actual, msg=None):
233238
if not msg:
234239
msg = "Expected '%r' to be equal to '%r'" % (actual, expected)
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
import sys
40+
import struct
41+
42+
ISBIGENDIAN = sys.byteorder == "big"
43+
44+
45+
def test_new_features():
46+
tests = [
47+
('c', b'a', b'a', b'a', 0),
48+
('xc', b'a', b'\0a', b'\0a', 0),
49+
('cx', b'a', b'a\0', b'a\0', 0),
50+
('s', b'a', b'a', b'a', 0),
51+
('0s', b'helloworld', b'', b'', 1),
52+
('1s', b'helloworld', b'h', b'h', 1),
53+
('9s', b'helloworld', b'helloworl', b'helloworl', 1),
54+
('10s', b'helloworld', b'helloworld', b'helloworld', 0),
55+
('11s', b'helloworld', b'helloworld\0', b'helloworld\0', 1),
56+
('20s', b'helloworld', b'helloworld'+10*b'\0', b'helloworld'+10*b'\0', 1),
57+
('b', 7, b'\7', b'\7', 0),
58+
('b', -7, b'\371', b'\371', 0),
59+
('B', 7, b'\7', b'\7', 0),
60+
('B', 249, b'\371', b'\371', 0),
61+
('h', 700, b'\002\274', b'\274\002', 0),
62+
('h', -700, b'\375D', b'D\375', 0),
63+
('H', 700, b'\002\274', b'\274\002', 0),
64+
('H', 0x10000-700, b'\375D', b'D\375', 0),
65+
('i', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
66+
('i', -70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
67+
('I', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
68+
('I', 0x100000000-70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
69+
('l', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
70+
('l', -70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
71+
('L', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
72+
('L', 0x100000000-70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
73+
('f', 2.0, b'@\000\000\000', b'\000\000\000@', 0),
74+
('d', 2.0, b'@\000\000\000\000\000\000\000',
75+
b'\000\000\000\000\000\000\000@', 0),
76+
('f', -2.0, b'\300\000\000\000', b'\000\000\000\300', 0),
77+
('d', -2.0, b'\300\000\000\000\000\000\000\000',
78+
b'\000\000\000\000\000\000\000\300', 0),
79+
('?', 0, b'\0', b'\0', 0),
80+
('?', 3, b'\1', b'\1', 1),
81+
('?', True, b'\1', b'\1', 0),
82+
('?', [], b'\0', b'\0', 1),
83+
('?', (1,), b'\1', b'\1', 1),
84+
]
85+
86+
for fmt, arg, big, lil, asy in tests:
87+
for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
88+
('='+fmt, ISBIGENDIAN and big or lil)]:
89+
res = struct.pack(xfmt, arg)
90+
assert res == exp
91+
assert struct.calcsize(xfmt) == len(res)
92+
rev = struct.unpack(xfmt, res)[0]
93+
if rev != arg:
94+
assert asy
95+
96+
97+
def test_pack_unpack():
98+
# numbers
99+
cases = [
100+
((60, 61, 62, 12365, 3454353, 75, 76), '3BHI2B'),
101+
((9223372036854775806,), 'Q'),
102+
]
103+
104+
alignment = ['>', '<', '!', '=', '@']
105+
106+
for vals, fmt in cases:
107+
for align in alignment:
108+
_fmt = align + fmt
109+
result = struct.pack(_fmt, *vals)
110+
assert vals == struct.unpack(_fmt, result)
111+
assert struct.calcsize(_fmt) == len(result), "calcsize('{}')={} != len({})={}".format(
112+
_fmt, struct.calcsize(_fmt), result, len(result))
113+
114+
# bytes / strings
115+
long_str = b'hello-graal-python-hello-graal-python-hello-graal-python-hello-graal-python-hello-graal-python-hello-' \
116+
b'graal-python-hello-graal-python-hello-graal-python-hello-graal-python-hello-graal-python-hello-graal-' \
117+
b'python-hello-graal-python-hello-graal-python-hello-graal-p'
118+
119+
pascal_str = b'\xffhello-graal-python-hello-graal-python-hello-graal-python-hello-graal-python-hello-graal-python-' \
120+
b'hello-graal-python-hello-graal-python-hello-graal-python-hello-graal-python-hello-graal-python-' \
121+
b'hello-graal-python-hello-graal-python-hello-graal-python-hello-graal-'
122+
123+
for align in alignment:
124+
for (res, fmt) in [(long_str, 's'), (pascal_str, 'p')]:
125+
_fmt = align + '260' + fmt
126+
assert struct.calcsize(_fmt) == 260
127+
assert struct.pack(_fmt, b'hello-graal-python-'*20) == res
128+
129+
# floats
130+
cases = [
131+
# ('f', 1.12123123, 1.121231198310852),
132+
# ('d', 1.12123123, 1.12123123),
133+
('e', 1.12345678912345, 1.123046875),
134+
('e', -145.12345678912345, -145.125),
135+
]
136+
137+
for align in alignment:
138+
for (fmt, val, res) in cases:
139+
_fmt = align + fmt
140+
_bytes = struct.pack(_fmt, val)
141+
_res = struct.unpack(_fmt, _bytes)[0]
142+
assert _res == res, "({}), {} != {}".format(_fmt, _res, res)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ public enum PythonBuiltinClassType implements LazyPythonClass {
122122
PLZMACompressor("LZMACompressor", "_lzma"),
123123
PLZMADecompressor("LZMADecompressor", "_lzma"),
124124
LsprofProfiler("Profiler", "_lsprof"),
125+
PStruct("Struct", "_struct"),
125126

126127
// Errors and exceptions:
127128

0 commit comments

Comments
 (0)