local.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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. from .five import long_t, string, string_t
  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, string_t):
  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 as exc:
  49. raise ValueError("Couldn't import %r: %s" % (name, exc))
  50. return getattr(module, cls_name) if cls_name else module
  51. except (ImportError, AttributeError):
  52. if default is None:
  53. raise
  54. return default
  55. def try_import(module, default=None):
  56. """Try to import and return module, or return
  57. None if the module does not exist."""
  58. try:
  59. return importlib.import_module(module)
  60. except ImportError:
  61. return default
  62. class Proxy(object):
  63. """Proxy to another object."""
  64. # Code stolen from werkzeug.local.Proxy.
  65. __slots__ = ('__local', '__args', '__kwargs', '__dict__')
  66. def __init__(self, local, args=None, kwargs=None, name=None):
  67. object.__setattr__(self, '_Proxy__local', local)
  68. object.__setattr__(self, '_Proxy__args', args or ())
  69. object.__setattr__(self, '_Proxy__kwargs', kwargs or {})
  70. if name is not None:
  71. object.__setattr__(self, '__custom_name__', name)
  72. @property
  73. def __name__(self):
  74. try:
  75. return self.__custom_name__
  76. except AttributeError:
  77. return self._get_current_object().__name__
  78. @property
  79. def __module__(self):
  80. return self._get_current_object().__module__
  81. @property
  82. def __doc__(self):
  83. return self._get_current_object().__doc__
  84. def _get_class(self):
  85. return self._get_current_object().__class__
  86. @property
  87. def __class__(self):
  88. return self._get_class()
  89. def _get_current_object(self):
  90. """Return the current object. This is useful if you want the real
  91. object behind the proxy at a time for performance reasons or because
  92. you want to pass the object into a different context.
  93. """
  94. if not hasattr(self.__local, '__release_local__'):
  95. return self.__local(*self.__args, **self.__kwargs)
  96. try:
  97. return getattr(self.__local, self.__name__)
  98. except AttributeError:
  99. raise RuntimeError('no object bound to {0.__name__}'.format(self))
  100. @property
  101. def __dict__(self):
  102. try:
  103. return self._get_current_object().__dict__
  104. except RuntimeError: # pragma: no cover
  105. raise AttributeError('__dict__')
  106. def __repr__(self):
  107. try:
  108. obj = self._get_current_object()
  109. except RuntimeError: # pragma: no cover
  110. return '<{0} unbound>'.format(self.__class__.__name__)
  111. return repr(obj)
  112. def __bool__(self):
  113. try:
  114. return bool(self._get_current_object())
  115. except RuntimeError: # pragma: no cover
  116. return False
  117. __nonzero__ = __bool__ # Py2
  118. def __unicode__(self):
  119. try:
  120. return string(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_t(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