From d998790c2f12594e6d0edc5a98e908677b60b31f Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Wed, 17 Sep 2014 11:35:14 +1200 Subject: Clean up and clarify StateObject - Flatten the class hierarchy - get_state, load_state, from_state are public - Simplify code - Remove __eq__ and __neq__. This fundamentally changes the semantics of inherited objects in a way that's not part of the core function of the class --- libmproxy/stateobject.py | 96 ++++++++++++++---------------------------------- 1 file changed, 28 insertions(+), 68 deletions(-) (limited to 'libmproxy/stateobject.py') diff --git a/libmproxy/stateobject.py b/libmproxy/stateobject.py index 9e9d6088..37b72c7e 100644 --- a/libmproxy/stateobject.py +++ b/libmproxy/stateobject.py @@ -2,82 +2,42 @@ 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. + An object with serializable state. - 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. + State attributes can either be serializable types(str, tuple, bool, ...) + or StateObject instances themselves. """ - - _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. - """ - - def _get_state(self): - return {attr: self._get_state_attr(attr, cls) - for attr, cls in self._stateobject_attributes.iteritems()} + # An attribute-name -> class-or-type dict containing all attributes that + # should be serialized. If the attribute is a class, it must be a subclass + # of StateObject. + _stateobject_attributes = None def _get_state_attr(self, attr, cls): - """ - helper for _get_state. - returns the value of the given attribute - """ val = getattr(self, attr) - if hasattr(val, "_get_state"): - return val._get_state() + if hasattr(val, "get_state"): + return val.get_state() else: return val - def _load_state(self, state): - for attr, cls in self._stateobject_attributes.iteritems(): - self._load_state_attr(attr, cls, state) - - def _load_state_attr(self, attr, cls, state): - """ - helper for _load_state. - loads the given attribute from the state. - """ - if state.get(attr, None) is None: - setattr(self, attr, None) - return + def from_state(self): + raise NotImplementedError - 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])) + def get_state(self): + state = {} + for attr, cls in self._stateobject_attributes.iteritems(): + state[attr] = self._get_state_attr(attr, cls) + return state + def load_state(self, state): + 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])) -- cgit v1.2.3