From 25051d4c04ce0458a15657645d2b072beddfce10 Mon Sep 17 00:00:00 2001 From: Anders Ingemann Date: Wed, 25 Mar 2015 20:36:06 +0100 Subject: [PATCH] Improve __getstate__ for bootstrapinfo This approach may be a little hacked, but it works for now and if it breaks at some point in the future because of e.g. circular references that bridge will have to be crossed then --- bootstrapvz/base/bootstrapinfo.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/bootstrapvz/base/bootstrapinfo.py b/bootstrapvz/base/bootstrapinfo.py index f5dc0bc..111c1d9 100644 --- a/bootstrapvz/base/bootstrapinfo.py +++ b/bootstrapvz/base/bootstrapinfo.py @@ -115,13 +115,22 @@ class BootstrapInformation(object): return manifest_vars def __getstate__(self): - state = self.__dict__.copy() - exclude_keys = ['source_lists', 'preference_lists', 'packages'] - for key in exclude_keys: - # We may have been serialized before, - # so don't fail if the keys do not exist - if key in state: - del state[key] + from bootstrapvz.remote import supported_classes + + def can_serialize(obj): + if hasattr(obj, '__class__') and hasattr(obj, '__module__'): + class_name = obj.__module__ + '.' + obj.__class__.__name__ + return class_name in supported_classes or isinstance(obj, (BaseException, Exception)) + return True + + def filter_state(state): + if isinstance(state, dict): + return {key: filter_state(val) for key, val in state.items() if can_serialize(val)} + if isinstance(state, (set, tuple, list, frozenset)): + return type(state)(filter_state(val) for val in state if can_serialize(val)) + return state + + state = filter_state(self.__dict__) state['__class__'] = self.__module__ + '.' + self.__class__.__name__ return state