]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/modules/decorators.py
remove the jquery.copy plugin, we don't need it anymore
[osqa.git] / forum / modules / decorators.py
index 8fbee7e30d4b19c9475a77da0b682051e6753e86..11af9e3d1c4c1cd49e60b04db024a9344f7269f9 100644 (file)
@@ -5,17 +5,26 @@ class DecoratableObject(object):
     MODE_PARAMS = 1\r
     MODE_RESULT = 2\r
 \r
     MODE_PARAMS = 1\r
     MODE_RESULT = 2\r
 \r
-    def __init__(self, fn):\r
-        a = inspect.getargspec(fn)\r
+    def __init__(self, fn, is_method=False):\r
         self._callable = fn\r
         self._callable = fn\r
+        self.is_method = is_method\r
+\r
         self._params_decoration = None\r
         self._result_decoration = None\r
 \r
         self._params_decoration = None\r
         self._result_decoration = None\r
 \r
-    def _decorate(self, fn, needs_origin, method=False):\r
+    def _decorate(self, fn, mode, **kwargs):\r
+        if mode == self.MODE_OVERRIDE:\r
+            self._decorate_full(fn, **kwargs)\r
+        elif mode == self.MODE_PARAMS:\r
+            self._decorate_params(fn)\r
+        elif mode == self.MODE_RESULT:\r
+            self._decorate_result(fn, **kwargs)\r
+\r
+    def _decorate_full(self, fn, needs_origin=True):\r
         origin = self._callable\r
 \r
         if needs_origin:\r
         origin = self._callable\r
 \r
         if needs_origin:\r
-            if method:\r
+            if self.is_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
                 self._callable = lambda inst, *args, **kwargs: fn(inst, origin, *args, **kwargs)\r
             else:\r
                 self._callable = lambda *args, **kwargs: fn(origin, *args, **kwargs)\r
@@ -28,85 +37,128 @@ class DecoratableObject(object):
 \r
         self._params_decoration.append(fn)\r
 \r
 \r
         self._params_decoration.append(fn)\r
 \r
-    def _decorate_result(self, fn):\r
+    def _decorate_result(self, fn, needs_params=False):\r
         if not self._result_decoration:\r
             self._result_decoration = []\r
 \r
         if not self._result_decoration:\r
             self._result_decoration = []\r
 \r
+        fn._needs_params = needs_params\r
         self._result_decoration.append(fn)\r
 \r
     def __call__(self, *args, **kwargs):\r
         if self._params_decoration:\r
             for dec in self._params_decoration:\r
         self._result_decoration.append(fn)\r
 \r
     def __call__(self, *args, **kwargs):\r
         if self._params_decoration:\r
             for dec in self._params_decoration:\r
-                args, kwargs = dec(*args, **kwargs)\r
+                try:\r
+                    args, kwargs = dec(*args, **kwargs)\r
+                except ReturnImediatelyException, e:\r
+                    return e.ret\r
 \r
         res = self._callable(*args, **kwargs)\r
 \r
         if self._result_decoration:\r
             for dec in self._result_decoration:\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
+                if dec._needs_params:\r
+                    res = dec(res, *args, **kwargs)\r
+                else:\r
+                    res = dec(res)\r
 \r
         return res\r
 \r
 \r
         return res\r
 \r
+class ReturnImediatelyException(Exception):\r
+    def __init__(self, ret):\r
+        super(Exception, self).__init__()\r
+        self.ret = ret\r
 \r
 \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
+def _check_decoratable(origin, install=True):\r
+    if not hasattr(origin, '_decoratable_obj'):\r
+        if inspect.ismethod(origin) and not hasattr(origin, '_decoratable_obj'):\r
+            decoratable = DecoratableObject(origin)\r
 \r
 \r
-        return fn\r
+            def decoratable_method(self, *args, **kwargs):\r
+                return decoratable(self, *args, **kwargs)\r
 \r
 \r
-    return decorator\r
+            decoratable_method._decoratable_obj = decoratable\r
 \r
 \r
+            def decoratable_decorate(fn, mode, **kwargs):\r
+                decoratable._decorate(fn, mode, **kwargs)\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
+            decoratable_method._decorate = decoratable_decorate\r
 \r
 \r
-        decoratable = DecoratableObject(origin)\r
+            if install:\r
+                setattr(origin.im_class, origin.__name__, decoratable_method)\r
 \r
 \r
-        def decoratable_method(self, *args, **kwargs):\r
-            return decoratable(self, *args, **kwargs)\r
+            return decoratable_method\r
+                \r
+        elif inspect.isfunction(origin):\r
+            decoratable = DecoratableObject(origin)\r
 \r
 \r
-        decoratable_method._decoratable_obj = decoratable\r
-        setattr(cls, name, decoratable_method)\r
-    else:\r
-        decoratable = origin._decoratable_obj\r
+            def decorated(*args, **kwargs):\r
+                return decoratable(*args, **kwargs)\r
 \r
 \r
-    return _create_decorator(decoratable, needs_origin, mode, method=True)\r
+            decorated._decoratable_obj = decoratable\r
 \r
 \r
-def _decorate_function(origin, needs_origin, mode):\r
-    if not isinstance(origin, DecoratableObject):\r
-        mod = inspect.getmodule(origin)\r
+            if install:\r
+                setattr(inspect.getmodule(origin), origin.__name__, decorated)\r
 \r
 \r
-        name = origin.__name__\r
-        origin = DecoratableObject(origin)\r
-        setattr(mod, name, origin)\r
+            decorated.__name__ = origin.__name__\r
+            decorated.__module__ = origin.__module__\r
 \r
 \r
-    return _create_decorator(origin, needs_origin, mode)\r
+            return decorated\r
 \r
 \r
+    return origin\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
 \r
-    if inspect.isfunction(origin) or isinstance(origin, DecoratableObject):\r
-        return _decorate_function(origin, needs_origin, mode)\r
+def decorate(origin, needs_origin=True):\r
+    origin = _check_decoratable(origin)\r
 \r
     def decorator(fn):\r
 \r
     def decorator(fn):\r
-        return fn\r
+        origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_OVERRIDE, needs_origin=needs_origin)\r
+        \r
+    return decorator\r
 \r
 \r
 def _decorate_params(origin):\r
 \r
 \r
 def _decorate_params(origin):\r
-    return decorate(origin, mode=DecoratableObject.MODE_PARAMS)\r
+    origin = _check_decoratable(origin)\r
+\r
+    def decorator(fn):\r
+        origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_PARAMS)\r
+\r
+    return decorator\r
 \r
 decorate.params = _decorate_params\r
 \r
 \r
 decorate.params = _decorate_params\r
 \r
-def _decorate_result(origin):\r
-    return decorate(origin, mode=DecoratableObject.MODE_RESULT)\r
+def _decorate_result(origin, needs_params=False):\r
+    origin = _check_decoratable(origin)\r
+\r
+    def decorator(fn):\r
+        origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_RESULT, needs_params=needs_params)\r
+\r
+    return decorator\r
 \r
 decorate.result = _decorate_result\r
 \r
 decorate.result = _decorate_result\r
+\r
+def _decorate_with(fn):\r
+    def decorator(origin):\r
+        origin = _check_decoratable(origin)\r
+        origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_OVERRIDE, needs_origin=True)\r
+        return origin\r
+    return decorator\r
+\r
+decorate.withfn = _decorate_with\r
+\r
+def _decorate_result_with(fn, needs_params=False):\r
+    def decorator(origin):\r
+        origin = _check_decoratable(origin)\r
+        origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_RESULT, needs_params=needs_params)\r
+        return origin\r
+    return decorator\r
+\r
+decorate.result.withfn = _decorate_result_with\r
+\r
+def _decorate_params_with(fn):\r
+    def decorator(origin):\r
+        origin = _check_decoratable(origin)\r
+        origin._decoratable_obj._decorate(fn, DecoratableObject.MODE_PARAMS)\r
+        return origin\r
+    return decorator\r
+\r
+decorate.params.withfn = _decorate_params_with
\ No newline at end of file