File: test_base.py

package info (click to toggle)
dacite 1.9.2-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 320 kB
  • sloc: python: 1,870; makefile: 8
file content (227 lines) | stat: -rw-r--r-- 4,645 bytes parent folder | download | duplicates (2)
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
from dataclasses import dataclass, field
from typing import Any, NewType, Optional, List

import pytest

from dacite import from_dict, MissingValueError, WrongTypeError
from tests.common import type_hinting_using_standard_collections


def test_from_dict_iterables_with_typing_list():
    @dataclass
    class Foo:
        bar: List[str]

    result = from_dict(Foo, {"bar": ["foo", "bar"]})
    assert result == Foo(bar=["foo", "bar"])


@type_hinting_using_standard_collections
def test_from_dict_iterables():
    @dataclass
    class Foo:
        bar: list[str]

    result = from_dict(Foo, {"bar": ["foo", "bar"]})
    assert result == Foo(bar=["foo", "bar"])


def test_from_dict_with_correct_data():
    @dataclass
    class X:
        s: str
        i: int
        f: float

    result = from_dict(X, {"s": "test", "i": 1, "f": 1.0})

    assert result == X(s="test", i=1, f=1.0)


def test_from_dict_with_default_value():
    @dataclass
    class X:
        s: str
        i: int = 0

    result = from_dict(X, {"s": "test"})

    assert result == X(s="test", i=0)


def test_from_dict_with_default_factory():
    @dataclass
    class X:
        s: str
        i: int = field(default_factory=lambda: 42)

    result = from_dict(X, {"s": "test"})

    assert result == X(s="test", i=42)


def test_from_dict_with_wrong_type():
    @dataclass
    class X:
        s: str
        i: int

    with pytest.raises(WrongTypeError) as exception_info:
        from_dict(X, {"s": "test", "i": "wrong"})

    assert (
        str(exception_info.value)
        == 'wrong value type for field "i" - should be "int" instead of value "wrong" of type "str"'
    )
    assert exception_info.value.field_path == "i"
    assert exception_info.value.field_type == int
    assert exception_info.value.value == "wrong"


def test_from_dict_with_missing_value():
    @dataclass
    class X:
        s: str
        i: int

    with pytest.raises(MissingValueError) as exception_info:
        from_dict(X, {"s": "test"})

    assert str(exception_info.value) == 'missing value for field "i"'
    assert exception_info.value.field_path == "i"
    assert exception_info._excinfo[1].__suppress_context__


def test_from_dict_with_nested_data_class():
    @dataclass
    class X:
        i: int

    @dataclass
    class Y:
        s: str
        x: X

    result = from_dict(Y, {"s": "test", "x": {"i": 1}})

    assert result == Y(s="test", x=X(i=1))


def test_from_dict_with_missing_value_of_nested_data_class():
    @dataclass
    class X:
        i: int

    @dataclass
    class Y:
        x: X

    with pytest.raises(MissingValueError) as exception_info:
        from_dict(Y, {"x": {}})

    assert exception_info.value.field_path == "x.i"


def test_from_dict_with_additional_values():
    @dataclass
    class X:
        i: int

    result = from_dict(X, {"i": 1, "s": "extra"})

    assert result == X(i=1)


def test_from_dict_with_any():
    @dataclass
    class X:
        i: Any

    result = from_dict(X, {"i": 1})

    assert result == X(i=1)


def test_from_dict_with_nested_data_classes_and_default_factory():
    @dataclass
    class X:
        i: int

    @dataclass
    class Y:
        x: X = field(default_factory=lambda: X(i=42))

    result = from_dict(Y, {})

    assert result == Y(x=X(i=42))


def test_from_dict_with_post_init():
    @dataclass
    class X:
        s: str = field(init=False)

    x = X()
    x.s = "test"

    result = from_dict(X, {"s": "test"})

    assert result == x


def test_from_dict_with_post_init_missing_value():
    @dataclass
    class X:
        s: str = field(init=False)

    result = from_dict(X, {})

    assert not hasattr(result, "s")


def test_from_dict_with_optional_non_init_field():
    @dataclass
    class X:
        s: Optional[str] = field(init=False)

    x = X()
    x.s = None

    result = from_dict(X, {})

    assert result == x


def test_from_dict_with_non_init_field_with_default_value_and_frozen_dataclass():
    @dataclass(frozen=True)
    class X:
        s: str = field(init=False, default="test")

    result = from_dict(X, {})

    assert result == X()


def test_from_dict_with_new_type():
    MyStr = NewType("MyStr", str)

    @dataclass
    class X:
        s: MyStr

    result = from_dict(X, {"s": "test"})

    assert result == X(s=MyStr("test"))


def test_dataclass_default_factory_identity():
    # https://github.com/konradhalas/dacite/issues/215
    @dataclass
    class A:
        name: str
        items: List[str] = field(default_factory=list)

    a1 = from_dict(A, {"name": "a1"})
    a2 = from_dict(A, {"name": "a2"})

    assert a1.items is not a2.items