local.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. # -*- coding: utf-8 -*-
  2. """
  3. celery.local
  4. ~~~~~~~~~~~~
  5. This module contains critical utilities that
  6. needs to be loaded as soon as possible, and that
  7. shall not load any third party modules.
  8. :copyright: (c) 2009 - 2012 by Ask Solem.
  9. :license: BSD, see LICENSE for more details.
  10. """
  11. from __future__ import absolute_import
  12. def try_import(module, default=None):
  13. """Try to import and return module, or return
  14. None if the module does not exist."""
  15. from importlib import import_module
  16. try:
  17. return import_module(module)
  18. except ImportError:
  19. return default
  20. class Proxy(object):
  21. """Proxy to another object."""
  22. # Code stolen from werkzeug.local.Proxy.
  23. __slots__ = ('__local', '__args', '__kwargs', '__dict__', '__name__')
  24. def __init__(self, local, args=None, kwargs=None, name=None):
  25. object.__setattr__(self, '_Proxy__local', local)
  26. object.__setattr__(self, '_Proxy__args', args or ())
  27. object.__setattr__(self, '_Proxy__kwargs', kwargs or {})
  28. if name is not None:
  29. object.__setattr__(self, '__custom_name__', name)
  30. @property
  31. def __name__(self):
  32. try:
  33. return self.__custom_name__
  34. except AttributeError:
  35. return self._get_current_object().__name__
  36. @property
  37. def __doc__(self):
  38. return self._get_current_object().__doc__
  39. @property
  40. def __class__(self):
  41. return self._get_current_object().__class__
  42. def _get_current_object(self):
  43. """Return the current object. This is useful if you want the real
  44. object behind the proxy at a time for performance reasons or because
  45. you want to pass the object into a different context.
  46. """
  47. if not hasattr(self.__local, '__release_local__'):
  48. return self.__local(*self.__args, **self.__kwargs)
  49. try:
  50. return getattr(self.__local, self.__name__)
  51. except AttributeError:
  52. raise RuntimeError('no object bound to %s' % self.__name__)
  53. @property
  54. def __dict__(self):
  55. try:
  56. return self._get_current_object().__dict__
  57. except RuntimeError: # pragma: no cover
  58. raise AttributeError('__dict__')
  59. def __repr__(self):
  60. try:
  61. obj = self._get_current_object()
  62. except RuntimeError: # pragma: no cover
  63. return '<%s unbound>' % self.__class__.__name__
  64. return repr(obj)
  65. def __nonzero__(self):
  66. try:
  67. return bool(self._get_current_object())
  68. except RuntimeError: # pragma: no cover
  69. return False
  70. def __unicode__(self):
  71. try:
  72. return unicode(self._get_current_object())
  73. except RuntimeError: # pragma: no cover
  74. return repr(self)
  75. def __dir__(self):
  76. try:
  77. return dir(self._get_current_object())
  78. except RuntimeError: # pragma: no cover
  79. return []
  80. def __getattr__(self, name):
  81. if name == '__members__':
  82. return dir(self._get_current_object())
  83. return getattr(self._get_current_object(), name)
  84. def __setitem__(self, key, value):
  85. self._get_current_object()[key] = value
  86. def __delitem__(self, key):
  87. del self._get_current_object()[key]
  88. def __setslice__(self, i, j, seq):
  89. self._get_current_object()[i:j] = seq
  90. def __delslice__(self, i, j):
  91. del self._get_current_object()[i:j]
  92. __setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v)
  93. __delattr__ = lambda x, n: delattr(x._get_current_object(), n)
  94. __str__ = lambda x: str(x._get_current_object())
  95. __lt__ = lambda x, o: x._get_current_object() < o
  96. __le__ = lambda x, o: x._get_current_object() <= o
  97. __eq__ = lambda x, o: x._get_current_object() == o
  98. __ne__ = lambda x, o: x._get_current_object() != o
  99. __gt__ = lambda x, o: x._get_current_object() > o
  100. __ge__ = lambda x, o: x._get_current_object() >= o
  101. __cmp__ = lambda x, o: cmp(x._get_current_object(), o)
  102. __hash__ = lambda x: hash(x._get_current_object())
  103. __call__ = lambda x, *a, **kw: x._get_current_object()(*a, **kw)
  104. __len__ = lambda x: len(x._get_current_object())
  105. __getitem__ = lambda x, i: x._get_current_object()[i]
  106. __iter__ = lambda x: iter(x._get_current_object())
  107. __contains__ = lambda x, i: i in x._get_current_object()
  108. __getslice__ = lambda x, i, j: x._get_current_object()[i:j]
  109. __add__ = lambda x, o: x._get_current_object() + o
  110. __sub__ = lambda x, o: x._get_current_object() - o
  111. __mul__ = lambda x, o: x._get_current_object() * o
  112. __floordiv__ = lambda x, o: x._get_current_object() // o
  113. __mod__ = lambda x, o: x._get_current_object() % o
  114. __divmod__ = lambda x, o: x._get_current_object().__divmod__(o)
  115. __pow__ = lambda x, o: x._get_current_object() ** o
  116. __lshift__ = lambda x, o: x._get_current_object() << o
  117. __rshift__ = lambda x, o: x._get_current_object() >> o
  118. __and__ = lambda x, o: x._get_current_object() & o
  119. __xor__ = lambda x, o: x._get_current_object() ^ o
  120. __or__ = lambda x, o: x._get_current_object() | o
  121. __div__ = lambda x, o: x._get_current_object().__div__(o)
  122. __truediv__ = lambda x, o: x._get_current_object().__truediv__(o)
  123. __neg__ = lambda x: -(x._get_current_object())
  124. __pos__ = lambda x: +(x._get_current_object())
  125. __abs__ = lambda x: abs(x._get_current_object())
  126. __invert__ = lambda x: ~(x._get_current_object())
  127. __complex__ = lambda x: complex(x._get_current_object())
  128. __int__ = lambda x: int(x._get_current_object())
  129. __long__ = lambda x: long(x._get_current_object())
  130. __float__ = lambda x: float(x._get_current_object())
  131. __oct__ = lambda x: oct(x._get_current_object())
  132. __hex__ = lambda x: hex(x._get_current_object())
  133. __index__ = lambda x: x._get_current_object().__index__()
  134. __coerce__ = lambda x, o: x.__coerce__(x, o)
  135. __enter__ = lambda x: x._get_current_object().__enter__()
  136. __exit__ = lambda x, *a, **kw: x._get_current_object().__exit__(*a, **kw)
  137. __reduce__ = lambda x: x._get_current_object().__reduce__()
  138. class PromiseProxy(Proxy):
  139. """This is a proxy to an object that has not yet been evaulated.
  140. :class:`Proxy` will evaluate the object each time, while the
  141. promise will only evaluate it once.
  142. """
  143. def _get_current_object(self):
  144. try:
  145. return object.__getattribute__(self, "__thing")
  146. except AttributeError:
  147. return self.__evaluate__()
  148. def __maybe_evaluate__(self):
  149. return self._get_current_object()
  150. def __evaluate__(self):
  151. thing = Proxy._get_current_object(self)
  152. object.__setattr__(self, "__thing", thing)
  153. return thing
  154. def maybe_evaluate(obj):
  155. try:
  156. return obj.__maybe_evaluate__()
  157. except AttributeError:
  158. return obj