newserialized.py
179 lines
| 5.1 KiB
| text/x-python
|
PythonLexer
MinRK
|
r3539 | # encoding: utf-8 | ||
# -*- test-case-name: IPython.kernel.test.test_newserialized -*- | ||||
"""Refactored serialization classes and interfaces.""" | ||||
__docformat__ = "restructuredtext en" | ||||
# Tell nose to skip this module | ||||
__test__ = {} | ||||
#------------------------------------------------------------------------------- | ||||
# Copyright (C) 2008 The IPython Development Team | ||||
# | ||||
# Distributed under the terms of the BSD License. The full license is in | ||||
# the file COPYING, distributed as part of this software. | ||||
#------------------------------------------------------------------------------- | ||||
#------------------------------------------------------------------------------- | ||||
# Imports | ||||
#------------------------------------------------------------------------------- | ||||
MinRK
|
r4155 | import sys | ||
MinRK
|
r3539 | import cPickle as pickle | ||
try: | ||||
import numpy | ||||
except ImportError: | ||||
MinRK
|
r4155 | numpy = None | ||
MinRK
|
r3539 | |||
MinRK
|
r3557 | class SerializationError(Exception): | ||
pass | ||||
MinRK
|
r3539 | |||
MinRK
|
r4155 | if sys.version_info[0] >= 3: | ||
buffer = memoryview | ||||
py3k = True | ||||
else: | ||||
py3k = False | ||||
MinRK
|
r3539 | #----------------------------------------------------------------------------- | ||
# Classes and functions | ||||
#----------------------------------------------------------------------------- | ||||
class ISerialized: | ||||
def getData(): | ||||
"""""" | ||||
def getDataSize(units=10.0**6): | ||||
"""""" | ||||
def getTypeDescriptor(): | ||||
"""""" | ||||
def getMetadata(): | ||||
"""""" | ||||
class IUnSerialized: | ||||
def getObject(): | ||||
"""""" | ||||
class Serialized(object): | ||||
# implements(ISerialized) | ||||
def __init__(self, data, typeDescriptor, metadata={}): | ||||
self.data = data | ||||
self.typeDescriptor = typeDescriptor | ||||
self.metadata = metadata | ||||
def getData(self): | ||||
return self.data | ||||
def getDataSize(self, units=10.0**6): | ||||
return len(self.data)/units | ||||
def getTypeDescriptor(self): | ||||
return self.typeDescriptor | ||||
def getMetadata(self): | ||||
return self.metadata | ||||
class UnSerialized(object): | ||||
# implements(IUnSerialized) | ||||
def __init__(self, obj): | ||||
self.obj = obj | ||||
def getObject(self): | ||||
return self.obj | ||||
class SerializeIt(object): | ||||
# implements(ISerialized) | ||||
def __init__(self, unSerialized): | ||||
self.data = None | ||||
self.obj = unSerialized.getObject() | ||||
MinRK
|
r4155 | if numpy is not None and isinstance(self.obj, numpy.ndarray): | ||
if py3k or len(self.obj.shape) == 0: # length 0 arrays are just pickled | ||||
# FIXME: | ||||
# also use pickle for numpy arrays on py3k, since | ||||
# pyzmq doesn't rebuild from memoryviews properly | ||||
MinRK
|
r3648 | self.typeDescriptor = 'pickle' | ||
self.metadata = {} | ||||
else: | ||||
MinRK
|
r3539 | self.obj = numpy.ascontiguousarray(self.obj, dtype=None) | ||
self.typeDescriptor = 'ndarray' | ||||
self.metadata = {'shape':self.obj.shape, | ||||
'dtype':self.obj.dtype.str} | ||||
MinRK
|
r4155 | elif isinstance(self.obj, bytes): | ||
MinRK
|
r3539 | self.typeDescriptor = 'bytes' | ||
self.metadata = {} | ||||
elif isinstance(self.obj, buffer): | ||||
self.typeDescriptor = 'buffer' | ||||
self.metadata = {} | ||||
else: | ||||
self.typeDescriptor = 'pickle' | ||||
self.metadata = {} | ||||
MinRK
|
r3642 | self._generateData() | ||
MinRK
|
r3539 | |||
def _generateData(self): | ||||
if self.typeDescriptor == 'ndarray': | ||||
self.data = numpy.getbuffer(self.obj) | ||||
elif self.typeDescriptor in ('bytes', 'buffer'): | ||||
self.data = self.obj | ||||
elif self.typeDescriptor == 'pickle': | ||||
MinRK
|
r3545 | self.data = pickle.dumps(self.obj, -1) | ||
MinRK
|
r3539 | else: | ||
raise SerializationError("Really wierd serialization error.") | ||||
del self.obj | ||||
def getData(self): | ||||
return self.data | ||||
def getDataSize(self, units=10.0**6): | ||||
return 1.0*len(self.data)/units | ||||
def getTypeDescriptor(self): | ||||
return self.typeDescriptor | ||||
def getMetadata(self): | ||||
return self.metadata | ||||
class UnSerializeIt(UnSerialized): | ||||
# implements(IUnSerialized) | ||||
def __init__(self, serialized): | ||||
self.serialized = serialized | ||||
def getObject(self): | ||||
typeDescriptor = self.serialized.getTypeDescriptor() | ||||
MinRK
|
r4155 | if numpy is not None and typeDescriptor == 'ndarray': | ||
MinRK
|
r3642 | buf = self.serialized.getData() | ||
MinRK
|
r4155 | if isinstance(buf, (bytes, buffer)): | ||
MinRK
|
r3642 | result = numpy.frombuffer(buf, dtype = self.serialized.metadata['dtype']) | ||
else: | ||||
# memoryview | ||||
result = numpy.array(buf, dtype = self.serialized.metadata['dtype']) | ||||
MinRK
|
r3539 | result.shape = self.serialized.metadata['shape'] | ||
elif typeDescriptor == 'pickle': | ||||
result = pickle.loads(self.serialized.getData()) | ||||
elif typeDescriptor in ('bytes', 'buffer'): | ||||
result = self.serialized.getData() | ||||
else: | ||||
raise SerializationError("Really wierd serialization error.") | ||||
return result | ||||
def serialize(obj): | ||||
return SerializeIt(UnSerialized(obj)) | ||||
def unserialize(serialized): | ||||
return UnSerializeIt(serialized).getObject() | ||||