diff options
author | Aldo Cortesi <aldo@nullcube.com> | 2016-05-21 11:37:36 +1200 |
---|---|---|
committer | Aldo Cortesi <aldo@nullcube.com> | 2016-05-21 11:37:36 +1200 |
commit | a5c4cd034081d7dcdbd4b46bd69718edb45d4719 (patch) | |
tree | 52accc866d25c735e6c36f05255bb3f5349f8ac7 /netlib/multidict.py | |
parent | 96d8ec1ee33b076a472afc3053fdd8256559fcc3 (diff) | |
download | mitmproxy-a5c4cd034081d7dcdbd4b46bd69718edb45d4719.tar.gz mitmproxy-a5c4cd034081d7dcdbd4b46bd69718edb45d4719.tar.bz2 mitmproxy-a5c4cd034081d7dcdbd4b46bd69718edb45d4719.zip |
A clearer implementation of MultiDictView
This makes MultiDictView work with a simple getter/setter pair, rather than
using attributes with implicit leading underscores. Also move MultiDictView
into multidict.py and adds some simple unit tests.
Diffstat (limited to 'netlib/multidict.py')
-rw-r--r-- | netlib/multidict.py | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/netlib/multidict.py b/netlib/multidict.py index a359d46b..3af7979b 100644 --- a/netlib/multidict.py +++ b/netlib/multidict.py @@ -15,13 +15,7 @@ from .utils import Serializable @six.add_metaclass(ABCMeta) -class MultiDict(MutableMapping, Serializable): - def __init__(self, fields=None): - - # it is important for us that .fields is immutable, so that we can easily - # detect changes to it. - self.fields = tuple(fields) if fields else tuple() # type: Tuple[Tuple[bytes, bytes], ...] - +class _MultiDict(MutableMapping, Serializable): def __repr__(self): fields = tuple( repr(field) @@ -97,7 +91,7 @@ class MultiDict(MutableMapping, Serializable): value for k, value in self.fields if self._kconv(k) == key - ] + ] def set_all(self, key, values): """ @@ -173,7 +167,7 @@ class MultiDict(MutableMapping, Serializable): if multi: return self.fields else: - return super(MultiDict, self).items() + return super(_MultiDict, self).items() def to_dict(self): """ @@ -213,6 +207,12 @@ class MultiDict(MutableMapping, Serializable): return cls(tuple(x) for x in state) +class MultiDict(_MultiDict): + def __init__(self, fields=None): + super(MultiDict, self).__init__() + self.fields = tuple(fields) if fields else tuple() # type: Tuple[Tuple[bytes, bytes], ...] + + @six.add_metaclass(ABCMeta) class ImmutableMultiDict(MultiDict): def _immutable(self, *_): @@ -246,3 +246,34 @@ class ImmutableMultiDict(MultiDict): ret = self.copy() super(ImmutableMultiDict, ret).insert(index, key, value) return ret + + +class MultiDictView(_MultiDict): + """ + The MultiDictView provides the MultiDict interface over calculated data. + The view itself contains no state - data is retrieved from the parent on + request, and stored back to the parent on change. + """ + def __init__(self, getter, setter): + self._getter = getter + self._setter = setter + super(MultiDictView, self).__init__() + + @staticmethod + def _kconv(key): + # All request-attributes are case-sensitive. + return key + + @staticmethod + def _reduce_values(values): + # We just return the first element if + # multiple elements exist with the same key. + return values[0] + + @property + def fields(self): + return self._getter() + + @fields.setter + def fields(self, value): + return self._setter(value) |