Last active
August 29, 2015 14:16
-
-
Save jaraco/d979a558bc0bf2194c23 to your computer and use it in GitHub Desktop.
FixedOffset serialization fails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Save this file as test_fo.py and run it | |
""" | |
import pprint | |
import json | |
import datetime | |
import pickle | |
jsonpickle = None | |
bson = None | |
def setup_module(module): | |
module.jsonpickle = __import__('jsonpickle') | |
module.bson = __import__('bson.tz_util') | |
def test_FixedOffsetSerializable(): | |
fo = bson.tz_util.FixedOffset(-60*5, 'EST') | |
serialized = jsonpickle.dumps(fo) | |
pprint.pprint(json.loads(serialized)) | |
restored = jsonpickle.loads(serialized) | |
print(restored._FixedOffset__offset) | |
assert vars(restored) == vars(fo) | |
def test_timedelta(): | |
td = datetime.timedelta(-1, 68400) | |
serialized = jsonpickle.dumps(td) | |
pprint.pprint(json.loads(serialized)) | |
restored = jsonpickle.loads(serialized) | |
assert restored == td | |
def test_stdlib_pickle(): | |
fo = bson.tz_util.FixedOffset(-60*5, 'EST') | |
serialized = pickle.dumps(fo) | |
pprint.pprint(serialized) | |
restored = pickle.loads(serialized) | |
print(restored._FixedOffset__offset) | |
assert vars(restored) == vars(fo) | |
class FixedOffset(datetime.tzinfo): | |
def __init__(self, offset): | |
self.offset = datetime.timedelta(offset) | |
def __getinitargs__(self): | |
return self.offset, | |
def utcoffset(self, dt): | |
return self.offset | |
def tzname(self, dt): | |
return 'name' | |
def dst(self, dt): | |
return datetime.timedelta(0) | |
def test_nested_objects(): | |
o = FixedOffset(99) | |
serialized = jsonpickle.dumps(o) | |
pprint.pprint(json.loads(serialized)) | |
restored = jsonpickle.loads(serialized) | |
assert restored.offset == datetime.timedelta(99) | |
def test_datetime_with_fixed_offset(): | |
fo = FixedOffset(-60) | |
dt = datetime.datetime.now().replace(tzinfo=fo) | |
serialized = jsonpickle.dumps(dt) | |
pprint.pprint(json.loads(serialized)) | |
restored = jsonpickle.loads(serialized) | |
assert restored == dt | |
setup_params = dict( | |
install_requires=[ | |
'jsonpickle', | |
'pymongo', | |
], | |
setup_requires=[ | |
'pytest_runner', | |
], | |
tests_require=[ | |
'pytest', | |
], | |
) | |
if __name__ == '__main__': | |
import sys | |
sys.argv[1:1] = ['pytest'] | |
__import__('setuptools').setup(**setup_params) |
Going to try something like this... https://mail.python.org/pipermail/python-dev/2003-January/032043.html we'll see.
# crash-python.py
class Tuple(tuple):
__slots__ = ()
class List(list):
__slots__ = ()
t = List()
t.__class__ = Tuple
# --- >8 --- >8 ---
$ python2.7 crash-python.py
Segmentation fault: 11
$ python3.4 crash-python.py
TypeError: __class__ assignment: 'List' object layout differs from 'Tuple'
Oh well, I'll probably try a different approach, like maybe returning an instance that behaves like a tuple, but without actually being an instance. That's unfortunate, though.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ugh, nevermind, that totally doesn't work.. I'll keep digging. I was misled when I wrote some test code that made me believe that the above works, but it doesn't. doh.