summaryrefslogtreecommitdiffstats
path: root/command_context.py
diff options
context:
space:
mode:
authorJan Pokorný <jpokorny@redhat.com>2014-02-11 11:51:58 +0100
committerJan Pokorný <jpokorny@redhat.com>2014-02-11 13:36:43 +0100
commitb8288de9b54b4070c7f68d12268d3616083a236f (patch)
tree89518b2a2c35dbffaa3ba21db4ca7585e85e94f7 /command_context.py
parentd1e3861437ea588e448b4decf1b460ec5bea57f6 (diff)
downloadclufter-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.py76
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]