Merge branch 'master' of ssh://git.onelab.eu/git/myslice
[myslice.git] / manifold / util / functional.py
1 """Borrowed from Django."""
2
3 from threading import Lock
4
5 class LazyObject(object):
6     """
7     A wrapper for another class that can be used to delay instantiation of the
8     wrapped class.
9
10     By subclassing, you have the opportunity to intercept and alter the
11     instantiation. If you don't need to do that, use SimpleLazyObject.
12     """
13     def __init__(self):
14         self._wrapped = None
15         self._lock = Lock()
16
17     def __getattr__(self, name):
18         self._lock.acquire()
19         if self._wrapped is None:
20             self._setup()
21         self._lock.release()
22         return getattr(self._wrapped, name)
23
24     def __setattr__(self, name, value):
25         if name in ["_wrapped", "_lock"]:
26             # Assign to __dict__ to avoid infinite __setattr__ loops.
27             self.__dict__[name] = value
28         else:
29             if self._wrapped is None:
30                 self._setup()
31             setattr(self._wrapped, name, value)
32
33     def __delattr__(self, name):
34         if name == "_wrapped":
35             raise TypeError("can't delete _wrapped.")
36         if self._wrapped is None:
37             self._setup()
38         delattr(self._wrapped, name)
39
40     def _setup(self):
41         """
42         Must be implemented by subclasses to initialise the wrapped object.
43         """
44         raise NotImplementedError
45
46     # introspection support:
47     __members__ = property(lambda self: self.__dir__())
48
49     def __dir__(self):
50         if self._wrapped is None:
51             self._setup()
52         return  dir(self._wrapped)
53