mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
213 lines
4.4 KiB
Python
213 lines
4.4 KiB
Python
import pickle as pkl
|
|
|
|
def test(data): # type: ignore
|
|
print('-'*50)
|
|
b = pkl.dumps(data)
|
|
print(b)
|
|
o = pkl.loads(b)
|
|
print(o)
|
|
assert data == o
|
|
return o
|
|
|
|
test(None) # PKL_NONE
|
|
test(...) # PKL_ELLIPSIS
|
|
test(1) # PKL_INT8
|
|
test(277) # PKL_INT16
|
|
test(-66666) # PKL_INT32
|
|
test(0xffffffffffff) # PKL_INT64
|
|
test(1.0) # PKL_FLOAT32
|
|
test(1.12312434234) # PKL_FLOAT64
|
|
test(True) # PKL_TRUE
|
|
test(False) # PKL_FALSE
|
|
test("hello") # PKL_STRING
|
|
test(b"hello") # PKL_BYTES
|
|
|
|
from linalg import vec2, vec3, vec2i, vec3i
|
|
|
|
test(vec2(2/3, 1.0)) # PKL_VEC2
|
|
test(vec3(2/3, 1.0, 3.0)) # PKL_VEC3
|
|
test(vec2i(1, 2)) # PKL_VEC2I
|
|
test(vec3i(1, 2, 3)) # PKL_VEC3I
|
|
|
|
test(vec3i) # PKL_TYPE
|
|
|
|
print('-'*50)
|
|
from array2d import array2d
|
|
a = array2d[int | bool | vec2i].fromlist([
|
|
[1, 2, vec2i.LEFT],
|
|
[4, True, 6]
|
|
])
|
|
a_encoded = pkl.dumps(a)
|
|
print(a_encoded)
|
|
a_decoded = pkl.loads(a_encoded)
|
|
assert isinstance(a_decoded, array2d)
|
|
assert a_decoded.width == 3 and a_decoded.height == 2
|
|
assert (a == a_decoded).all()
|
|
print(a_decoded)
|
|
|
|
test([1, 2, 3]) # PKL_LIST
|
|
test((1, 2, 3)) # PKL_TUPLE
|
|
test({1: 2, 3: 4}) # PKL_DICT
|
|
|
|
# test complex data
|
|
test([1, '2', True])
|
|
test([1, '2', 3.0, True])
|
|
test([1, '2', True, {'key': 4}])
|
|
test([1, '2', 3.0, True, {'k1': 4, 'k2': [b'xxxx']}])
|
|
|
|
# test memo
|
|
a = [1, 2, 3, 4, 5, 6, 745]
|
|
b = [a] * 10
|
|
c = test(b)
|
|
assert b == c
|
|
assert b is not c
|
|
assert c[0] is c[1] and c[1] is c[2]
|
|
|
|
s1 = 'hello'
|
|
s2 = 'world'
|
|
a = [s1, s2] * 10
|
|
b = test(a)
|
|
assert b == a
|
|
assert b is not a
|
|
assert b[0] is b[2]
|
|
assert b[1] is b[3]
|
|
|
|
from pkpy import TValue
|
|
|
|
class Base(TValue[int]):
|
|
def __eq__(self, other):
|
|
return self.value == other.value
|
|
|
|
def __ne__(self, other):
|
|
return self.value != other.value
|
|
|
|
class TVal(Base): pass # type: ignore
|
|
|
|
test(TVal(1))
|
|
|
|
old_bytes = pkl.dumps(TVal(1))
|
|
print(old_bytes)
|
|
|
|
# re-define the class so it will have a new type id
|
|
class TVal(Base): pass
|
|
# see if we can still load the old data
|
|
decoded = pkl.loads(old_bytes)
|
|
assert decoded == TVal(1)
|
|
print(pkl.dumps(decoded))
|
|
|
|
# test array2d with TValue
|
|
a = array2d[TVal].fromlist([
|
|
[TVal(1), TVal(2)],
|
|
[TVal(3), 1]])
|
|
test(a)
|
|
|
|
# test __reduce__
|
|
|
|
class A:
|
|
def __init__(self, seed):
|
|
self.seed = seed
|
|
self.x = seed
|
|
self.y = seed + 1
|
|
self.z = seed + 2
|
|
def __eq__(self, other):
|
|
return (self.x, self.y, self.z) == (other.x, other.y, other.z)
|
|
def __ne__(self, other):
|
|
return (self.x, self.y, self.z) != (other.x, other.y, other.z)
|
|
def __repr__(self):
|
|
return f"A({self.seed}, x={self.x}, y={self.y}, z={self.z})"
|
|
def __reduce__(self):
|
|
print('__reduce__() called')
|
|
return A, (self.seed,)
|
|
|
|
test([A(1)]*10)
|
|
|
|
class Simple:
|
|
def __init__(self, x):
|
|
self.field1 = x
|
|
self.field2 = [...]
|
|
def __eq__(self, other): return self.field1 == other.field1
|
|
def __ne__(self, other): return self.field1 != other.field1
|
|
|
|
test(Simple(1))
|
|
test([Simple(2)]*10)
|
|
|
|
from dataclasses import dataclass
|
|
|
|
@dataclass
|
|
class Data:
|
|
a: int
|
|
b: str = '2'
|
|
c: float = 3.0
|
|
|
|
test(Data(1))
|
|
|
|
exit()
|
|
|
|
from pickle import dumps, loads, _wrap, _unwrap
|
|
|
|
def test(x):
|
|
y = dumps(x)
|
|
# print(y.decode())
|
|
ok = x == loads(y)
|
|
if not ok:
|
|
_0 = _wrap(x)
|
|
_1 = _unwrap(_0)
|
|
print('='*50)
|
|
print(_0)
|
|
print('-'*50)
|
|
print(_1)
|
|
print('='*50)
|
|
assert False
|
|
|
|
test(1)
|
|
test(1.0)
|
|
test("hello")
|
|
test(True)
|
|
test(False)
|
|
test(None)
|
|
|
|
test([1, 2, 3])
|
|
test((1, 2, 3))
|
|
test({1: 2, 3: 4})
|
|
|
|
class Foo:
|
|
def __init__(self, x, y):
|
|
self.x = x
|
|
self.y = y
|
|
|
|
def __eq__(self, __value: object) -> bool:
|
|
if not isinstance(__value, Foo):
|
|
return False
|
|
return self.x == __value.x and self.y == __value.y
|
|
|
|
def __repr__(self) -> str:
|
|
return f"Foo({self.x}, {self.y})"
|
|
|
|
test(Foo(1, 2))
|
|
test(Foo([1, True], 'c'))
|
|
|
|
from linalg import vec2
|
|
|
|
test(vec2(1, 2))
|
|
|
|
a = {1, 2, 3, 4}
|
|
test(a)
|
|
|
|
a = bytes([1, 2, 3, 4])
|
|
test(a)
|
|
|
|
a = [1, 2]
|
|
d = {'k': a, 'j': a}
|
|
c = loads(dumps(d))
|
|
|
|
assert c['k'] is c['j']
|
|
assert c == d
|
|
|
|
# test circular references
|
|
from collections import deque
|
|
|
|
a = deque([1, 2, 3])
|
|
test(a)
|
|
|
|
a = [int, float, Foo]
|
|
test(a) |