diff options
Diffstat (limited to 'libmproxy/stateobject.py')
-rw-r--r-- | libmproxy/stateobject.py | 103 |
1 files changed, 38 insertions, 65 deletions
diff --git a/libmproxy/stateobject.py b/libmproxy/stateobject.py index 6fb73c24..53ccef0e 100644 --- a/libmproxy/stateobject.py +++ b/libmproxy/stateobject.py @@ -1,78 +1,51 @@ from __future__ import absolute_import -class StateObject(object): - def _get_state(self): - raise NotImplementedError # pragma: nocover - - def _load_state(self, state): - raise NotImplementedError # pragma: nocover - - @classmethod - def _from_state(cls, state): - raise NotImplementedError # pragma: nocover - # Usually, this function roughly equals to the following code: - # f = cls() - # f._load_state(state) - # return f - - def __eq__(self, other): - try: - return self._get_state() == other._get_state() - except AttributeError: # we may compare with something that's not a StateObject - return False - - def __ne__(self, other): - return not self.__eq__(other) - - -class SimpleStateObject(StateObject): - """ - A StateObject with opionated conventions that tries to keep everything DRY. - Simply put, you agree on a list of attributes and their type. - Attributes can either be primitive types(str, tuple, bool, ...) or StateObject instances themselves. - SimpleStateObject uses this information for the default _get_state(), _from_state(s) and _load_state(s) methods. - Overriding _get_state or _load_state to add custom adjustments is always possible. +class StateObject(object): """ + An object with serializable state. - _stateobject_attributes = None # none by default to raise an exception if definition was forgotten - """ - An attribute-name -> class-or-type dict containing all attributes that should be serialized - If the attribute is a class, this class must be a subclass of StateObject. + State attributes can either be serializable types(str, tuple, bool, ...) + or StateObject instances themselves. """ + # An attribute-name -> class-or-type dict containing all attributes that + # should be serialized. If the attribute is a class, it must implement the + # StateObject protocol. + _stateobject_attributes = None + # A set() of attributes that should be ignored for short state + _stateobject_long_attributes = frozenset([]) - def _get_state(self): - return {attr: self._get_state_attr(attr, cls) - for attr, cls in self._stateobject_attributes.iteritems()} + def from_state(self, state): + raise NotImplementedError() - def _get_state_attr(self, attr, cls): + def get_state(self, short=False): """ - helper for _get_state. - returns the value of the given attribute + Retrieve object state. If short is true, return an abbreviated + format with long data elided. """ - val = getattr(self, attr) - if hasattr(val, "_get_state"): - return val._get_state() - else: - return val - - def _load_state(self, state): + state = {} for attr, cls in self._stateobject_attributes.iteritems(): - self._load_state_attr(attr, cls, state) - - def _load_state_attr(self, attr, cls, state): + if short and attr in self._stateobject_long_attributes: + continue + val = getattr(self, attr) + if hasattr(val, "get_state"): + state[attr] = val.get_state(short) + else: + state[attr] = val + return state + + def load_state(self, state): """ - helper for _load_state. - loads the given attribute from the state. + Load object state from data returned by a get_state call. """ - if state.get(attr, None) is None: - setattr(self, attr, None) - return - - curr = getattr(self, attr) - if hasattr(curr, "_load_state"): - curr._load_state(state[attr]) - elif hasattr(cls, "_from_state"): - setattr(self, attr, cls._from_state(state[attr])) - else: - setattr(self, attr, cls(state[attr]))
\ No newline at end of file + for attr, cls in self._stateobject_attributes.iteritems(): + if state.get(attr, None) is None: + setattr(self, attr, None) + else: + curr = getattr(self, attr) + if hasattr(curr, "load_state"): + curr.load_state(state[attr]) + elif hasattr(cls, "from_state"): + setattr(self, attr, cls.from_state(state[attr])) + else: + setattr(self, attr, cls(state[attr])) |