From efb2a74dedd4bb006ab4dc7c4d798969cdd8990d Mon Sep 17 00:00:00 2001 From: Jan Pokorný Date: Thu, 3 Apr 2014 22:14:48 +0200 Subject: command_context: introduce filters-global keyword-based config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's up to command implementer to keep possible collisions away. Signed-off-by: Jan Pokorný --- command_context.py | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/command_context.py b/command_context.py index 72bad05..1e9df42 100644 --- a/command_context.py +++ b/command_context.py @@ -20,20 +20,22 @@ class CommandContextError(ClufterError): class CommandContextBase(MutableMapping): """Object representing command context""" def __init__(self, initial=None, parent=None): - if parent is None: - parent = self - self._parent = parent try: - self._dict = dict(initial) + self._dict = initial if type(initial) is dict else dict(initial) except TypeError: self._dict = {} + self._parent = parent if parent is not None else self def __delitem__(self, key): del self._dict[key] def __getitem__(self, key): - #return self._dict[key] - return self._dict.get(key) # make it soft-error (->setdefault reimpl.) + try: + return self._dict[key] + except KeyError: + pass + # make it soft-error (->setdefault reimpl.) + return None if self._parent is self else self._parent[key] def setdefault(self, key, default=None): return self._dict.setdefault(key, default) @@ -45,6 +47,7 @@ class CommandContextBase(MutableMapping): return len(self._dict) def __setitem__(self, key, value): + # XXX value could be also any valid dict constructor argument self._dict[key] = CommandContextBase(initial=value, parent=self) \ if isinstance(value, dict) else value @@ -55,10 +58,15 @@ class CommandContextBase(MutableMapping): class CommandContext(CommandContextBase): def __init__(self, *args, **kwargs): + # filter_context ... where global arguments for filters to be stored + # filters ... where filter instance + arguments hybrid is stored super(CommandContext, self).__init__(*args, **kwargs) - self._filters = {} + # could be cycle up to self if {} was used instead + self['__filter_context__'] = CommandContextBase() + self['__filters__'] = CommandContextBase() - def _wrapping_nested_context(self, obj): + @staticmethod + def _wrapping_nested_context(obj): class wrapped(CommandContextBase): def __getattribute__(self, name): if name == 'ctxt_wrapped': @@ -82,19 +90,24 @@ class CommandContext(CommandContextBase): def __setattribute__(self, name, value): obj.__setattribute__(name, value) - return (wrapped(parent=self)) + return wrapped def ensure_filter(self, flt): - existing, key = self._filters, flt.__class__.name + existing, key = self['__filters__'], flt.__class__.name ret = existing.get(key, None) - if ret: + if ret is not None: assert id(ret.ctxt_wrapped) == id(flt) else: - ret = existing[key] = self._wrapping_nested_context(flt) + ret = self._wrapping_nested_context(flt) + ret = existing[key] = ret(parent=self['__filter_context__']) return ret def ensure_filters(self, flts): return map(self.ensure_filter, flts) - def filter(self, which): - return self._filters[which] + def filter(self, which=None): + if which is not None: + ret = self['__filters__'][which] + else: + ret = self['__filter_context__'] + return ret -- cgit