def testCustomClass(self): def something_serializer(obj, serializer, stream, level): d = { "__class__": "Something", "custom": True, "name": obj.name, "value": obj.value } serializer.ser_builtins_dict(d, stream, level) serpent.register_class(Something, something_serializer) s = Something("hello", 42) d = serpent.dumps(s) x = serpent.loads(d) self.assertEqual( { "__class__": "Something", "custom": True, "name": "hello", "value": 42 }, x) serpent.unregister_class(Something) d = serpent.dumps(s) x = serpent.loads(d) self.assertEqual(("bogus", "state"), x)
def register_type_replacement(cls, object_type, replacement_function): def custom_serializer(object, serpent_serializer, outputstream, indentlevel): replaced = replacement_function(object) if replaced is object: serpent_serializer.ser_default_class(replaced, outputstream, indentlevel) else: serpent_serializer._serialize(replaced, outputstream, indentlevel) serpent.register_class(object_type, custom_serializer)
def register_type_replacement(cls, object_type, replacement_function): def custom_serializer(object, serpent_serializer, outputstream, indentlevel): replaced = replacement_function(object) if replaced is object: serpent_serializer.ser_default_class(replaced, outputstream, indentlevel) else: serpent_serializer._serialize(replaced, outputstream, indentlevel) serpent.register_class(object_type, custom_serializer)
def testSubclass(self): def custom_serializer(obj, serializer, stream, level): serializer._serialize("[(sub)class=%s]" % type(obj), stream, level) serpent.register_class(BaseClass, custom_serializer) s = SubClass() d = serpent.dumps(s) x = serpent.loads(d) classname = __name__ + ".SubClass" self.assertEqual("[(sub)class=<class '" + classname + "'>]", x)
def register_type_replacement(cls, object_type, replacement_function): def custom_serializer(object, serpent_serializer, outputstream, indentlevel): replaced = replacement_function(object) if replaced is object: serpent_serializer.ser_default_class(replaced, outputstream, indentlevel) else: serpent_serializer._serialize(replaced, outputstream, indentlevel) if object_type is type or not inspect.isclass(object_type): raise ValueError("refusing to register replacement for a non-type or the type 'type' itself") serpent.register_class(object_type, custom_serializer)
def register_class_to_dict(cls, clazz, converter, serpent_too=True): """Registers a custom function that returns a dict representation of objects of the given class. The function is called with a single parameter; the object to be converted to a dict.""" cls.__custom_class_to_dict_registry[clazz] = converter if serpent_too: with contextlib.suppress(errors.ProtocolError): def serpent_converter(obj, serializer, stream, level): d = converter(obj) serializer.ser_builtins_dict(d, stream, level) serpent.register_class(clazz, serpent_converter)
def register_type_replacement(cls, object_type, replacement_function): def custom_serializer(object, serpent_serializer, outputstream, indentlevel): replaced = replacement_function(object) if replaced is object: serpent_serializer.ser_default_class(replaced, outputstream, indentlevel) else: serpent_serializer._serialize(replaced, outputstream, indentlevel) if object_type is type or not inspect.isclass(object_type): raise ValueError("refusing to register replacement for a non-type or the type 'type' itself") serpent.register_class(object_type, custom_serializer)
def register_class_to_dict(cls, clazz, converter, serpent_too=True): """Registers a custom function that returns a dict representation of objects of the given class. The function is called with a single parameter; the object to be converted to a dict.""" cls.__custom_class_to_dict_registry[clazz] = converter if serpent_too: try: get_serializer_by_id(SerpentSerializer.serializer_id) import serpent def serpent_converter(obj, serializer, stream, level): d = converter(obj) serializer.ser_builtins_dict(d, stream, level) serpent.register_class(clazz, serpent_converter) except Pyro4.errors.ProtocolError: pass
def testRegisterOrderPreserving(self): serpent._reset_special_classes_registry() serpent.register_class(BaseClass, lambda: None) serpent.register_class(SubClass, lambda: None) classes = list(serpent._special_classes_registry) self.assertEqual(KeysView, classes.pop(0)) self.assertEqual(ValuesView, classes.pop(0)) self.assertEqual(ItemsView, classes.pop(0)) if sys.version_info >= (2, 7): self.assertEqual(collections.OrderedDict, classes.pop(0)) if sys.version_info >= (3, 4): import enum self.assertEqual(enum.Enum, classes.pop(0)) self.assertEqual(BaseClass, classes.pop(0)) self.assertEqual(SubClass, classes.pop(0)) self.assertEqual(0, len(classes))
def register_class_to_dict(cls, clazz, converter, serpent_too=True): """Registers a custom function that returns a dict representation of objects of the given class. The function is called with a single parameter; the object to be converted to a dict.""" cls.__custom_class_to_dict_registry[clazz] = converter if serpent_too: try: get_serializer_by_id(SerpentSerializer.serializer_id) import serpent def serpent_converter(obj, serializer, stream, level): d = converter(obj) serializer.ser_builtins_dict(d, stream, level) serpent.register_class(clazz, serpent_converter) except Pyro4.errors.ProtocolError: pass
def testUUID(self): uid = uuid.uuid4() string_uid = str(uid) ser = serpent.dumps(uid) x = serpent.loads(ser) self.assertEqual(string_uid, x) def custom_uuid_translate(obj, serp, stream, level): serp._serialize("custom_uuid!", stream, level) serpent.register_class(uuid.UUID, custom_uuid_translate) try: ser = serpent.dumps(uid) x = serpent.loads(ser) self.assertEqual("custom_uuid!", x) finally: serpent.unregister_class(uuid.UUID)
def testIntercept(self): ex = ZeroDivisionError("wrong") ser = serpent.dumps(ex) data = serpent.loads(ser) # default behavior is to serialize the exception to a dict self.assertEqual({'__exception__': True, 'args': ('wrong',), '__class__': 'ZeroDivisionError', 'attributes': {}}, data) def custom_exception_translate(obj, serializer, stream, indent): serializer._serialize("custom_exception!", stream, indent) try: serpent.register_class(Exception, custom_exception_translate) ser = serpent.dumps(ex) data = serpent.loads(ser) self.assertEqual("custom_exception!", data) finally: serpent.unregister_class(Exception)
def testUUID(self): uid = uuid.uuid4() string_uid = str(uid) ser = serpent.dumps(uid) x = serpent.loads(ser) self.assertEqual(string_uid, x) def custom_uuid_translate(obj, serp, stream, level): serp._serialize("custom_uuid!", stream, level) serpent.register_class(uuid.UUID, custom_uuid_translate) try: ser = serpent.dumps(uid) x = serpent.loads(ser) self.assertEqual("custom_uuid!", x) finally: serpent.unregister_class(uuid.UUID)
def testCustomClass(self): def something_serializer(obj, serializer, stream, level): d = { "__class__": "Something", "custom": True, "name": obj.name, "value": obj.value } serializer.ser_builtins_dict(d, stream, level) serpent.register_class(Something, something_serializer) s = Something("hello", 42) d = serpent.dumps(s) x = serpent.loads(d) self.assertEqual({"__class__": "Something", "custom": True, "name": "hello", "value": 42}, x) serpent.unregister_class(Something) d = serpent.dumps(s) x = serpent.loads(d) self.assertEqual(("bogus", "state"), x)
def testIntercept(self): ex = ZeroDivisionError("wrong") ser = serpent.dumps(ex) data = serpent.loads(ser) # default behavior is to serialize the exception to a dict self.assertEqual( { '__exception__': True, 'args': ('wrong', ), '__class__': 'ZeroDivisionError', 'attributes': {} }, data) def custom_exception_translate(obj, serializer, stream, indent): serializer._serialize("custom_exception!", stream, indent) try: serpent.register_class(Exception, custom_exception_translate) ser = serpent.dumps(ex) data = serpent.loads(ser) self.assertEqual("custom_exception!", data) finally: serpent.unregister_class(Exception)
def __init__(self): serpent.register_class(Player, self.serialize_player) serpent.register_class(ShopBehavior, self.serialize_shopbehavior) serpent.register_class(Location, self.serialize_location) serpent.register_class(Stats, self.serialize_stats) serpent.register_class(Item, self.serialize_item) serpent.register_class(Living, self.serialize_living) serpent.register_class(Exit, self.serialize_exit) serpent.register_class(Deferred, self.serialize_deferred) self.serializer = serpent.Serializer(indent=True, module_in_classname=True)
stream_id = str(uuid.uuid4()) self.streaming_responses[stream_id] = (client, time.time(), 0, data) return True, stream_id return True, None return False, data def __deserializeBlobArgs(self, protocolmsg): import marshal blobinfo = protocolmsg.annotations["BLBI"] blobinfo, objId, method = marshal.loads(blobinfo) blob = client.SerializedBlob(blobinfo, protocolmsg, is_blob=True) return objId, method, (blob,), {} # object, method, vargs, kwargs # register the special serializers for the pyro objects serpent.register_class(Daemon, serializers.pyro_class_serpent_serializer) serializers.SerializerBase.register_class_to_dict(Daemon, serializers.serialize_pyro_object_to_dict, serpent_too=False) def pyro_obj_to_auto_proxy(obj): """reduce function that automatically replaces Pyro objects by a Proxy""" daemon = getattr(obj, "_pyroDaemon", None) if daemon: # only return a proxy if the object is a registered pyro object return daemon.proxyFor(obj) return obj def get_attribute(obj, attr): """ Resolves an attribute name to an object. Raises
def run(self): i = 0 while not self.stop_running: serpent.register_class(type("clazz %d" % i, (), {}), None) # just register dummy serializer i += 1
""" object._pyroCallback = True return object try: import serpent def pyro_class_serpent_serializer(obj, serializer, stream, level): # Override the default way that a Pyro URI/proxy/daemon is serialized. # Because it defines a __getstate__ it would otherwise just become a tuple, # and not be deserialized as a class. d = Pyro4.util.SerializerBase.class_to_dict(obj) serializer.ser_builtins_dict(d, stream, level) serpent.register_class(URI, pyro_class_serpent_serializer) serpent.register_class(Proxy, pyro_class_serpent_serializer) serpent.register_class(Daemon, pyro_class_serpent_serializer) serpent.register_class(futures._ExceptionWrapper, pyro_class_serpent_serializer) except ImportError: pass def serialize_core_object_to_dict(obj): return { "__class__": "Pyro4.core." + obj.__class__.__name__, "state": obj.__getstate_for_dict__() }
self.exception = exception def raiseIt(self): raise self.exception def __serialized_dict__(self): """serialized form as a dictionary""" return { "__class__": "Pyro5.core._ExceptionWrapper", "exception": serializers.SerializerBase.class_to_dict(self.exception) } # register the special serializers for the pyro objects with Serpent serpent.register_class(URI, serializers.pyro_class_serpent_serializer) serpent.register_class(_ExceptionWrapper, serializers.pyro_class_serpent_serializer) serializers.SerializerBase.register_class_to_dict( URI, serializers.serialize_pyro_object_to_dict, serpent_too=False) serializers.SerializerBase.register_class_to_dict( _ExceptionWrapper, _ExceptionWrapper.__serialized_dict__, serpent_too=False) def resolve(uri, delay_time=0): """ Resolve a 'magic' uri (PYRONAME, PYROMETA) into the direct PYRO uri. It finds a name server, and use that to resolve a PYRONAME uri into the direct PYRO uri pointing to the named object. If uri is already a PYRO uri, it is returned unmodified.
def run(self): i = 0 while not self.stop_running: serpent.register_class(type("clazz %d" % i, (), {}), None) # just register dummy serializer i += 1
Only when you need to access the actual client data you can deserialize on demand. This makes efficient, transparent gateways or dispatchers and such possible: they don't have to de/reserialize the message and are independent from the serialized class definitions. You have to pass this as the only parameter to a remote method call for Pyro to understand it. Init arguments: ``info`` = some (small) descriptive data about the blob. Can be a simple id or name or guid. Must be marshallable. ``data`` = the actual client data payload that you want to transfer in the blob. Can be anything that you would otherwise have used as regular remote call arguments. """ def __init__(self, info, data, is_blob=False): self.info = info self._data = data self._contains_blob = is_blob def deserialized(self): """Retrieves the client data stored in this blob. Deserializes the data automatically if required.""" if self._contains_blob: protocol_msg = self._data serializer = serializers.serializers_by_id[ protocol_msg.serializer_id] _, _, data, _ = serializer.loads(protocol_msg.data) return data else: return self._data # register the special serializers for the pyro objects serpent.register_class(Proxy, serializers.pyro_class_serpent_serializer) serializers.SerializerBase.register_class_to_dict( Proxy, serializers.serialize_pyro_object_to_dict, serpent_too=False)
def __init__(self): serpent.register_class(Player, self.serialize_player) serpent.register_class(ShopBehavior, self.serialize_shopbehavior) serpent.register_class(Location, self.serialize_location) serpent.register_class(Stats, self.serialize_stats) serpent.register_class(Item, self.serialize_item) serpent.register_class(Living, self.serialize_living) serpent.register_class(Exit, self.serialize_exit) serpent.register_class(Deferred, self.serialize_deferred) self.serializer = serpent.Serializer(indent=True, module_in_classname=True)