import inspect\r
\r
class DecoratableObject(object):\r
+ MODE_OVERRIDE = 0\r
+ MODE_PARAMS = 1\r
+ MODE_RESULT = 2\r
+\r
def __init__(self, fn):\r
+ a = inspect.getargspec(fn)\r
self._callable = fn\r
+ self._params_decoration = None\r
+ self._result_decoration = None\r
\r
- def _decorate(self, fn, needs_origin):\r
+ def _decorate(self, fn, needs_origin, method=False):\r
origin = self._callable\r
\r
if needs_origin:\r
- self._callable = lambda *args, **kwargs: fn(origin, *args, **kwargs)\r
+ if method:\r
+ self._callable = lambda inst, *args, **kwargs: fn(inst, origin, *args, **kwargs)\r
+ else:\r
+ self._callable = lambda *args, **kwargs: fn(origin, *args, **kwargs)\r
else:\r
- self._callable = lambda *args, **kwargs: fn(*args, **kwargs)\r
+ self._callable = fn\r
\r
- def _decorate_method(self, fn, needs_origin):\r
- origin = self._callable\r
+ def _decorate_params(self, fn):\r
+ if not self._params_decoration:\r
+ self._params_decoration = []\r
\r
- if needs_origin:\r
- self._callable = lambda inst, *args, **kwargs: fn(inst, origin, *args, **kwargs)\r
- else:\r
- self._callable = lambda inst, *args, **kwargs: fn(inst, *args, **kwargs)\r
+ self._params_decoration.append(fn)\r
\r
+ def _decorate_result(self, fn):\r
+ if not self._result_decoration:\r
+ self._result_decoration = []\r
+\r
+ self._result_decoration.append(fn)\r
\r
def __call__(self, *args, **kwargs):\r
- return self._callable(*args, **kwargs)\r
+ if self._params_decoration:\r
+ for dec in self._params_decoration:\r
+ args, kwargs = dec(*args, **kwargs)\r
+\r
+ res = self._callable(*args, **kwargs)\r
+\r
+ if self._result_decoration:\r
+ for dec in self._result_decoration:\r
+ res = dec(res)\r
+\r
+ return res\r
\r
\r
-def _decorate_method(origin, needs_origin):\r
+def _create_decorator(origin, needs_origin, mode, method=False):\r
+ def decorator(fn):\r
+ if mode == DecoratableObject.MODE_OVERRIDE:\r
+ origin._decorate(fn, needs_origin, method=method)\r
+ elif mode == DecoratableObject.MODE_PARAMS:\r
+ origin._decorate_params(fn)\r
+ elif mode == DecoratableObject.MODE_RESULT:\r
+ origin._decorate_result(fn)\r
+\r
+ return fn\r
+\r
+ return decorator\r
+\r
+\r
+def _decorate_method(origin, needs_origin, mode):\r
if not hasattr(origin, '_decoratable_obj'):\r
name = origin.__name__\r
cls = origin.im_class\r
else:\r
decoratable = origin._decoratable_obj\r
\r
- def decorator(fn):\r
- decoratable._decorate_method(fn, needs_origin)\r
+ return _create_decorator(decoratable, needs_origin, mode, method=True)\r
\r
- return decorator\r
-\r
-def _decorate_function(origin, needs_origin):\r
+def _decorate_function(origin, needs_origin, mode):\r
if not isinstance(origin, DecoratableObject):\r
mod = inspect.getmodule(origin)\r
\r
name = origin.__name__\r
origin = DecoratableObject(origin)\r
- setattr(mod, name, DecoratableObject(origin))\r
+ setattr(mod, name, origin)\r
+\r
+ return _create_decorator(origin, needs_origin, mode)\r
+\r
+\r
+def decorate(origin, needs_origin=True, mode=DecoratableObject.MODE_OVERRIDE):\r
+ if inspect.ismethod(origin):\r
+ return _decorate_method(origin, needs_origin, mode)\r
+\r
+ if inspect.isfunction(origin) or isinstance(origin, DecoratableObject):\r
+ return _decorate_function(origin, needs_origin, mode)\r
\r
def decorator(fn):\r
- origin._decorate(fn, needs_origin)\r
+ return fn\r
\r
return decorator\r
\r
\r
-def decorate(origin, needs_origin=True):\r
- if inspect.ismethod(origin):\r
- return _decorate_method(origin, needs_origin)\r
+def _decorate_params(origin):\r
+ return decorate(origin, mode=DecoratableObject.MODE_PARAMS)\r
+\r
+decorate.params = _decorate_params\r
+\r
+def _decorate_result(origin):\r
+ return decorate(origin, mode=DecoratableObject.MODE_RESULT)\r
+\r
+decorate.result = _decorate_result\r
+\r
+def _decorate_with(fn):\r
+ def decorator(origin):\r
+ if not isinstance(origin, DecoratableObject):\r
+ decoratable = DecoratableObject(origin)\r
+ else:\r
+ decoratable = origin\r
+\r
+ decoratable._decorate(fn, True, False)\r
+ return decoratable\r
+ return decorator\r
+\r
\r
- if inspect.isfunction(origin):\r
- return _decorate_function(origin, needs_origin)
\ No newline at end of file
+decorate.withfn = _decorate_with
\ No newline at end of file