Completed
Push — master ( b2b0a5...3849b1 )
by Ionel Cristian
57s
created

tests.SimpleProxy   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 9
Duplicated Lines 0 %
Metric Value
dl 0
loc 9
rs 10
wmc 3
1
from __future__ import print_function
2
3
import imp
4
import pickle
5
import platform
6
import sys
7
import weakref
8
from datetime import date
9
from datetime import datetime
10
from decimal import Decimal
11
from functools import partial
12
import gc
13
14
import pytest
15
16
from compat import PY2, PY3, exec_
17
18
PYPY = '__pypy__' in sys.builtin_module_names
19
20
OBJECTS_CODE = """
21
class TargetBaseClass(object):
22
    "documentation"
23
24
class Target(TargetBaseClass):
25
    "documentation"
26
27
def target():
28
    "documentation"
29
    pass
30
"""
31
32
objects = imp.new_module('objects')
33
exec_(OBJECTS_CODE, objects.__dict__, objects.__dict__)
34
35
36
def load_implementation(name):
37
    class FakeModule:
38
        subclass = False
39
        kind = name
40
        if name == "slots":
41
            from lazy_object_proxy.slots import Proxy
42
        elif name == "simple":
43
            from lazy_object_proxy.simple import Proxy
44
        elif name == "cext":
45
            try:
46
                from lazy_object_proxy.cext import Proxy
47
            except ImportError:
48
                if PYPY:
49
                    pytest.skip(msg="C Extension not available.")
50
                else:
51
                    raise
52
        elif name == "objproxies":
53
            Proxy = pytest.importorskip("objproxies").LazyProxy
54
        elif name == "django":
55
            Proxy = pytest.importorskip("django.utils.functional").SimpleLazyObject
56
        else:
57
            raise RuntimeError("Unsupported param: %r." % name)
58
59
        Proxy
60
61
    return FakeModule
62
63
64
@pytest.fixture(scope="module", params=[
65
    "slots", "cext",
66
    "simple",
67
    # "external-django", "external-objproxies"
68
])
69
def lop_implementation(request):
70
    return load_implementation(request.param)
71
72
73
@pytest.fixture(scope="module", params=[True, False], ids=['subclassed', 'normal'])
74
def lop_subclass(request, lop_implementation):
75
    if request.param:
76
        class submod(lop_implementation):
77
            subclass = True
78
            Proxy = type("SubclassOf_" + lop_implementation.Proxy.__name__,
79
                         (lop_implementation.Proxy,), {})
80
81
        return submod
82
    else:
83
        return lop_implementation
84
85
86
@pytest.fixture(scope="function")
87
def lazy_object_proxy(request, lop_subclass):
88
    if request.node.get_marker('xfail_subclass'):
89
        request.applymarker(pytest.mark.xfail(
90
            reason="This test can't work because subclassing disables certain "
91
                   "features like __doc__ and __module__ proxying."
92
        ))
93
    if request.node.get_marker('xfail_simple'):
94
        request.applymarker(pytest.mark.xfail(
95
            reason="The lazy_object_proxy.simple.Proxy has some limitations."
96
        ))
97
98
    return lop_subclass
99
100
101
def test_round(lazy_object_proxy):
102
    proxy = lazy_object_proxy.Proxy(lambda: 1.2)
103
    assert round(proxy) == 1
104
105
106
def test_attributes(lazy_object_proxy):
107
    def function1(*args, **kwargs):
108
        return args, kwargs
109
110
    function2 = lazy_object_proxy.Proxy(lambda: function1)
111
112
    assert function2.__wrapped__ == function1
113
114
115
def test_get_wrapped(lazy_object_proxy):
116
    def function1(*args, **kwargs):
117
        return args, kwargs
118
119
    function2 = lazy_object_proxy.Proxy(lambda: function1)
120
121
    assert function2.__wrapped__ == function1
122
123
    function3 = lazy_object_proxy.Proxy(lambda: function2)
124
125
    assert function3.__wrapped__ == function1
126
127
128
def test_set_wrapped(lazy_object_proxy):
129
    def function1(*args, **kwargs):
130
        return args, kwargs
131
132
    function2 = lazy_object_proxy.Proxy(lambda: function1)
133
134
    assert function2 == function1
135
    assert function2.__wrapped__ is function1
136
    assert function2.__name__ == function1.__name__
137
138
    if PY3:
139
        assert function2.__qualname__ == function1.__qualname__
140
141
    function2.__wrapped__ = None
142
143
    assert not hasattr(function1, '__wrapped__')
144
145
    assert function2 == None
146
    assert function2.__wrapped__ is None
147
    assert not hasattr(function2, '__name__')
148
149
    if PY3:
150
        assert not hasattr(function2, '__qualname__')
151
152
    def function3(*args, **kwargs):
153
        return args, kwargs
154
155
    function2.__wrapped__ = function3
156
157
    assert function2 == function3
158
    assert function2.__wrapped__ == function3
159
    assert function2.__name__ == function3.__name__
160
161
    if PY3:
162
        assert function2.__qualname__ == function3.__qualname__
163
164
165
def test_wrapped_attribute(lazy_object_proxy):
166
    def function1(*args, **kwargs):
167
        return args, kwargs
168
169
    function2 = lazy_object_proxy.Proxy(lambda: function1)
170
171
    function2.variable = True
172
173
    assert hasattr(function1, 'variable')
174
    assert hasattr(function2, 'variable')
175
176
    assert function2.variable == True
177
178
    del function2.variable
179
180
    assert not hasattr(function1, 'variable')
181
    assert not hasattr(function2, 'variable')
182
183
    assert getattr(function2, 'variable', None) == None
184
185
186
def test_class_object_name(lazy_object_proxy):
187
    # Test preservation of class __name__ attribute.
188
189
    target = objects.Target
190
    wrapper = lazy_object_proxy.Proxy(lambda: target)
191
192
    assert wrapper.__name__ == target.__name__
193
194
195
def test_class_object_qualname(lazy_object_proxy):
196
    # Test preservation of class __qualname__ attribute.
197
198
    target = objects.Target
199
    wrapper = lazy_object_proxy.Proxy(lambda: target)
200
201
    try:
202
        __qualname__ = target.__qualname__
203
    except AttributeError:
204
        pass
205
    else:
206
        assert wrapper.__qualname__ == __qualname__
207
208
209
@pytest.mark.xfail_subclass
210
def test_class_module_name(lazy_object_proxy):
211
    # Test preservation of class __module__ attribute.
212
213
    target = objects.Target
214
    wrapper = lazy_object_proxy.Proxy(lambda: target)
215
216
    assert wrapper.__module__ == target.__module__
217
218
219
@pytest.mark.xfail_subclass
220
def test_class_doc_string(lazy_object_proxy):
221
    # Test preservation of class __doc__ attribute.
222
223
    target = objects.Target
224
    wrapper = lazy_object_proxy.Proxy(lambda: target)
225
226
    assert wrapper.__doc__ == target.__doc__
227
228
229
@pytest.mark.xfail_subclass
230
def test_instance_module_name(lazy_object_proxy):
231
    # Test preservation of instance __module__ attribute.
232
233
    target = objects.Target()
234
    wrapper = lazy_object_proxy.Proxy(lambda: target)
235
236
    assert wrapper.__module__ == target.__module__
237
238
239
@pytest.mark.xfail_subclass
240
def test_instance_doc_string(lazy_object_proxy):
241
    # Test preservation of instance __doc__ attribute.
242
243
    target = objects.Target()
244
    wrapper = lazy_object_proxy.Proxy(lambda: target)
245
246
    assert wrapper.__doc__ == target.__doc__
247
248
249
def test_function_object_name(lazy_object_proxy):
250
    # Test preservation of function __name__ attribute.
251
252
    target = objects.target
253
    wrapper = lazy_object_proxy.Proxy(lambda: target)
254
255
    assert wrapper.__name__ == target.__name__
256
257
258
def test_function_object_qualname(lazy_object_proxy):
259
    # Test preservation of function __qualname__ attribute.
260
261
    target = objects.target
262
    wrapper = lazy_object_proxy.Proxy(lambda: target)
263
264
    try:
265
        __qualname__ = target.__qualname__
266
    except AttributeError:
267
        pass
268
    else:
269
        assert wrapper.__qualname__ == __qualname__
270
271
272
@pytest.mark.xfail_subclass
273
def test_function_module_name(lazy_object_proxy):
274
    # Test preservation of function __module__ attribute.
275
276
    target = objects.target
277
    wrapper = lazy_object_proxy.Proxy(lambda: target)
278
279
    assert wrapper.__module__ == target.__module__
280
281
282
@pytest.mark.xfail_subclass
283
def test_function_doc_string(lazy_object_proxy):
284
    # Test preservation of function __doc__ attribute.
285
286
    target = objects.target
287
    wrapper = lazy_object_proxy.Proxy(lambda: target)
288
289
    assert wrapper.__doc__ == target.__doc__
290
291
292
def test_class_of_class(lazy_object_proxy):
293
    # Test preservation of class __class__ attribute.
294
295
    target = objects.Target
296
    wrapper = lazy_object_proxy.Proxy(lambda: target)
297
298
    assert wrapper.__class__ is target.__class__
299
300
    assert isinstance(wrapper, type(target))
301
302
303
def test_revert_class_proxying(lazy_object_proxy):
304
    class ProxyWithOldStyleIsInstance(lazy_object_proxy.Proxy):
305
        __class__ = object.__dict__['__class__']
306
307
    target = objects.Target()
308
    wrapper = ProxyWithOldStyleIsInstance(lambda: target)
309
310
    assert wrapper.__class__ is ProxyWithOldStyleIsInstance
311
312
    assert isinstance(wrapper, ProxyWithOldStyleIsInstance)
313
    assert not isinstance(wrapper, objects.Target)
314
    assert not isinstance(wrapper, objects.TargetBaseClass)
315
316
    class ProxyWithOldStyleIsInstance2(ProxyWithOldStyleIsInstance):
317
        pass
318
319
    wrapper = ProxyWithOldStyleIsInstance2(lambda: target)
320
321
    assert wrapper.__class__ is ProxyWithOldStyleIsInstance2
322
323
    assert isinstance(wrapper, ProxyWithOldStyleIsInstance2)
324
    assert not isinstance(wrapper, objects.Target)
325
    assert not isinstance(wrapper, objects.TargetBaseClass)
326
327
328
def test_class_of_instance(lazy_object_proxy):
329
    # Test preservation of instance __class__ attribute.
330
331
    target = objects.Target()
332
    wrapper = lazy_object_proxy.Proxy(lambda: target)
333
334
    assert wrapper.__class__ is target.__class__
335
336
    assert isinstance(wrapper, objects.Target)
337
    assert isinstance(wrapper, objects.TargetBaseClass)
338
339
340
def test_class_of_function(lazy_object_proxy):
341
    # Test preservation of function __class__ attribute.
342
343
    target = objects.target
344
    wrapper = lazy_object_proxy.Proxy(lambda: target)
345
346
    assert wrapper.__class__ is target.__class__
347
348
    assert isinstance(wrapper, type(target))
349
350
351
def test_dir_of_class(lazy_object_proxy):
352
    # Test preservation of class __dir__ attribute.
353
354
    target = objects.Target
355
    wrapper = lazy_object_proxy.Proxy(lambda: target)
356
357
    assert dir(wrapper) == dir(target)
358
359
360
@pytest.mark.xfail_simple
361
def test_vars_of_class(lazy_object_proxy):
362
    # Test preservation of class __dir__ attribute.
363
364
    target = objects.Target
365
    wrapper = lazy_object_proxy.Proxy(lambda: target)
366
367
    assert vars(wrapper) == vars(target)
368
369
370
def test_dir_of_instance(lazy_object_proxy):
371
    # Test preservation of instance __dir__ attribute.
372
373
    target = objects.Target()
374
    wrapper = lazy_object_proxy.Proxy(lambda: target)
375
376
    assert dir(wrapper) == dir(target)
377
378
379
@pytest.mark.xfail_simple
380
def test_vars_of_instance(lazy_object_proxy):
381
    # Test preservation of instance __dir__ attribute.
382
383
    target = objects.Target()
384
    wrapper = lazy_object_proxy.Proxy(lambda: target)
385
386
    assert vars(wrapper) == vars(target)
387
388
389
def test_dir_of_function(lazy_object_proxy):
390
    # Test preservation of function __dir__ attribute.
391
392
    target = objects.target
393
    wrapper = lazy_object_proxy.Proxy(lambda: target)
394
395
    assert dir(wrapper) == dir(target)
396
397
398
@pytest.mark.xfail_simple
399
def test_vars_of_function(lazy_object_proxy):
400
    # Test preservation of function __dir__ attribute.
401
402
    target = objects.target
403
    wrapper = lazy_object_proxy.Proxy(lambda: target)
404
405
    assert vars(wrapper) == vars(target)
406
407
408
def test_function_no_args(lazy_object_proxy):
409
    _args = ()
410
    _kwargs = {}
411
412
    def function(*args, **kwargs):
413
        return args, kwargs
414
415
    wrapper = lazy_object_proxy.Proxy(lambda: function)
416
417
    result = wrapper()
418
419
    assert result, (_args == _kwargs)
420
421
422
def test_function_args(lazy_object_proxy):
423
    _args = (1, 2)
424
    _kwargs = {}
425
426
    def function(*args, **kwargs):
427
        return args, kwargs
428
429
    wrapper = lazy_object_proxy.Proxy(lambda: function)
430
431
    result = wrapper(*_args)
432
433
    assert result, (_args == _kwargs)
434
435
436
def test_function_kwargs(lazy_object_proxy):
437
    _args = ()
438
    _kwargs = {"one": 1, "two": 2}
439
440
    def function(*args, **kwargs):
441
        return args, kwargs
442
443
    wrapper = lazy_object_proxy.Proxy(lambda: function)
444
445
    result = wrapper(**_kwargs)
446
447
    assert result, (_args == _kwargs)
448
449
450
def test_function_args_plus_kwargs(lazy_object_proxy):
451
    _args = (1, 2)
452
    _kwargs = {"one": 1, "two": 2}
453
454
    def function(*args, **kwargs):
455
        return args, kwargs
456
457
    wrapper = lazy_object_proxy.Proxy(lambda: function)
458
459
    result = wrapper(*_args, **_kwargs)
460
461
    assert result, (_args == _kwargs)
462
463
464
def test_instancemethod_no_args(lazy_object_proxy):
465
    _args = ()
466
    _kwargs = {}
467
468
    class Class(object):
469
        def function(self, *args, **kwargs):
470
            return args, kwargs
471
472
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
473
474
    result = wrapper()
475
476
    assert result, (_args == _kwargs)
477
478
479
def test_instancemethod_args(lazy_object_proxy):
480
    _args = (1, 2)
481
    _kwargs = {}
482
483
    class Class(object):
484
        def function(self, *args, **kwargs):
485
            return args, kwargs
486
487
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
488
489
    result = wrapper(*_args)
490
491
    assert result, (_args == _kwargs)
492
493
494
def test_instancemethod_kwargs(lazy_object_proxy):
495
    _args = ()
496
    _kwargs = {"one": 1, "two": 2}
497
498
    class Class(object):
499
        def function(self, *args, **kwargs):
500
            return args, kwargs
501
502
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
503
504
    result = wrapper(**_kwargs)
505
506
    assert result, (_args == _kwargs)
507
508
509
def test_instancemethod_args_plus_kwargs(lazy_object_proxy):
510
    _args = (1, 2)
511
    _kwargs = {"one": 1, "two": 2}
512
513
    class Class(object):
514
        def function(self, *args, **kwargs):
515
            return args, kwargs
516
517
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
518
519
    result = wrapper(*_args, **_kwargs)
520
521
    assert result, (_args == _kwargs)
522
523
524
def test_instancemethod_via_class_no_args(lazy_object_proxy):
525
    _args = ()
526
    _kwargs = {}
527
528
    class Class(object):
529
        def function(self, *args, **kwargs):
530
            return args, kwargs
531
532
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
533
534
    result = wrapper(Class())
535
536
    assert result, (_args == _kwargs)
537
538
539
def test_instancemethod_via_class_args(lazy_object_proxy):
540
    _args = (1, 2)
541
    _kwargs = {}
542
543
    class Class(object):
544
        def function(self, *args, **kwargs):
545
            return args, kwargs
546
547
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
548
549
    result = wrapper(Class(), *_args)
550
551
    assert result, (_args == _kwargs)
552
553
554
def test_instancemethod_via_class_kwargs(lazy_object_proxy):
555
    _args = ()
556
    _kwargs = {"one": 1, "two": 2}
557
558
    class Class(object):
559
        def function(self, *args, **kwargs):
560
            return args, kwargs
561
562
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
563
564
    result = wrapper(Class(), **_kwargs)
565
566
    assert result, (_args == _kwargs)
567
568
569
def test_instancemethod_via_class_args_plus_kwargs(lazy_object_proxy):
570
    _args = (1, 2)
571
    _kwargs = {"one": 1, "two": 2}
572
573
    class Class(object):
574
        def function(self, *args, **kwargs):
575
            return args, kwargs
576
577
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
578
579
    result = wrapper(Class(), *_args, **_kwargs)
580
581
    assert result, (_args == _kwargs)
582
583
584
def test_classmethod_no_args(lazy_object_proxy):
585
    _args = ()
586
    _kwargs = {}
587
588
    class Class(object):
589
        @classmethod
590
        def function(cls, *args, **kwargs):
591
            return args, kwargs
592
593
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
594
595
    result = wrapper()
596
597
    assert result, (_args == _kwargs)
598
599
600
def test_classmethod_args(lazy_object_proxy):
601
    _args = (1, 2)
602
    _kwargs = {}
603
604
    class Class(object):
605
        @classmethod
606
        def function(cls, *args, **kwargs):
607
            return args, kwargs
608
609
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
610
611
    result = wrapper(*_args)
612
613
    assert result, (_args == _kwargs)
614
615
616
def test_classmethod_kwargs(lazy_object_proxy):
617
    _args = ()
618
    _kwargs = {"one": 1, "two": 2}
619
620
    class Class(object):
621
        @classmethod
622
        def function(cls, *args, **kwargs):
623
            return args, kwargs
624
625
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
626
627
    result = wrapper(**_kwargs)
628
629
    assert result, (_args == _kwargs)
630
631
632
def test_classmethod_args_plus_kwargs(lazy_object_proxy):
633
    _args = (1, 2)
634
    _kwargs = {"one": 1, "two": 2}
635
636
    class Class(object):
637
        @classmethod
638
        def function(cls, *args, **kwargs):
639
            return args, kwargs
640
641
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
642
643
    result = wrapper(*_args, **_kwargs)
644
645
    assert result, (_args == _kwargs)
646
647
648
def test_classmethod_via_class_no_args(lazy_object_proxy):
649
    _args = ()
650
    _kwargs = {}
651
652
    class Class(object):
653
        @classmethod
654
        def function(cls, *args, **kwargs):
655
            return args, kwargs
656
657
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
658
659
    result = wrapper()
660
661
    assert result, (_args == _kwargs)
662
663
664
def test_classmethod_via_class_args(lazy_object_proxy):
665
    _args = (1, 2)
666
    _kwargs = {}
667
668
    class Class(object):
669
        @classmethod
670
        def function(cls, *args, **kwargs):
671
            return args, kwargs
672
673
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
674
675
    result = wrapper(*_args)
676
677
    assert result, (_args == _kwargs)
678
679
680
def test_classmethod_via_class_kwargs(lazy_object_proxy):
681
    _args = ()
682
    _kwargs = {"one": 1, "two": 2}
683
684
    class Class(object):
685
        @classmethod
686
        def function(cls, *args, **kwargs):
687
            return args, kwargs
688
689
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
690
691
    result = wrapper(**_kwargs)
692
693
    assert result, (_args == _kwargs)
694
695
696
def test_classmethod_via_class_args_plus_kwargs(lazy_object_proxy):
697
    _args = (1, 2)
698
    _kwargs = {"one": 1, "two": 2}
699
700
    class Class(object):
701
        @classmethod
702
        def function(cls, *args, **kwargs):
703
            return args, kwargs
704
705
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
706
707
    result = wrapper(*_args, **_kwargs)
708
709
    assert result, (_args == _kwargs)
710
711
712
def test_staticmethod_no_args(lazy_object_proxy):
713
    _args = ()
714
    _kwargs = {}
715
716
    class Class(object):
717
        @staticmethod
718
        def function(*args, **kwargs):
719
            return args, kwargs
720
721
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
722
723
    result = wrapper()
724
725
    assert result, (_args == _kwargs)
726
727
728
def test_staticmethod_args(lazy_object_proxy):
729
    _args = (1, 2)
730
    _kwargs = {}
731
732
    class Class(object):
733
        @staticmethod
734
        def function(*args, **kwargs):
735
            return args, kwargs
736
737
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
738
739
    result = wrapper(*_args)
740
741
    assert result, (_args == _kwargs)
742
743
744
def test_staticmethod_kwargs(lazy_object_proxy):
745
    _args = ()
746
    _kwargs = {"one": 1, "two": 2}
747
748
    class Class(object):
749
        @staticmethod
750
        def function(*args, **kwargs):
751
            return args, kwargs
752
753
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
754
755
    result = wrapper(**_kwargs)
756
757
    assert result, (_args == _kwargs)
758
759
760
def test_staticmethod_args_plus_kwargs(lazy_object_proxy):
761
    _args = (1, 2)
762
    _kwargs = {"one": 1, "two": 2}
763
764
    class Class(object):
765
        @staticmethod
766
        def function(*args, **kwargs):
767
            return args, kwargs
768
769
    wrapper = lazy_object_proxy.Proxy(lambda: Class().function)
770
771
    result = wrapper(*_args, **_kwargs)
772
773
    assert result, (_args == _kwargs)
774
775
776
def test_staticmethod_via_class_no_args(lazy_object_proxy):
777
    _args = ()
778
    _kwargs = {}
779
780
    class Class(object):
781
        @staticmethod
782
        def function(*args, **kwargs):
783
            return args, kwargs
784
785
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
786
787
    result = wrapper()
788
789
    assert result, (_args == _kwargs)
790
791
792
def test_staticmethod_via_class_args(lazy_object_proxy):
793
    _args = (1, 2)
794
    _kwargs = {}
795
796
    class Class(object):
797
        @staticmethod
798
        def function(*args, **kwargs):
799
            return args, kwargs
800
801
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
802
803
    result = wrapper(*_args)
804
805
    assert result, (_args == _kwargs)
806
807
808
def test_staticmethod_via_class_kwargs(lazy_object_proxy):
809
    _args = ()
810
    _kwargs = {"one": 1, "two": 2}
811
812
    class Class(object):
813
        @staticmethod
814
        def function(*args, **kwargs):
815
            return args, kwargs
816
817
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
818
819
    result = wrapper(**_kwargs)
820
821
    assert result, (_args == _kwargs)
822
823
824
def test_staticmethod_via_class_args_plus_kwargs(lazy_object_proxy):
825
    _args = (1, 2)
826
    _kwargs = {"one": 1, "two": 2}
827
828
    class Class(object):
829
        @staticmethod
830
        def function(*args, **kwargs):
831
            return args, kwargs
832
833
    wrapper = lazy_object_proxy.Proxy(lambda: Class.function)
834
835
    result = wrapper(*_args, **_kwargs)
836
837
    assert result, (_args == _kwargs)
838
839
840
def test_iteration(lazy_object_proxy):
841
    items = [1, 2]
842
843
    wrapper = lazy_object_proxy.Proxy(lambda: items)
844
845
    result = [x for x in wrapper]
846
847
    assert result == items
848
849
    with pytest.raises(TypeError):
850
        for _ in lazy_object_proxy.Proxy(lambda: 1):
851
            pass
852
853
854
def test_iter_builtin(lazy_object_proxy):
855
    iter(lazy_object_proxy.Proxy(lambda: [1, 2]))
856
    pytest.raises(TypeError, iter, lazy_object_proxy.Proxy(lambda: 1))
857
858
859
def test_context_manager(lazy_object_proxy):
860
    class Class(object):
861
        def __enter__(self):
862
            return self
863
864
        def __exit__(*args, **kwargs):
865
            return
866
867
    instance = Class()
868
869
    wrapper = lazy_object_proxy.Proxy(lambda: instance)
870
871
    with wrapper:
872
        pass
873
874
875
def test_object_hash(lazy_object_proxy):
876
    def function1(*args, **kwargs):
877
        return args, kwargs
878
879
    function2 = lazy_object_proxy.Proxy(lambda: function1)
880
881
    assert hash(function2) == hash(function1)
882
883
884
def test_mapping_key(lazy_object_proxy):
885
    def function1(*args, **kwargs):
886
        return args, kwargs
887
888
    function2 = lazy_object_proxy.Proxy(lambda: function1)
889
890
    table = dict()
891
    table[function1] = True
892
893
    assert table.get(function2)
894
895
    table = dict()
896
    table[function2] = True
897
898
    assert table.get(function1)
899
900
901
def test_comparison(lazy_object_proxy):
902
    one = lazy_object_proxy.Proxy(lambda: 1)
903
    two = lazy_object_proxy.Proxy(lambda: 2)
904
    three = lazy_object_proxy.Proxy(lambda: 3)
905
906
    assert two > 1
907
    assert two >= 1
908
    assert two < 3
909
    assert two <= 3
910
    assert two != 1
911
    assert two == 2
912
    assert two != 3
913
914
    assert 2 > one
915
    assert 2 >= one
916
    assert 2 < three
917
    assert 2 <= three
918
    assert 2 != one
919
    assert 2 == two
920
    assert 2 != three
921
922
    assert two > one
923
    assert two >= one
924
    assert two < three
925
    assert two <= three
926
    assert two != one
927
    assert two == two
928
    assert two != three
929
930
931
def test_nonzero(lazy_object_proxy):
932
    true = lazy_object_proxy.Proxy(lambda: True)
933
    false = lazy_object_proxy.Proxy(lambda: False)
934
935
    assert true
936
    assert not false
937
938
    assert bool(true)
939
    assert not bool(false)
940
941
    assert not false
942
    assert not not true
943
944
945
def test_int(lazy_object_proxy):
946
    one = lazy_object_proxy.Proxy(lambda: 1)
947
948
    assert int(one) == 1
949
950
    if not PY3:
951
        assert long(one) == 1
952
953
954
def test_float(lazy_object_proxy):
955
    one = lazy_object_proxy.Proxy(lambda: 1)
956
957
    assert float(one) == 1.0
958
959
960
def test_add(lazy_object_proxy):
961
    one = lazy_object_proxy.Proxy(lambda: 1)
962
    two = lazy_object_proxy.Proxy(lambda: 2)
963
964
    assert one + two == 1 + 2
965
    assert 1 + two == 1 + 2
966
    assert one + 2 == 1 + 2
967
968
969
def test_sub(lazy_object_proxy):
970
    one = lazy_object_proxy.Proxy(lambda: 1)
971
    two = lazy_object_proxy.Proxy(lambda: 2)
972
973
    assert one - two == 1 - 2
974
    assert 1 - two == 1 - 2
975
    assert one - 2 == 1 - 2
976
977
978
def test_mul(lazy_object_proxy):
979
    two = lazy_object_proxy.Proxy(lambda: 2)
980
    three = lazy_object_proxy.Proxy(lambda: 3)
981
982
    assert two * three == 2 * 3
983
    assert 2 * three == 2 * 3
984
    assert two * 3 == 2 * 3
985
986
987
def test_div(lazy_object_proxy):
988
    # On Python 2 this will pick up div and on Python
989
    # 3 it will pick up truediv.
990
991
    two = lazy_object_proxy.Proxy(lambda: 2)
992
    three = lazy_object_proxy.Proxy(lambda: 3)
993
994
    assert two / three == 2 / 3
995
    assert 2 / three == 2 / 3
996
    assert two / 3 == 2 / 3
997
998
999
def test_mod(lazy_object_proxy):
1000
    two = lazy_object_proxy.Proxy(lambda: 2)
1001
    three = lazy_object_proxy.Proxy(lambda: 3)
1002
1003
    assert three // two == 3 // 2
1004
    assert 3 // two == 3 // 2
1005
    assert three // 2 == 3 // 2
1006
1007
1008
def test_mod(lazy_object_proxy):
1009
    two = lazy_object_proxy.Proxy(lambda: 2)
1010
    three = lazy_object_proxy.Proxy(lambda: 3)
1011
1012
    assert three % two == 3 % 2
1013
    assert 3 % two == 3 % 2
1014
    assert three % 2 == 3 % 2
1015
1016
1017
def test_divmod(lazy_object_proxy):
1018
    two = lazy_object_proxy.Proxy(lambda: 2)
1019
    three = lazy_object_proxy.Proxy(lambda: 3)
1020
1021
    assert divmod(three, two), divmod(3 == 2)
1022
    assert divmod(3, two), divmod(3 == 2)
1023
    assert divmod(three, 2), divmod(3 == 2)
1024
1025
1026
def test_pow(lazy_object_proxy):
1027
    two = lazy_object_proxy.Proxy(lambda: 2)
1028
    three = lazy_object_proxy.Proxy(lambda: 3)
1029
1030
    assert three ** two == pow(3, 2)
1031
    assert 3 ** two == pow(3, 2)
1032
    assert three ** 2 == pow(3, 2)
1033
1034
    assert pow(three, two) == pow(3, 2)
1035
    assert pow(3, two) == pow(3, 2)
1036
    assert pow(three, 2) == pow(3, 2)
1037
1038
    # Only PyPy implements __rpow__ for ternary pow().
1039
1040
    if PYPY:
1041
        assert pow(three, two, 2) == pow(3, 2, 2)
1042
        assert pow(3, two, 2) == pow(3, 2, 2)
1043
1044
    assert pow(three, 2, 2) == pow(3, 2, 2)
1045
1046
1047
def test_lshift(lazy_object_proxy):
1048
    two = lazy_object_proxy.Proxy(lambda: 2)
1049
    three = lazy_object_proxy.Proxy(lambda: 3)
1050
1051
    assert three << two == 3 << 2
1052
    assert 3 << two == 3 << 2
1053
    assert three << 2 == 3 << 2
1054
1055
1056
def test_rshift(lazy_object_proxy):
1057
    two = lazy_object_proxy.Proxy(lambda: 2)
1058
    three = lazy_object_proxy.Proxy(lambda: 3)
1059
1060
    assert three >> two == 3 >> 2
1061
    assert 3 >> two == 3 >> 2
1062
    assert three >> 2 == 3 >> 2
1063
1064
1065
def test_and(lazy_object_proxy):
1066
    two = lazy_object_proxy.Proxy(lambda: 2)
1067
    three = lazy_object_proxy.Proxy(lambda: 3)
1068
1069
    assert three & two == 3 & 2
1070
    assert 3 & two == 3 & 2
1071
    assert three & 2 == 3 & 2
1072
1073
1074
def test_xor(lazy_object_proxy):
1075
    two = lazy_object_proxy.Proxy(lambda: 2)
1076
    three = lazy_object_proxy.Proxy(lambda: 3)
1077
1078
    assert three ^ two == 3 ^ 2
1079
    assert 3 ^ two == 3 ^ 2
1080
    assert three ^ 2 == 3 ^ 2
1081
1082
1083
def test_or(lazy_object_proxy):
1084
    two = lazy_object_proxy.Proxy(lambda: 2)
1085
    three = lazy_object_proxy.Proxy(lambda: 3)
1086
1087
    assert three | two == 3 | 2
1088
    assert 3 | two == 3 | 2
1089
    assert three | 2 == 3 | 2
1090
1091
1092
def test_iadd(lazy_object_proxy):
1093
    value = lazy_object_proxy.Proxy(lambda: 1)
1094
    one = lazy_object_proxy.Proxy(lambda: 1)
1095
1096
    value += 1
1097
    assert value == 2
1098
1099
    if lazy_object_proxy.kind != 'simple':
1100
        assert type(value) == lazy_object_proxy.Proxy
1101
1102
    value += one
1103
    assert value == 3
1104
1105
    if lazy_object_proxy.kind != 'simple':
1106
        assert type(value) == lazy_object_proxy.Proxy
1107
1108
1109
def test_isub(lazy_object_proxy):
1110
    value = lazy_object_proxy.Proxy(lambda: 1)
1111
    one = lazy_object_proxy.Proxy(lambda: 1)
1112
1113
    value -= 1
1114
    assert value == 0
1115
    if lazy_object_proxy.kind != 'simple':
1116
        assert type(value) == lazy_object_proxy.Proxy
1117
1118
    value -= one
1119
    assert value == -1
1120
1121
    if lazy_object_proxy.kind != 'simple':
1122
        assert type(value) == lazy_object_proxy.Proxy
1123
1124
1125
def test_imul(lazy_object_proxy):
1126
    value = lazy_object_proxy.Proxy(lambda: 2)
1127
    two = lazy_object_proxy.Proxy(lambda: 2)
1128
1129
    value *= 2
1130
    assert value == 4
1131
1132
    if lazy_object_proxy.kind != 'simple':
1133
        assert type(value) == lazy_object_proxy.Proxy
1134
1135
    value *= two
1136
    assert value == 8
1137
1138
    if lazy_object_proxy.kind != 'simple':
1139
        assert type(value) == lazy_object_proxy.Proxy
1140
1141
1142
def test_idiv(lazy_object_proxy):
1143
    # On Python 2 this will pick up div and on Python
1144
    # 3 it will pick up truediv.
1145
1146
    value = lazy_object_proxy.Proxy(lambda: 2)
1147
    two = lazy_object_proxy.Proxy(lambda: 2)
1148
1149
    value /= 2
1150
    assert value == 2 / 2
1151
1152
    if lazy_object_proxy.kind != 'simple':
1153
        assert type(value) == lazy_object_proxy.Proxy
1154
1155
    value /= two
1156
    assert value == 2 / 2 / 2
1157
1158
    if lazy_object_proxy.kind != 'simple':
1159
        assert type(value) == lazy_object_proxy.Proxy
1160
1161
1162
def test_ifloordiv(lazy_object_proxy):
1163
    value = lazy_object_proxy.Proxy(lambda: 2)
1164
    two = lazy_object_proxy.Proxy(lambda: 2)
1165
1166
    value //= 2
1167
    assert value == 2 // 2
1168
1169
    if lazy_object_proxy.kind != 'simple':
1170
        assert type(value) == lazy_object_proxy.Proxy
1171
1172
    value //= two
1173
    assert value == 2 // 2 // 2
1174
1175
    if lazy_object_proxy.kind != 'simple':
1176
        assert type(value) == lazy_object_proxy.Proxy
1177
1178
1179
def test_imod(lazy_object_proxy):
1180
    value = lazy_object_proxy.Proxy(lambda: 10)
1181
    two = lazy_object_proxy.Proxy(lambda: 2)
1182
1183
    value %= 2
1184
    assert value == 10 % 2
1185
1186
    if lazy_object_proxy.kind != 'simple':
1187
        assert type(value) == lazy_object_proxy.Proxy
1188
1189
    value %= two
1190
    assert value == 10 % 2 % 2
1191
1192
    if lazy_object_proxy.kind != 'simple':
1193
        assert type(value) == lazy_object_proxy.Proxy
1194
1195
1196
def test_ipow(lazy_object_proxy):
1197
    value = lazy_object_proxy.Proxy(lambda: 10)
1198
    two = lazy_object_proxy.Proxy(lambda: 2)
1199
1200
    value **= 2
1201
    assert value == 10 ** 2
1202
1203
    if lazy_object_proxy.kind != 'simple':
1204
        assert type(value) == lazy_object_proxy.Proxy
1205
1206
    value **= two
1207
    assert value == 10 ** 2 ** 2
1208
1209
    if lazy_object_proxy.kind != 'simple':
1210
        assert type(value) == lazy_object_proxy.Proxy
1211
1212
1213
def test_ilshift(lazy_object_proxy):
1214
    value = lazy_object_proxy.Proxy(lambda: 256)
1215
    two = lazy_object_proxy.Proxy(lambda: 2)
1216
1217
    value <<= 2
1218
    assert value == 256 << 2
1219
1220
    if lazy_object_proxy.kind != 'simple':
1221
        assert type(value) == lazy_object_proxy.Proxy
1222
1223
    value <<= two
1224
    assert value == 256 << 2 << 2
1225
1226
    if lazy_object_proxy.kind != 'simple':
1227
        assert type(value) == lazy_object_proxy.Proxy
1228
1229
1230
def test_irshift(lazy_object_proxy):
1231
    value = lazy_object_proxy.Proxy(lambda: 2)
1232
    two = lazy_object_proxy.Proxy(lambda: 2)
1233
1234
    value >>= 2
1235
    assert value == 2 >> 2
1236
1237
    if lazy_object_proxy.kind != 'simple':
1238
        assert type(value) == lazy_object_proxy.Proxy
1239
1240
    value >>= two
1241
    assert value == 2 >> 2 >> 2
1242
1243
    if lazy_object_proxy.kind != 'simple':
1244
        assert type(value) == lazy_object_proxy.Proxy
1245
1246
1247
def test_iand(lazy_object_proxy):
1248
    value = lazy_object_proxy.Proxy(lambda: 1)
1249
    two = lazy_object_proxy.Proxy(lambda: 2)
1250
1251
    value &= 2
1252
    assert value == 1 & 2
1253
1254
    if lazy_object_proxy.kind != 'simple':
1255
        assert type(value) == lazy_object_proxy.Proxy
1256
1257
    value &= two
1258
    assert value == 1 & 2 & 2
1259
1260
    if lazy_object_proxy.kind != 'simple':
1261
        assert type(value) == lazy_object_proxy.Proxy
1262
1263
1264
def test_ixor(lazy_object_proxy):
1265
    value = lazy_object_proxy.Proxy(lambda: 1)
1266
    two = lazy_object_proxy.Proxy(lambda: 2)
1267
1268
    value ^= 2
1269
    assert value == 1 ^ 2
1270
1271
    if lazy_object_proxy.kind != 'simple':
1272
        assert type(value) == lazy_object_proxy.Proxy
1273
1274
    value ^= two
1275
    assert value == 1 ^ 2 ^ 2
1276
1277
    if lazy_object_proxy.kind != 'simple':
1278
        assert type(value) == lazy_object_proxy.Proxy
1279
1280
1281
def test_ior(lazy_object_proxy):
1282
    value = lazy_object_proxy.Proxy(lambda: 1)
1283
    two = lazy_object_proxy.Proxy(lambda: 2)
1284
1285
    value |= 2
1286
    assert value == 1 | 2
1287
1288
    if lazy_object_proxy.kind != 'simple':
1289
        assert type(value) == lazy_object_proxy.Proxy
1290
1291
    value |= two
1292
    assert value == 1 | 2 | 2
1293
1294
    if lazy_object_proxy.kind != 'simple':
1295
        assert type(value) == lazy_object_proxy.Proxy
1296
1297
1298
def test_neg(lazy_object_proxy):
1299
    value = lazy_object_proxy.Proxy(lambda: 1)
1300
1301
    assert -value == -1
1302
1303
1304
def test_pos(lazy_object_proxy):
1305
    value = lazy_object_proxy.Proxy(lambda: 1)
1306
1307
    assert +value == 1
1308
1309
1310
def test_abs(lazy_object_proxy):
1311
    value = lazy_object_proxy.Proxy(lambda: -1)
1312
1313
    assert abs(value) == 1
1314
1315
1316
def test_invert(lazy_object_proxy):
1317
    value = lazy_object_proxy.Proxy(lambda: 1)
1318
1319
    assert ~value == ~1
1320
1321
1322
def test_oct(lazy_object_proxy):
1323
    value = lazy_object_proxy.Proxy(lambda: 20)
1324
1325
    assert oct(value) == oct(20)
1326
1327
1328
def test_hex(lazy_object_proxy):
1329
    value = lazy_object_proxy.Proxy(lambda: 20)
1330
1331
    assert hex(value) == hex(20)
1332
1333
1334
def test_index(lazy_object_proxy):
1335
    class Class(object):
1336
        def __index__(self):
1337
            return 1
1338
1339
    value = lazy_object_proxy.Proxy(lambda: Class())
1340
    items = [0, 1, 2]
1341
1342
    assert items[value] == items[1]
1343
1344
1345
def test_length(lazy_object_proxy):
1346
    value = lazy_object_proxy.Proxy(lambda: list(range(3)))
1347
1348
    assert len(value) == 3
1349
1350
1351
def test_contains(lazy_object_proxy):
1352
    value = lazy_object_proxy.Proxy(lambda: list(range(3)))
1353
1354
    assert 2 in value
1355
    assert not -2 in value
1356
1357
1358
def test_getitem(lazy_object_proxy):
1359
    value = lazy_object_proxy.Proxy(lambda: list(range(3)))
1360
1361
    assert value[1] == 1
1362
1363
1364
def test_setitem(lazy_object_proxy):
1365
    value = lazy_object_proxy.Proxy(lambda: list(range(3)))
1366
    value[1] = -1
1367
1368
    assert value[1] == -1
1369
1370
1371
def test_delitem(lazy_object_proxy):
1372
    value = lazy_object_proxy.Proxy(lambda: list(range(3)))
1373
1374
    assert len(value) == 3
1375
1376
    del value[1]
1377
1378
    assert len(value) == 2
1379
    assert value[1] == 2
1380
1381
1382
def test_getslice(lazy_object_proxy):
1383
    value = lazy_object_proxy.Proxy(lambda: list(range(5)))
1384
1385
    assert value[1:4] == [1, 2, 3]
1386
1387
1388
def test_setslice(lazy_object_proxy):
1389
    value = lazy_object_proxy.Proxy(lambda: list(range(5)))
1390
1391
    value[1:4] = reversed(value[1:4])
1392
1393
    assert value[1:4] == [3, 2, 1]
1394
1395
1396
def test_delslice(lazy_object_proxy):
1397
    value = lazy_object_proxy.Proxy(lambda: list(range(5)))
1398
1399
    del value[1:4]
1400
1401
    assert len(value) == 2
1402
    assert value == [0, 4]
1403
1404
1405
def test_length(lazy_object_proxy):
1406
    value = lazy_object_proxy.Proxy(lambda: dict.fromkeys(range(3), False))
1407
1408
    assert len(value) == 3
1409
1410
1411
def test_contains(lazy_object_proxy):
1412
    value = lazy_object_proxy.Proxy(lambda: dict.fromkeys(range(3), False))
1413
1414
    assert 2 in value
1415
    assert -2 not in value
1416
1417
1418
def test_getitem(lazy_object_proxy):
1419
    value = lazy_object_proxy.Proxy(lambda: dict.fromkeys(range(3), False))
1420
1421
    assert value[1] == False
1422
1423
1424
def test_setitem(lazy_object_proxy):
1425
    value = lazy_object_proxy.Proxy(lambda: dict.fromkeys(range(3), False))
1426
    value[1] = True
1427
1428
    assert value[1] == True
1429
1430
1431
def test_delitem(lazy_object_proxy):
1432
    value = lazy_object_proxy.Proxy(lambda: dict.fromkeys(range(3), False))
1433
1434
    assert len(value) == 3
1435
1436
    del value[1]
1437
1438
    assert len(value) == 2
1439
1440
1441
def test_str(lazy_object_proxy):
1442
    value = lazy_object_proxy.Proxy(lambda: 10)
1443
1444
    assert str(value) == str(10)
1445
1446
    value = lazy_object_proxy.Proxy(lambda: (10,))
1447
1448
    assert str(value) == str((10,))
1449
1450
    value = lazy_object_proxy.Proxy(lambda: [10])
1451
1452
    assert str(value) == str([10])
1453
1454
    value = lazy_object_proxy.Proxy(lambda: {10: 10})
1455
1456
    assert str(value) == str({10: 10})
1457
1458
1459
def test_repr(lazy_object_proxy):
1460
    class Foobar:
1461
        pass
1462
1463
    value = lazy_object_proxy.Proxy(lambda: Foobar())
1464
    str(value)
1465
    representation = repr(value)
1466
    print(representation)
1467
    assert 'Proxy at' in representation
1468
    assert 'lambda' in representation
1469
    assert 'Foobar' in representation
1470
1471
1472
def test_repr_doesnt_consume(lazy_object_proxy):
1473
    consumed = []
1474
    value = lazy_object_proxy.Proxy(lambda: consumed.append(1))
1475
    print(repr(value))
1476
    assert not consumed
1477
1478
1479
def test_derived_new(lazy_object_proxy):
1480
    class DerivedObjectProxy(lazy_object_proxy.Proxy):
1481
        def __new__(cls, wrapped):
1482
            instance = super(DerivedObjectProxy, cls).__new__(cls)
1483
            instance.__init__(wrapped)
1484
1485
        def __init__(self, wrapped):
1486
            super(DerivedObjectProxy, self).__init__(wrapped)
1487
1488
    def function():
1489
        pass
1490
1491
    obj = DerivedObjectProxy(lambda: function)
1492
1493
1494
def test_setup_class_attributes(lazy_object_proxy):
1495
    def function():
1496
        pass
1497
1498
    class DerivedObjectProxy(lazy_object_proxy.Proxy):
1499
        pass
1500
1501
    obj = DerivedObjectProxy(lambda: function)
1502
1503
    DerivedObjectProxy.ATTRIBUTE = 1
1504
1505
    assert obj.ATTRIBUTE == 1
1506
    assert not hasattr(function, 'ATTRIBUTE')
1507
1508
    del DerivedObjectProxy.ATTRIBUTE
1509
1510
    assert not hasattr(DerivedObjectProxy, 'ATTRIBUTE')
1511
    assert not hasattr(obj, 'ATTRIBUTE')
1512
    assert not hasattr(function, 'ATTRIBUTE')
1513
1514
1515
def test_override_class_attributes(lazy_object_proxy):
1516
    def function():
1517
        pass
1518
1519
    class DerivedObjectProxy(lazy_object_proxy.Proxy):
1520
        ATTRIBUTE = 1
1521
1522
    obj = DerivedObjectProxy(lambda: function)
1523
1524
    assert DerivedObjectProxy.ATTRIBUTE == 1
1525
    assert obj.ATTRIBUTE == 1
1526
1527
    obj.ATTRIBUTE = 2
1528
1529
    assert DerivedObjectProxy.ATTRIBUTE == 1
1530
1531
    assert obj.ATTRIBUTE == 2
1532
    assert not hasattr(function, 'ATTRIBUTE')
1533
1534
    del DerivedObjectProxy.ATTRIBUTE
1535
1536
    assert not hasattr(DerivedObjectProxy, 'ATTRIBUTE')
1537
    assert obj.ATTRIBUTE == 2
1538
    assert not hasattr(function, 'ATTRIBUTE')
1539
1540
1541
def test_attr_functions(lazy_object_proxy):
1542
    def function():
1543
        pass
1544
1545
    proxy = lazy_object_proxy.Proxy(lambda: function)
1546
1547
    assert hasattr(proxy, '__getattr__')
1548
    assert hasattr(proxy, '__setattr__')
1549
    assert hasattr(proxy, '__delattr__')
1550
1551
1552
def test_override_getattr(lazy_object_proxy):
1553
    def function():
1554
        pass
1555
1556
    accessed = []
1557
1558
    class DerivedObjectProxy(lazy_object_proxy.Proxy):
1559
        def __getattr__(self, name):
1560
            accessed.append(name)
1561
            try:
1562
                __getattr__ = super(DerivedObjectProxy, self).__getattr__
1563
            except AttributeError as e:
1564
                raise RuntimeError(str(e))
1565
            return __getattr__(name)
1566
1567
    function.attribute = 1
1568
1569
    proxy = DerivedObjectProxy(lambda: function)
1570
1571
    assert proxy.attribute == 1
1572
1573
    assert 'attribute' in accessed
1574
1575
1576
skipcallable = pytest.mark.xfail(
1577
    reason="Don't know how to make this work. This tests the existance of the __call__ method.")
1578
1579
1580
@skipcallable
1581
def test_proxy_hasattr_call(lazy_object_proxy):
1582
    proxy = lazy_object_proxy.Proxy(lambda: None)
1583
1584
    assert not hasattr(proxy, '__call__')
1585
1586
1587
@skipcallable
1588
def test_proxy_getattr_call(lazy_object_proxy):
1589
    proxy = lazy_object_proxy.Proxy(lambda: None)
1590
1591
    assert getattr(proxy, '__call__', None) == None
1592
1593
1594
@skipcallable
1595
def test_proxy_is_callable(lazy_object_proxy):
1596
    proxy = lazy_object_proxy.Proxy(lambda: None)
1597
1598
    assert not callable(proxy)
1599
1600
1601
def test_callable_proxy_hasattr_call(lazy_object_proxy):
1602
    proxy = lazy_object_proxy.Proxy(lambda: None)
1603
1604
    assert hasattr(proxy, '__call__')
1605
1606
1607
@skipcallable
1608
def test_callable_proxy_getattr_call(lazy_object_proxy):
1609
    proxy = lazy_object_proxy.Proxy(lambda: None)
1610
1611
    assert getattr(proxy, '__call__', None) is None
1612
1613
1614
def test_callable_proxy_is_callable(lazy_object_proxy):
1615
    proxy = lazy_object_proxy.Proxy(lambda: None)
1616
1617
    assert callable(proxy)
1618
1619
1620
def test_class_bytes(lazy_object_proxy):
1621
    if PY3:
1622
        class Class(object):
1623
            def __bytes__(self):
1624
                return b'BYTES'
1625
1626
        instance = Class()
1627
1628
        proxy = lazy_object_proxy.Proxy(lambda: instance)
1629
1630
        assert bytes(instance) == bytes(proxy)
1631
1632
1633
def test_str_format(lazy_object_proxy):
1634
    instance = 'abcd'
1635
1636
    proxy = lazy_object_proxy.Proxy(lambda: instance)
1637
1638
    assert format(instance, ''), format(proxy == '')
1639
1640
1641
def test_list_reversed(lazy_object_proxy):
1642
    instance = [1, 2]
1643
1644
    proxy = lazy_object_proxy.Proxy(lambda: instance)
1645
1646
    assert list(reversed(instance)) == list(reversed(proxy))
1647
1648
1649
def test_decimal_complex(lazy_object_proxy):
1650
    import decimal
1651
1652
    instance = decimal.Decimal(123)
1653
1654
    proxy = lazy_object_proxy.Proxy(lambda: instance)
1655
1656
    assert complex(instance) == complex(proxy)
1657
1658
1659
def test_fractions_round(lazy_object_proxy):
1660
    import fractions
1661
1662
    instance = fractions.Fraction('1/2')
1663
1664
    proxy = lazy_object_proxy.Proxy(lambda: instance)
1665
1666
    assert round(instance) == round(proxy)
1667
1668
1669
def test_readonly(lazy_object_proxy):
1670
    class Foo(object):
1671
        if PY2:
1672
            @property
1673
            def __qualname__(self):
1674
                return 'object'
1675
1676
    proxy = lazy_object_proxy.Proxy(lambda: Foo() if PY2 else object)
1677
    assert proxy.__qualname__ == 'object'
1678
1679
1680
def test_del_wrapped(lazy_object_proxy):
1681
    foo = object()
1682
    called = []
1683
1684
    def make_foo():
1685
        called.append(1)
1686
        return foo
1687
1688
    proxy = lazy_object_proxy.Proxy(make_foo)
1689
    str(proxy)
1690
    assert called == [1]
1691
    assert proxy.__wrapped__ is foo
1692
    # print(type(proxy), hasattr(type(proxy), '__wrapped__'))
1693
    del proxy.__wrapped__
1694
    str(proxy)
1695
    assert called == [1, 1]
1696
1697
1698
def test_raise_attribute_error(lazy_object_proxy):
1699
    def foo():
1700
        raise AttributeError("boom!")
1701
1702
    proxy = lazy_object_proxy.Proxy(foo)
1703
    pytest.raises(AttributeError, str, proxy)
1704
    pytest.raises(AttributeError, lambda: proxy.__wrapped__)
1705
    assert proxy.__factory__ is foo
1706
1707
1708
def test_patching_the_factory(lazy_object_proxy):
1709
    def foo():
1710
        raise AttributeError("boom!")
1711
1712
    proxy = lazy_object_proxy.Proxy(foo)
1713
    pytest.raises(AttributeError, lambda: proxy.__wrapped__)
1714
    assert proxy.__factory__ is foo
1715
1716
    proxy.__factory__ = lambda: foo
1717
    pytest.raises(AttributeError, proxy)
1718
    assert proxy.__wrapped__ is foo
1719
1720
1721
def test_deleting_the_factory(lazy_object_proxy):
1722
    proxy = lazy_object_proxy.Proxy(None)
1723
    assert proxy.__factory__ is None
1724
    proxy.__factory__ = None
1725
    assert proxy.__factory__ is None
1726
1727
    pytest.raises(TypeError, str, proxy)
1728
    del proxy.__factory__
1729
    pytest.raises(ValueError, str, proxy)
1730
1731
1732
def test_patching_the_factory_with_none(lazy_object_proxy):
1733
    proxy = lazy_object_proxy.Proxy(None)
1734
    assert proxy.__factory__ is None
1735
    proxy.__factory__ = None
1736
    assert proxy.__factory__ is None
1737
    proxy.__factory__ = None
1738
    assert proxy.__factory__ is None
1739
1740
    def foo():
1741
        return 1
1742
1743
    proxy.__factory__ = foo
1744
    assert proxy.__factory__ is foo
1745
    assert proxy.__wrapped__ == 1
1746
    assert str(proxy) == '1'
1747
1748
1749
def test_new(lazy_object_proxy):
1750
    a = lazy_object_proxy.Proxy.__new__(lazy_object_proxy.Proxy)
1751
    b = lazy_object_proxy.Proxy.__new__(lazy_object_proxy.Proxy)
1752
    # NOW KISS
1753
    pytest.raises(ValueError, lambda: a + b)
1754
    # no segfault, yay
1755
    pytest.raises(ValueError, lambda: a.__wrapped__)
1756
1757
1758
def test_set_wrapped_via_new(lazy_object_proxy):
1759
    obj = lazy_object_proxy.Proxy.__new__(lazy_object_proxy.Proxy)
1760
    obj.__wrapped__ = 1
1761
    assert str(obj) == '1'
1762
    assert obj + 1 == 2
1763
1764
1765
def test_set_wrapped(lazy_object_proxy):
1766
    obj = lazy_object_proxy.Proxy(None)
1767
    obj.__wrapped__ = 1
1768
    assert str(obj) == '1'
1769
    assert obj + 1 == 2
1770
1771
1772
@pytest.fixture(params=["pickle", "cPickle"])
1773
def pickler(request):
1774
    return pytest.importorskip(request.param)
1775
1776
1777
@pytest.mark.parametrize("obj", [
1778
    1,
1779
    1.2,
1780
    "a",
1781
    ["b", "c"],
1782
    {"d": "e"},
1783
    date(2015, 5, 1),
1784
    datetime(2015, 5, 1),
1785
    Decimal("1.2")
1786
])
1787
@pytest.mark.parametrize("level", range(pickle.HIGHEST_PROTOCOL + 1))
1788
def test_pickling(lazy_object_proxy, obj, pickler, level):
1789
    proxy = lazy_object_proxy.Proxy(lambda: obj)
1790
    dump = pickler.dumps(proxy, protocol=level)
1791
    result = pickler.loads(dump)
1792
    assert obj == result
1793
1794
1795
@pytest.mark.parametrize("level", range(pickle.HIGHEST_PROTOCOL + 1))
1796
def test_pickling_exception(lazy_object_proxy, pickler, level):
1797
    class BadStuff(Exception):
1798
        pass
1799
1800
    def trouble_maker():
1801
        raise BadStuff("foo")
1802
1803
    proxy = lazy_object_proxy.Proxy(trouble_maker)
1804
    pytest.raises(BadStuff, pickler.dumps, proxy, protocol=level)
1805
1806
1807
@pytest.mark.skipif(platform.python_implementation() != 'CPython',
1808
                    reason="Interpreter doesn't have reference counting")
1809
def test_garbage_collection(lazy_object_proxy):
1810
    leaky = lambda: "foobar"
1811
    proxy = lazy_object_proxy.Proxy(leaky)
1812
    leaky.leak = proxy
1813
    ref = weakref.ref(leaky)
1814
    assert proxy == "foobar"
1815
    del leaky
1816
    del proxy
1817
    gc.collect()
1818
    assert ref() is None
1819
1820
1821
@pytest.mark.skipif(platform.python_implementation() != 'CPython',
1822
                    reason="Interpreter doesn't have reference counting")
1823
def test_garbage_collection_count(lazy_object_proxy):
1824
    obj = object()
1825
    count = sys.getrefcount(obj)
1826
    for _ in range(100):
1827
        str(lazy_object_proxy.Proxy(lambda: obj))
1828
    assert count == sys.getrefcount(obj)
1829
1830
1831
@pytest.mark.parametrize("name", ["slots", "cext", "simple", "django", "objproxies"])
1832
def test_perf(benchmark, name):
1833
    implementation = load_implementation(name)
1834
    obj = "foobar"
1835
    proxied = implementation.Proxy(lambda: obj)
1836
    assert benchmark(partial(str, proxied)) == obj
1837
1838
1839
empty = object()
1840
1841
1842
@pytest.fixture(scope="module", params=["SimpleProxy", "LocalsSimpleProxy", "CachedPropertyProxy",
1843
                                        "LocalsCachedPropertyProxy"])
1844
def prototype(request):
1845
    from lazy_object_proxy.simple import cached_property
1846
    name = request.param
1847
1848
    if name == "SimpleProxy":
1849
        class SimpleProxy(object):
1850
            def __init__(self, factory):
1851
                self.factory = factory
1852
                self.object = empty
1853
1854
            def __str__(self):
1855
                if self.object is empty:
1856
                    self.object = self.factory()
1857
                return str(self.object)
1858
1859
        return SimpleProxy
1860
    elif name == "CachedPropertyProxy":
1861
        class CachedPropertyProxy(object):
1862
            def __init__(self, factory):
1863
                self.factory = factory
1864
1865
            @cached_property
1866
            def object(self):
1867
                return self.factory()
1868
1869
            def __str__(self):
1870
                return str(self.object)
1871
1872
        return CachedPropertyProxy
1873
    elif name == "LocalsSimpleProxy":
1874
        class LocalsSimpleProxy(object):
1875
            def __init__(self, factory):
1876
                self.factory = factory
1877
                self.object = empty
1878
1879
            def __str__(self, func=str):
1880
                if self.object is empty:
1881
                    self.object = self.factory()
1882
                return func(self.object)
1883
1884
        return LocalsSimpleProxy
1885
    elif name == "LocalsCachedPropertyProxy":
1886
        class LocalsCachedPropertyProxy(object):
1887
            def __init__(self, factory):
1888
                self.factory = factory
1889
1890
            @cached_property
1891
            def object(self):
1892
                return self.factory()
1893
1894
            def __str__(self, func=str):
1895
                return func(self.object)
1896
1897
        return LocalsCachedPropertyProxy
1898
1899
1900
@pytest.mark.benchmark(group="prototypes")
1901
def test_proto(benchmark, prototype):
1902
    obj = "foobar"
1903
    proxied = prototype(lambda: obj)
1904
    assert benchmark(partial(str, proxied)) == obj
1905