Skip to content

Commit bff02ce

Browse files
committed
[GR-13976] Support marshal.dumps and marshal.loads for PCode
PullRequest: graalpython/411
2 parents 2ffddd0 + 43f4686 commit bff02ce

File tree

3 files changed

+771
-7
lines changed

3 files changed

+771
-7
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Copyright (c) 2019, Oracle and/or its affiliates.
2+
# Copyright (C) 1996-2017 Python Software Foundation
3+
#
4+
# Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
5+
6+
import unittest
7+
import marshal
8+
import array
9+
import types
10+
import sys
11+
12+
class BaseMarshalUnmarshal:
13+
def helper(self, sample, *extra):
14+
new = marshal.loads(marshal.dumps(sample, *extra))
15+
self.assertEqual(sample, new)
16+
17+
class IntTest (unittest.TestCase, BaseMarshalUnmarshal):
18+
19+
def test_ints(self):
20+
# Test a range of Python ints larger than the machine word size.
21+
n = sys.maxsize ** 20
22+
while n:
23+
for expected in (-n, n):
24+
self.helper(expected)
25+
n = n >> 1
26+
27+
def test_int64(self):
28+
# Simulate int marshaling with TYPE_INT64.
29+
maxint64 = (1 << 63) - 1
30+
minint64 = -maxint64-1
31+
for base in maxint64, minint64, -maxint64, -(minint64 >> 1):
32+
while base:
33+
self.helper(base)
34+
if base == -1: # a fixed-point for shifting right 1
35+
base = 0
36+
else:
37+
base >>= 1
38+
39+
self.helper(0x1032547698badcfe)
40+
self.helper(-0x1032547698badcff)
41+
self.helper(0x7f6e5d4c3b2a1908)
42+
self.helper(-0x7f6e5d4c3b2a1909)
43+
44+
def test_bool(self):
45+
for b in (True, False):
46+
self.helper(b)
47+
48+
class FloatTest(unittest.TestCase, BaseMarshalUnmarshal):
49+
def test_floats(self):
50+
# Test a few floats
51+
small = 1e-25
52+
n = sys.maxsize * 3.7e250
53+
while n > small:
54+
for expected in (-n, n):
55+
self.helper(float(expected))
56+
n /= 123.4567
57+
58+
f = 0.0
59+
s = marshal.dumps(f, 2)
60+
got = marshal.loads(s)
61+
self.assertEqual(f, got)
62+
# and with version <= 1 (floats marshalled differently then)
63+
s = marshal.dumps(f, 1)
64+
got = marshal.loads(s)
65+
self.assertEqual(f, got)
66+
67+
n = sys.maxsize * 3.7e-250
68+
while n < small:
69+
for expected in (-n, n):
70+
f = float(expected)
71+
self.helper(f)
72+
self.helper(f, 1)
73+
n *= 123.4567
74+
75+
class StringTest(unittest.TestCase, BaseMarshalUnmarshal):
76+
def test_unicode(self):
77+
for s in ["", "Andr\xe8 Previn", "abc", " "*10000]:
78+
self.helper(marshal.loads(marshal.dumps(s)))
79+
80+
def test_string(self):
81+
for s in ["", "Andr\xe8 Previn", "abc", " "*10000]:
82+
self.helper(s)
83+
84+
def test_bytes(self):
85+
for s in [b"", b"Andr\xe8 Previn", b"abc", b" "*10000]:
86+
self.helper(s)
87+
88+
class ExceptionTest(unittest.TestCase):
89+
90+
def test_exceptions(self):
91+
new = marshal.loads(marshal.dumps(StopIteration))
92+
self.assertEqual(StopIteration, new)
93+
94+
class CodeTest(unittest.TestCase):
95+
96+
# TODO, currently the object created from serialized data is not equal.
97+
#def test_code(self):
98+
# co = ExceptionTest.test_exceptions.__code__
99+
# new = marshal.loads(marshal.dumps(co))
100+
# self.assertEqual(co, new)
101+
102+
def test_many_codeobjects(self):
103+
# Issue2957: bad recursion count on code objects
104+
count = 5000 # more than MAX_MARSHAL_STACK_DEPTH
105+
codes = (ExceptionTest.test_exceptions.__code__,) * count
106+
marshal.loads(marshal.dumps(codes))
107+
108+
def test_different_filenames(self):
109+
co1 = compile("x", "f1", "exec")
110+
co2 = compile("y", "f2", "exec")
111+
co1, co2 = marshal.loads(marshal.dumps((co1, co2)))
112+
self.assertEqual(co1.co_filename, "f1")
113+
self.assertEqual(co2.co_filename, "f2")
114+
115+
def test_same_filename_used(self):
116+
s = """def f(): pass\ndef g(): pass"""
117+
co = compile(s, "myfile", "exec")
118+
co = marshal.loads(marshal.dumps(co))
119+
for obj in co.co_consts:
120+
if isinstance(obj, types.CodeType):
121+
self.assertIs(co.co_filename, obj.co_filename)
122+
123+
class ContainerTest(unittest.TestCase, BaseMarshalUnmarshal):
124+
d = {'astring': '[email protected]',
125+
'afloat': 7283.43,
126+
'anint': 2**20,
127+
'ashortlong': 2,
128+
'alist': ['.zyx.41'],
129+
'atuple': ('.zyx.41',)*10,
130+
'aboolean': False,
131+
'aunicode': "Andr\xe8 Previn"
132+
}
133+
134+
def test_dict(self):
135+
self.helper(self.d)
136+
137+
def test_list(self):
138+
self.helper(list(self.d.items()))
139+
140+
def test_tuple(self):
141+
self.helper(tuple(self.d.keys()))
142+
143+
def test_sets(self):
144+
for constructor in (set, frozenset):
145+
self.helper(constructor(self.d.keys()))
146+
147+
# TODO enable this test, when GR-13961 and GR-13962 will be fixed
148+
#def test_empty_frozenset_singleton(self):
149+
# # marshal.loads() must reuse the empty frozenset singleton
150+
# obj = frozenset()
151+
# obj2 = marshal.loads(marshal.dumps(obj))
152+
# self.assertIs(obj2, obj)
153+
154+
class BufferTest(unittest.TestCase, BaseMarshalUnmarshal):
155+
156+
def test_bytearray(self):
157+
b = bytearray(b"abc")
158+
self.helper(b)
159+
new = marshal.loads(marshal.dumps(b))
160+
self.assertEqual(type(new), bytes)
161+
162+
def test_memoryview(self):
163+
b = memoryview(b"abc")
164+
#self.helper(b)
165+
new = marshal.loads(marshal.dumps(b))
166+
self.assertEqual(type(new), bytes)
167+
168+
## TODO currently we don't support all the variation of arrays.
169+
#def test_array(self):
170+
# a = array.array('b', b"abc")
171+
# new = marshal.loads(marshal.dumps(a))
172+
# self.assertEqual(new, b"abc")

0 commit comments

Comments
 (0)