File: test_autoparams.py

package info (click to toggle)
python-inject 5.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 196 kB
  • sloc: python: 1,039; makefile: 28; sh: 5
file content (239 lines) | stat: -rw-r--r-- 7,624 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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
import sys
from typing import Optional

from test import BaseTestInject

import inject


class A: pass
class B: pass
class C: pass


class TestInjectEmptyAutoparamsWithBraces(BaseTestInject):
    @staticmethod
    def _get_decorator():
        return inject.autoparams()

    def test_autoparams_by_class(self):
        @self._get_decorator()
        def test_func(val: int = None):
            return val

        inject.configure(lambda binder: binder.bind(int, 123))

        assert test_func() == 123
        assert test_func(val=321) == 321

    def test_autoparams_multi(self):
        @self._get_decorator()
        def test_func(a: A, b: B, *, c: C):
            return a, b, c

        def config(binder):
            binder.bind(A, 1)
            binder.bind(B, 2)
            binder.bind(C, 3)

        inject.configure(config)

        assert test_func() == (1, 2, 3)
        assert test_func(10) == (10, 2, 3)
        assert test_func(10, 20) == (10, 20, 3)
        assert test_func(10, 20, c=30) == (10, 20, 30)
        assert test_func(a='a') == ('a', 2, 3)
        assert test_func(b='b') == (1, 'b', 3)
        assert test_func(c='c') == (1, 2, 'c')
        assert test_func(a=10, c=30) == (10, 2, 30)
        assert test_func(c=30, b=20, a=10) == (10, 20, 30)
        assert test_func(10, b=20) == (10, 20, 3)

    def test_autoparams_strings(self):
        @self._get_decorator()
        def test_func(a: 'A', b: 'B', *, c: 'C'):
            return a, b, c

        def config(binder):
            binder.bind(A, 1)
            binder.bind(B, 2)
            binder.bind(C, 3)

        inject.configure(config)

        assert test_func() == (1, 2, 3)
        assert test_func(10) == (10, 2, 3)
        assert test_func(10, 20) == (10, 20, 3)
        assert test_func(10, 20, c=30) == (10, 20, 30)
        assert test_func(a='a') == ('a', 2, 3)
        assert test_func(b='b') == (1, 'b', 3)
        assert test_func(c='c') == (1, 2, 'c')
        assert test_func(a=10, c=30) == (10, 2, 30)
        assert test_func(c=30, b=20, a=10) == (10, 20, 30)
        assert test_func(10, b=20) == (10, 20, 3)

    def test_autoparams_with_defaults(self):
        @self._get_decorator()
        def test_func(a=1, b: 'B' = None, *, c: 'C' = 300):
            return a, b, c

        def config(binder):
            binder.bind(B, 2)
            binder.bind(C, 3)

        inject.configure(config)

        assert test_func() == (1, 2, 3)
        assert test_func(10) == (10, 2, 3)
        assert test_func(10, 20) == (10, 20, 3)
        assert test_func(10, 20, c=30) == (10, 20, 30)
        assert test_func(a='a') == ('a', 2, 3)
        assert test_func(b='b') == (1, 'b', 3)
        assert test_func(c='c') == (1, 2, 'c')
        assert test_func(a=10, c=30) == (10, 2, 30)
        assert test_func(c=30, b=20, a=10) == (10, 20, 30)
        assert test_func(10, b=20) == (10, 20, 3)

    def test_autoparams_on_method(self):
        class Test:
            @self._get_decorator()
            def func(self, a=1, b: 'B' = None, *, c: 'C' = None):
                return self, a, b, c

        def config(binder):
            binder.bind(B, 2)
            binder.bind(C, 3)

        inject.configure(config)
        test = Test()

        assert test.func() == (test, 1, 2, 3)
        assert test.func(10) == (test, 10, 2, 3)
        assert test.func(10, 20) == (test, 10, 20, 3)
        assert test.func(10, 20, c=30) == (test, 10, 20, 30)
        assert test.func(a='a') == (test, 'a', 2, 3)
        assert test.func(b='b') == (test, 1, 'b', 3)
        assert test.func(c='c') == (test, 1, 2, 'c')
        assert test.func(a=10, c=30) == (test, 10, 2, 30)
        assert test.func(c=30, b=20, a=10) == (test, 10, 20, 30)
        assert test.func(10, b=20) == (test, 10, 20, 3)

    def test_autoparams_on_classmethod(self):
        class Test:
            # note inject must be *before* classmethod!
            @classmethod
            @self._get_decorator()
            def func(cls, a=1, b: 'B' = None, *, c: 'C' = None):
                return cls, a, b, c

        def config(binder):
            binder.bind(B, 2)
            binder.bind(C, 3)

        inject.configure(config)

        assert Test.func() == (Test, 1, 2, 3)
        assert Test.func(10) == (Test, 10, 2, 3)
        assert Test.func(10, 20) == (Test, 10, 20, 3)
        assert Test.func(10, 20, c=30) == (Test, 10, 20, 30)
        assert Test.func(a='a') == (Test, 'a', 2, 3)
        assert Test.func(b='b') == (Test, 1, 'b', 3)
        assert Test.func(c='c') == (Test, 1, 2, 'c')
        assert Test.func(a=10, c=30) == (Test, 10, 2, 30)
        assert Test.func(c=30, b=20, a=10) == (Test, 10, 20, 30)
        assert Test.func(10, b=20) == (Test, 10, 20, 3)

    def test_autoparams_on_classmethod_ob_object(self):
        class Test:
            # note inject must be *before* classmethod!
            @classmethod
            @self._get_decorator()
            def func(cls, a=1, b: 'B' = None, *, c: 'C' = None):
                return cls, a, b, c

        def config(binder):
            binder.bind(B, 2)
            binder.bind(C, 3)

        inject.configure(config)
        test = Test

        assert test.func() == (Test, 1, 2, 3)
        assert test.func(10) == (Test, 10, 2, 3)
        assert test.func(10, 20) == (Test, 10, 20, 3)
        assert test.func(10, 20, c=30) == (Test, 10, 20, 30)
        assert test.func(a='a') == (Test, 'a', 2, 3)
        assert test.func(b='b') == (Test, 1, 'b', 3)
        assert test.func(c='c') == (Test, 1, 2, 'c')
        assert test.func(a=10, c=30) == (Test, 10, 2, 30)
        assert test.func(c=30, b=20, a=10) == (Test, 10, 20, 30)
        assert test.func(10, b=20) == (Test, 10, 20, 3)

    def test_autoparams_omits_return_type(self):
        @self._get_decorator()
        def test_func(a: str) -> int:
            return a

        def config(binder):
            binder.bind(str, 'bazinga')

        inject.configure(config)

        assert test_func() == 'bazinga'


class TestInjectEmptyAutoparamsNoBraces(TestInjectEmptyAutoparamsWithBraces):
    @staticmethod
    def _get_decorator():
        return inject.autoparams


class TestInjectSelectedAutoparams(BaseTestInject):

    def test_autoparams_only_selected(self):
        @inject.autoparams('a', 'c')
        def test_func(a: 'A', b: 'B', *, c: 'C'):
            return a, b, c

        def config(binder):
            binder.bind(A, 1)
            binder.bind(B, 2)
            binder.bind(C, 3)

        inject.configure(config)

        self.assertRaises(TypeError, test_func)
        self.assertRaises(TypeError, test_func, a=1, c=3)

    def test_autoparams_only_selected_with_optional(self):
        @inject.autoparams('a', 'c')
        def test_func(a: 'A', b: 'B', *, c: Optional[C] = None):
            return a, b, c

        def config(binder):
            binder.bind(A, 1)
            binder.bind(B, 2)
            binder.bind(C, 3)

        inject.configure(config)

        self.assertRaises(TypeError, test_func)
        self.assertRaises(TypeError, test_func, a=1, c=3)

    def test_autoparams_only_selected_with_optional_pep604_union(self):
        if not sys.version_info[:3] >= (3, 10, 0):
            return

        @inject.autoparams('a', 'c')
        def test_func(a: 'A', b: 'B', *, c: C | None = None):
            return a, b, c

        def config(binder):
            binder.bind(A, 1)
            binder.bind(B, 2)
            binder.bind(C, 3)

        inject.configure(config)

        self.assertRaises(TypeError, test_func)
        self.assertRaises(TypeError, test_func, a=1, c=3)