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