aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/stateobject.py
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2014-09-17 11:35:14 +1200
committerAldo Cortesi <aldo@nullcube.com>2014-09-17 11:41:42 +1200
commitd998790c2f12594e6d0edc5a98e908677b60b31f (patch)
tree2c9de7840374297d466eabf7670e87ab943e059f /libmproxy/stateobject.py
parentb9531ac89ba70d8404444d4e2b86b94153a783c9 (diff)
downloadmitmproxy-d998790c2f12594e6d0edc5a98e908677b60b31f.tar.gz
mitmproxy-d998790c2f12594e6d0edc5a98e908677b60b31f.tar.bz2
mitmproxy-d998790c2f12594e6d0edc5a98e908677b60b31f.zip
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
Diffstat (limited to 'libmproxy/stateobject.py')
-rw-r--r--libmproxy/stateobject.py96
1 files changed, 28 insertions, 68 deletions
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]))