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 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_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 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 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.
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)