diff options
author | Jan Pokorný <jpokorny@redhat.com> | 2014-02-11 11:51:58 +0100 |
---|---|---|
committer | Jan Pokorný <jpokorny@redhat.com> | 2014-02-11 13:36:43 +0100 |
commit | b8288de9b54b4070c7f68d12268d3616083a236f (patch) | |
tree | 89518b2a2c35dbffaa3ba21db4ca7585e85e94f7 /command_context.py | |
parent | d1e3861437ea588e448b4decf1b460ec5bea57f6 (diff) | |
download | clufter-b8288de9b54b4070c7f68d12268d3616083a236f.tar.gz clufter-b8288de9b54b4070c7f68d12268d3616083a236f.tar.xz clufter-b8288de9b54b4070c7f68d12268d3616083a236f.zip |
filters/command context: filters get passed their portion + no self
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
Diffstat (limited to 'command_context.py')
-rw-r--r-- | command_context.py | 76 |
1 files changed, 73 insertions, 3 deletions
diff --git a/command_context.py b/command_context.py index fc8c7dd..0434c1c 100644 --- a/command_context.py +++ b/command_context.py @@ -5,6 +5,7 @@ """Command context, i.e., state distributed along filters chain""" __author__ = "Jan Pokorný <jpokorny @at@ Red Hat .dot. com>" +from collections import MutableMapping import logging from .error import ClufterError @@ -16,6 +17,75 @@ class CommandContextError(ClufterError): pass -class CommandContext(dict): - """Object representing command context (WIP: use dict for now)""" - pass +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) + except TypeError: + self._dict = {} + + 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 + + def __iter__(self): + return iter(self._dict) + + def __len__(self): + return len(self._dict) + + def __setitem__(self, key, value): + self._dict[key] = CommandContextBase(initial=value, parent=self) \ + if isinstance(value, dict) else value + + @property + def parent(self): + return self._parent + + +class CommandContext(CommandContextBase): + def __init__(self, *args, **kwargs): + super(CommandContext, self).__init__(*args, **kwargs) + self._filters = {} + + def _wrapping_nested_context(self, obj): + class wrapped(CommandContextBase): + def __getattribute__(self, name): + if name == 'ctxt_wrapped': + return obj + elif name == 'ctxt_set': + ret = lambda self, **kwargs: self.update(kwargs) + elif name.startswith('ctxt_'): + # by convention, ctxt_* methods are using second + # argument to pass the respective (nested) context + ret = obj.__getattribute__(name) + if callable(ret): + ret = \ + lambda this, *args, **kwargs: \ + ret(this, this, *args, **kwargs) + else: + ret = obj.__getattribute__(name) + return ret + + def __setattribute__(self, name, value): + obj.__setattribute__(name, value) + return (wrapped(parent=self)) + + def add_filter(self, flt): + existing = self._filters + if flt.__class__.name not in existing: + existing[flt.__class__.name] = self._wrapping_nested_context(flt) + + def add_filters(self, flts): + for flt in flts: + self.add_filter(flt) + + def filter(self, which): + return self._filters[which] |