test_local.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. from __future__ import absolute_import, unicode_literals
  2. import pytest
  3. import sys
  4. from case import Mock, skip
  5. from celery.five import python_2_unicode_compatible, string, long_t
  6. from celery.local import (
  7. Proxy,
  8. PromiseProxy,
  9. maybe_evaluate,
  10. try_import,
  11. )
  12. PY3 = sys.version_info[0] == 3
  13. class test_try_import:
  14. def test_imports(self):
  15. assert try_import(__name__)
  16. def test_when_default(self):
  17. default = object()
  18. assert try_import('foobar.awqewqe.asdwqewq', default) is default
  19. class test_Proxy:
  20. def test_std_class_attributes(self):
  21. assert Proxy.__name__ == 'Proxy'
  22. assert Proxy.__module__ == 'celery.local'
  23. assert isinstance(Proxy.__doc__, str)
  24. def test_doc(self):
  25. def real():
  26. pass
  27. x = Proxy(real, __doc__='foo')
  28. assert x.__doc__ == 'foo'
  29. def test_name(self):
  30. def real():
  31. """real function"""
  32. return 'REAL'
  33. x = Proxy(lambda: real, name='xyz')
  34. assert x.__name__ == 'xyz'
  35. y = Proxy(lambda: real)
  36. assert y.__name__ == 'real'
  37. assert x.__doc__ == 'real function'
  38. assert x.__class__ == type(real)
  39. assert x.__dict__ == real.__dict__
  40. assert repr(x) == repr(real)
  41. assert x.__module__
  42. def test_get_current_local(self):
  43. x = Proxy(lambda: 10)
  44. object.__setattr__(x, '_Proxy_local', Mock())
  45. assert x._get_current_object()
  46. def test_bool(self):
  47. class X(object):
  48. def __bool__(self):
  49. return False
  50. __nonzero__ = __bool__
  51. x = Proxy(lambda: X())
  52. assert not x
  53. def test_slots(self):
  54. class X(object):
  55. __slots__ = ()
  56. x = Proxy(X)
  57. with pytest.raises(AttributeError):
  58. x.__dict__
  59. @skip.if_python3()
  60. def test_unicode(self):
  61. @python_2_unicode_compatible
  62. class X(object):
  63. def __unicode__(self):
  64. return 'UNICODE'
  65. __str__ = __unicode__
  66. def __repr__(self):
  67. return 'REPR'
  68. x = Proxy(lambda: X())
  69. assert string(x) == 'UNICODE'
  70. del(X.__unicode__)
  71. del(X.__str__)
  72. assert string(x) == 'REPR'
  73. def test_dir(self):
  74. class X(object):
  75. def __dir__(self):
  76. return ['a', 'b', 'c']
  77. x = Proxy(lambda: X())
  78. assert dir(x) == ['a', 'b', 'c']
  79. class Y(object):
  80. def __dir__(self):
  81. raise RuntimeError()
  82. y = Proxy(lambda: Y())
  83. assert dir(y) == []
  84. def test_getsetdel_attr(self):
  85. class X(object):
  86. a = 1
  87. b = 2
  88. c = 3
  89. def __dir__(self):
  90. return ['a', 'b', 'c']
  91. v = X()
  92. x = Proxy(lambda: v)
  93. assert x.__members__ == ['a', 'b', 'c']
  94. assert x.a == 1
  95. assert x.b == 2
  96. assert x.c == 3
  97. setattr(x, 'a', 10)
  98. assert x.a == 10
  99. del(x.a)
  100. assert x.a == 1
  101. def test_dictproxy(self):
  102. v = {}
  103. x = Proxy(lambda: v)
  104. x['foo'] = 42
  105. assert x['foo'] == 42
  106. assert len(x) == 1
  107. assert 'foo' in x
  108. del(x['foo'])
  109. with pytest.raises(KeyError):
  110. x['foo']
  111. assert iter(x)
  112. def test_listproxy(self):
  113. v = []
  114. x = Proxy(lambda: v)
  115. x.append(1)
  116. x.extend([2, 3, 4])
  117. assert x[0] == 1
  118. assert x[:-1] == [1, 2, 3]
  119. del(x[-1])
  120. assert x[:-1] == [1, 2]
  121. x[0] = 10
  122. assert x[0] == 10
  123. assert 10 in x
  124. assert len(x) == 3
  125. assert iter(x)
  126. x[0:2] = [1, 2]
  127. del(x[0:2])
  128. assert str(x)
  129. if sys.version_info[0] < 3:
  130. assert x.__cmp__(object()) == -1
  131. def test_complex_cast(self):
  132. class O(object):
  133. def __complex__(self):
  134. return complex(10.333)
  135. o = Proxy(O)
  136. assert o.__complex__() == complex(10.333)
  137. def test_index(self):
  138. class O(object):
  139. def __index__(self):
  140. return 1
  141. o = Proxy(O)
  142. assert o.__index__() == 1
  143. def test_coerce(self):
  144. class O(object):
  145. def __coerce__(self, other):
  146. return self, other
  147. o = Proxy(O)
  148. assert o.__coerce__(3)
  149. def test_int(self):
  150. assert Proxy(lambda: 10) + 1 == Proxy(lambda: 11)
  151. assert Proxy(lambda: 10) - 1 == Proxy(lambda: 9)
  152. assert Proxy(lambda: 10) * 2 == Proxy(lambda: 20)
  153. assert Proxy(lambda: 10) ** 2 == Proxy(lambda: 100)
  154. assert Proxy(lambda: 20) / 2 == Proxy(lambda: 10)
  155. assert Proxy(lambda: 20) // 2 == Proxy(lambda: 10)
  156. assert Proxy(lambda: 11) % 2 == Proxy(lambda: 1)
  157. assert Proxy(lambda: 10) << 2 == Proxy(lambda: 40)
  158. assert Proxy(lambda: 10) >> 2 == Proxy(lambda: 2)
  159. assert Proxy(lambda: 10) ^ 7 == Proxy(lambda: 13)
  160. assert Proxy(lambda: 10) | 40 == Proxy(lambda: 42)
  161. assert Proxy(lambda: 10) != Proxy(lambda: -11)
  162. assert Proxy(lambda: 10) != Proxy(lambda: -10)
  163. assert Proxy(lambda: -10) == Proxy(lambda: -10)
  164. assert Proxy(lambda: 10) < Proxy(lambda: 20)
  165. assert Proxy(lambda: 20) > Proxy(lambda: 10)
  166. assert Proxy(lambda: 10) >= Proxy(lambda: 10)
  167. assert Proxy(lambda: 10) <= Proxy(lambda: 10)
  168. assert Proxy(lambda: 10) == Proxy(lambda: 10)
  169. assert Proxy(lambda: 20) != Proxy(lambda: 10)
  170. assert Proxy(lambda: 100).__divmod__(30)
  171. assert Proxy(lambda: 100).__truediv__(30)
  172. assert abs(Proxy(lambda: -100))
  173. x = Proxy(lambda: 10)
  174. x -= 1
  175. assert x == 9
  176. x = Proxy(lambda: 9)
  177. x += 1
  178. assert x == 10
  179. x = Proxy(lambda: 10)
  180. x *= 2
  181. assert x == 20
  182. x = Proxy(lambda: 20)
  183. x /= 2
  184. assert x == 10
  185. x = Proxy(lambda: 10)
  186. x %= 2
  187. assert x == 0
  188. x = Proxy(lambda: 10)
  189. x <<= 3
  190. assert x == 80
  191. x = Proxy(lambda: 80)
  192. x >>= 4
  193. assert x == 5
  194. x = Proxy(lambda: 5)
  195. x ^= 1
  196. assert x == 4
  197. x = Proxy(lambda: 4)
  198. x **= 4
  199. assert x == 256
  200. x = Proxy(lambda: 256)
  201. x //= 2
  202. assert x == 128
  203. x = Proxy(lambda: 128)
  204. x |= 2
  205. assert x == 130
  206. x = Proxy(lambda: 130)
  207. x &= 10
  208. assert x == 2
  209. x = Proxy(lambda: 10)
  210. assert type(x.__float__()) == float
  211. assert type(x.__int__()) == int
  212. if not PY3:
  213. assert type(x.__long__()) == long_t
  214. assert hex(x)
  215. assert oct(x)
  216. def test_hash(self):
  217. class X(object):
  218. def __hash__(self):
  219. return 1234
  220. assert hash(Proxy(lambda: X())) == 1234
  221. def test_call(self):
  222. class X(object):
  223. def __call__(self):
  224. return 1234
  225. assert Proxy(lambda: X())() == 1234
  226. def test_context(self):
  227. class X(object):
  228. entered = exited = False
  229. def __enter__(self):
  230. self.entered = True
  231. return 1234
  232. def __exit__(self, *exc_info):
  233. self.exited = True
  234. v = X()
  235. x = Proxy(lambda: v)
  236. with x as val:
  237. assert val == 1234
  238. assert x.entered
  239. assert x.exited
  240. def test_reduce(self):
  241. class X(object):
  242. def __reduce__(self):
  243. return 123
  244. x = Proxy(lambda: X())
  245. assert x.__reduce__() == 123
  246. class test_PromiseProxy:
  247. def test_only_evaluated_once(self):
  248. class X(object):
  249. attr = 123
  250. evals = 0
  251. def __init__(self):
  252. self.__class__.evals += 1
  253. p = PromiseProxy(X)
  254. assert p.attr == 123
  255. assert p.attr == 123
  256. assert X.evals == 1
  257. def test_callbacks(self):
  258. source = Mock(name='source')
  259. p = PromiseProxy(source)
  260. cbA = Mock(name='cbA')
  261. cbB = Mock(name='cbB')
  262. cbC = Mock(name='cbC')
  263. p.__then__(cbA, p)
  264. p.__then__(cbB, p)
  265. assert not p.__evaluated__()
  266. assert object.__getattribute__(p, '__pending__')
  267. assert repr(p)
  268. assert p.__evaluated__()
  269. with pytest.raises(AttributeError):
  270. object.__getattribute__(p, '__pending__')
  271. cbA.assert_called_with(p)
  272. cbB.assert_called_with(p)
  273. assert p.__evaluated__()
  274. p.__then__(cbC, p)
  275. cbC.assert_called_with(p)
  276. with pytest.raises(AttributeError):
  277. object.__getattribute__(p, '__pending__')
  278. def test_maybe_evaluate(self):
  279. x = PromiseProxy(lambda: 30)
  280. assert not x.__evaluated__()
  281. assert maybe_evaluate(x) == 30
  282. assert maybe_evaluate(x) == 30
  283. assert maybe_evaluate(30) == 30
  284. assert x.__evaluated__()