local.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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. Parts of this module is Copyright by Werkzeug Team.
  9. """
  10. from __future__ import absolute_import
  11. import importlib
  12. import sys
  13. def symbol_by_name(name, aliases={}, imp=None, package=None,
  14. sep='.', default=None, **kwargs):
  15. """Get symbol by qualified name.
  16. The name should be the full dot-separated path to the class::
  17. modulename.ClassName
  18. Example::
  19. celery.concurrency.processes.TaskPool
  20. ^- class name
  21. or using ':' to separate module and symbol::
  22. celery.concurrency.processes:TaskPool
  23. If `aliases` is provided, a dict containing short name/long name
  24. mappings, the name is looked up in the aliases first.
  25. Examples:
  26. >>> symbol_by_name('celery.concurrency.processes.TaskPool')
  27. <class 'celery.concurrency.processes.TaskPool'>
  28. >>> symbol_by_name('default', {
  29. ... 'default': 'celery.concurrency.processes.TaskPool'})
  30. <class 'celery.concurrency.processes.TaskPool'>
  31. # Does not try to look up non-string names.
  32. >>> from celery.concurrency.processes import TaskPool
  33. >>> symbol_by_name(TaskPool) is TaskPool
  34. True
  35. """
  36. if imp is None:
  37. imp = importlib.import_module
  38. if not isinstance(name, basestring):
  39. return name # already a class
  40. name = aliases.get(name) or name
  41. sep = ':' if ':' in name else sep
  42. module_name, _, cls_name = name.rpartition(sep)
  43. if not module_name:
  44. cls_name, module_name = None, package if package else cls_name
  45. try:
  46. try:
  47. module = imp(module_name, package=package, **kwargs)
  48. except ValueError, exc:
  49. raise ValueError, ValueError(
  50. "Couldn't import %r: %s" % (name, exc)), sys.exc_info()[2]
  51. return getattr(module, cls_name) if cls_name else module
  52. except (ImportError, AttributeError):
  53. if default is None:
  54. raise
  55. return default
  56. def try_import(module, default=None):
  57. """Try to import and return module, or return
  58. None if the module does not exist."""
  59. try:
  60. return importlib.import_module(module)
  61. except ImportError:
  62. return default
  63. class Proxy(object):
  64. """Proxy to another object."""
  65. # Code stolen from werkzeug.local.Proxy.
  66. __slots__ = ('__local', '__args', '__kwargs', '__dict__', '__name__')
  67. def __init__(self, local, args=None, kwargs=None, name=None):
  68. object.__setattr__(self, '_Proxy__local', local)
  69. object.__setattr__(self, '_Proxy__args', args or ())
  70. object.__setattr__(self, '_Proxy__kwargs', kwargs or {})
  71. if name is not None:
  72. object.__setattr__(self, '__custom_name__', name)
  73. @property
  74. def __name__(self):
  75. try:
  76. return self.__custom_name__
  77. except AttributeError:
  78. return self._get_current_object().__name__
  79. @property
  80. def __module__(self):
  81. return self._get_current_object().__module__
  82. @property
  83. def __doc__(self):
  84. return self._get_current_object().__doc__
  85. def _get_class(self):
  86. return self._get_current_object().__class__
  87. @property
  88. def __class__(self):
  89. return self._get_class()
  90. def _get_current_object(self):
  91. """Return the current object. This is useful if you want the real
  92. object behind the proxy at a time for performance reasons or because
  93. you want to pass the object into a different context.
  94. """
  95. if not hasattr(self.__local, '__release_local__'):
  96. return self.__local(*self.__args, **self.__kwargs)
  97. try:
  98. return getattr(self.__local, self.__name__)
  99. except AttributeError:
  100. raise RuntimeError('no object bound to %s' % self.__name__)
  101. @property
  102. def __dict__(self):
  103. try:
  104. return self._get_current_object().__dict__
  105. except RuntimeError: # pragma: no cover
  106. raise AttributeError('__dict__')
  107. def __repr__(self):
  108. try:
  109. obj = self._get_current_object()
  110. except RuntimeError: # pragma: no cover
  111. return '<%s unbound>' % self.__class__.__name__
  112. return repr(obj)
  113. def __nonzero__(self):
  114. try:
  115. return bool(self._get_current_object())
  116. except RuntimeError: # pragma: no cover
  117. return False
  118. def __unicode__(self):
  119. try:
  120. return unicode(self._get_current_object())
  121. except RuntimeError: # pragma: no cover
  122. return repr(self)
  123. def __dir__(self):
  124. try:
  125. return dir(self._get_current_object())
  126. except RuntimeError: # pragma: no cover
  127. return []
  128. def __getattr__(self, name):
  129. if name == '__members__':
  130. return dir(self._get_current_object())
  131. return getattr(self._get_current_object(), name)
  132. def __setitem__(self, key, value):
  133. self._get_current_object()[key] = value
  134. def __delitem__(self, key):
  135. del self._get_current_object()[key]
  136. def __setslice__(self, i, j, seq):
  137. self._get_current_object()[i:j] = seq
  138. def __delslice__(self, i, j):
  139. del self._get_current_object()[i:j]
  140. __setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v)
  141. __delattr__ = lambda x, n: delattr(x._get_current_object(), n)
  142. __str__ = lambda x: str(x._get_current_object())
  143. __lt__ = lambda x, o: x._get_current_object() < o
  144. __le__ = lambda x, o: x._get_current_object() <= o
  145. __eq__ = lambda x, o: x._get_current_object() == o
  146. __ne__ = lambda x, o: x._get_current_object() != o
  147. __gt__ = lambda x, o: x._get_current_object() > o
  148. __ge__ = lambda x, o: x._get_current_object() >= o
  149. __cmp__ = lambda x, o: cmp(x._get_current_object(), o)
  150. __hash__ = lambda x: hash(x._get_current_object())
  151. __call__ = lambda x, *a, **kw: x._get_current_object()(*a, **kw)
  152. __len__ = lambda x: len(x._get_current_object())
  153. __getitem__ = lambda x, i: x._get_current_object()[i]
  154. __iter__ = lambda x: iter(x._get_current_object())
  155. __contains__ = lambda x, i: i in x._get_current_object()
  156. __getslice__ = lambda x, i, j: x._get_current_object()[i:j]
  157. __add__ = lambda x, o: x._get_current_object() + o
  158. __sub__ = lambda x, o: x._get_current_object() - o
  159. __mul__ = lambda x, o: x._get_current_object() * o
  160. __floordiv__ = lambda x, o: x._get_current_object() // o
  161. __mod__ = lambda x, o: x._get_current_object() % o
  162. __divmod__ = lambda x, o: x._get_current_object().__divmod__(o)
  163. __pow__ = lambda x, o: x._get_current_object() ** o
  164. __lshift__ = lambda x, o: x._get_current_object() << o
  165. __rshift__ = lambda x, o: x._get_current_object() >> o
  166. __and__ = lambda x, o: x._get_current_object() & o
  167. __xor__ = lambda x, o: x._get_current_object() ^ o
  168. __or__ = lambda x, o: x._get_current_object() | o
  169. __div__ = lambda x, o: x._get_current_object().__div__(o)
  170. __truediv__ = lambda x, o: x._get_current_object().__truediv__(o)
  171. __neg__ = lambda x: -(x._get_current_object())
  172. __pos__ = lambda x: +(x._get_current_object())
  173. __abs__ = lambda x: abs(x._get_current_object())
  174. __invert__ = lambda x: ~(x._get_current_object())
  175. __complex__ = lambda x: complex(x._get_current_object())
  176. __int__ = lambda x: int(x._get_current_object())
  177. __long__ = lambda x: long(x._get_current_object())
  178. __float__ = lambda x: float(x._get_current_object())
  179. __oct__ = lambda x: oct(x._get_current_object())
  180. __hex__ = lambda x: hex(x._get_current_object())
  181. __index__ = lambda x: x._get_current_object().__index__()
  182. __coerce__ = lambda x, o: x.__coerce__(x, o)
  183. __enter__ = lambda x: x._get_current_object().__enter__()
  184. __exit__ = lambda x, *a, **kw: x._get_current_object().__exit__(*a, **kw)
  185. __reduce__ = lambda x: x._get_current_object().__reduce__()
  186. class PromiseProxy(Proxy):
  187. """This is a proxy to an object that has not yet been evaulated.
  188. :class:`Proxy` will evaluate the object each time, while the
  189. promise will only evaluate it once.
  190. """
  191. def _get_current_object(self):
  192. try:
  193. return object.__getattribute__(self, '__thing')
  194. except AttributeError:
  195. return self.__evaluate__()
  196. def __evaluated__(self):
  197. try:
  198. object.__getattribute__(self, '__thing')
  199. except AttributeError:
  200. return False
  201. return True
  202. def __maybe_evaluate__(self):
  203. return self._get_current_object()
  204. def __evaluate__(self):
  205. try:
  206. thing = Proxy._get_current_object(self)
  207. object.__setattr__(self, '__thing', thing)
  208. return thing
  209. finally:
  210. object.__delattr__(self, '_Proxy__local')
  211. object.__delattr__(self, '_Proxy__args')
  212. object.__delattr__(self, '_Proxy__kwargs')
  213. def maybe_evaluate(obj):
  214. try:
  215. return obj.__maybe_evaluate__()
  216. except AttributeError:
  217. return obj