]> git.openstreetmap.org Git - osqa.git/blob - forum/modules/decorators.py
Removes the necessity of the "decoratable" decorator in modules and makes the api...
[osqa.git] / forum / modules / decorators.py
1 import inspect\r
2 \r
3 class DecoratableObject(object):\r
4     def __init__(self, fn):\r
5         self._callable = fn\r
6 \r
7     def _decorate(self, fn, needs_origin):\r
8         origin = self._callable\r
9 \r
10         if needs_origin:\r
11             self._callable = lambda *args, **kwargs: fn(origin, *args, **kwargs)\r
12         else:\r
13             self._callable = lambda *args, **kwargs: fn(*args, **kwargs)\r
14 \r
15     def _decorate_method(self, fn, needs_origin):\r
16         origin = self._callable\r
17 \r
18         if needs_origin:\r
19             self._callable = lambda inst, *args, **kwargs: fn(inst, origin, *args, **kwargs)\r
20         else:\r
21             self._callable = lambda inst, *args, **kwargs: fn(inst, *args, **kwargs)\r
22 \r
23 \r
24     def __call__(self, *args, **kwargs):\r
25         return self._callable(*args, **kwargs)\r
26 \r
27 \r
28 def _decorate_method(origin, needs_origin):\r
29     if not hasattr(origin, '_decoratable_obj'):\r
30         name = origin.__name__\r
31         cls = origin.im_class\r
32 \r
33         decoratable = DecoratableObject(origin)\r
34 \r
35         def decoratable_method(self, *args, **kwargs):\r
36             return decoratable(self, *args, **kwargs)\r
37 \r
38         decoratable_method._decoratable_obj = decoratable\r
39         setattr(cls, name, decoratable_method)\r
40     else:\r
41         decoratable = origin._decoratable_obj\r
42 \r
43     def decorator(fn):\r
44         decoratable._decorate_method(fn, needs_origin)\r
45 \r
46     return decorator\r
47 \r
48 def _decorate_function(origin, needs_origin):\r
49     if not isinstance(origin, DecoratableObject):\r
50         mod = inspect.getmodule(origin)\r
51 \r
52         name = origin.__name__\r
53         origin = DecoratableObject(origin)\r
54         setattr(mod, name, DecoratableObject(origin))\r
55 \r
56     def decorator(fn):\r
57         origin._decorate(fn, needs_origin)\r
58 \r
59     return decorator\r
60 \r
61 \r
62 def decorate(origin, needs_origin=True):\r
63     if inspect.ismethod(origin):\r
64         return _decorate_method(origin, needs_origin)\r
65 \r
66     if inspect.isfunction(origin):\r
67         return _decorate_function(origin, needs_origin)