File: test_objects.py

package info (click to toggle)
python-funcy 2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 536 kB
  • sloc: python: 2,989; makefile: 140; javascript: 96; sh: 6
file content (156 lines) | stat: -rw-r--r-- 2,799 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import sys
import pytest
from funcy.objects import *
from funcy import suppress


### @cached_property

def test_cached_property():
    calls = [0]

    class A(object):
        @cached_property
        def prop(self):
            calls[0] += 1
            return 7

    a = A()
    assert a.prop == 7
    assert a.prop == 7
    assert calls == [1]

    a.prop = 42
    assert a.prop == 42

    del a.prop
    assert a.prop == 7
    assert calls == [2]

def test_cached_property_doc():
    class A(object):
        @cached_property
        def prop(self):
            "prop doc"
            return 7

    assert A.prop.__doc__ == "prop doc"


def test_cached_readonly():
    class A(object):
        @cached_readonly
        def prop(self):
            return 7

    a = A()
    assert a.prop == 7
    with pytest.raises(AttributeError):
        a.prop = 8


def test_wrap_prop():
    calls = []

    # Not using @contextmanager to not make this a decorator
    class Manager:
        def __init__(self, name):
            self.name = name

        def __enter__(self):
            calls.append(self.name)
            return self

        def __exit__(self, *args):
            pass

    class A(object):
        @wrap_prop(Manager('p'))
        @property
        def prop(self):
            return 1

        @wrap_prop(Manager('cp'))
        @cached_property
        def cached_prop(self):
            return 1

    a = A()
    assert a.prop and calls == ['p']
    assert a.prop and calls == ['p', 'p']
    assert a.cached_prop and calls == ['p', 'p', 'cp']
    assert a.cached_prop and calls == ['p', 'p', 'cp']

    # Wrap __set__ for data props
    a = A()
    calls[:] = []
    with suppress(AttributeError):
        a.prop = 2
    assert calls == ['p']

    # Do not wrap __set__ for non-data props
    a.cached_property = 2
    assert calls == ['p']


### Monkey tests

def test_monkey():
    class A(object):
        def f(self):
            return 7

    @monkey(A)
    def f(self):
        return f.original(self) * 6

    assert A().f() == 42


def test_monkey_with_name():
    class A(object):
        def f(self):
            return 7

    @monkey(A, name='f')
    def g(self):
        return g.original(self) * 6

    assert A().f() == 42


def test_monkey_property():
    class A(object):
        pass

    @monkey(A)
    @property
    def prop(self):
        return 42

    assert A().prop == 42


def f(x):
    return x

def test_monkey_module():
    this_module = sys.modules[__name__]

    @monkey(this_module)
    def f(x):
        return f.original(x) * 2

    assert f(21) == 42


def test_lazy_object():
    class A(object):
        x = 42
        def __init__(self):
            log.append('init')

    log = []
    a = LazyObject(A)
    assert not log
    assert a.x == 42