File: test_unstructure_collections.py

package info (click to toggle)
python-cattrs 25.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,812 kB
  • sloc: python: 12,236; makefile: 155
file content (150 lines) | stat: -rw-r--r-- 5,717 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
from collections import Counter
from collections.abc import (
    Mapping,
    MutableMapping,
    MutableSequence,
    MutableSet,
    Sequence,
    Set,
)
from functools import partial

from attrs import define, field
from immutables import Map

from cattrs import Converter
from cattrs.converters import is_mutable_set, is_sequence


def test_collection_unstructure_override_set():
    """Test overriding unstructuring sets."""

    # First approach, predicate hook with is_mutable_set
    c = Converter()

    c._unstructure_func.register_func_list(
        [
            (
                is_mutable_set,
                partial(c.gen_unstructure_iterable, unstructure_to=list),
                True,
            )
        ]
    )

    assert c.unstructure({1, 2, 3}, unstructure_as=Set[int]) == [1, 2, 3]

    # Second approach, using __builtins__.set
    c = Converter(unstruct_collection_overrides={set: list})

    assert c.unstructure({1, 2, 3}, unstructure_as=Set[int]) == {1, 2, 3}
    assert c.unstructure({1, 2, 3}, unstructure_as=MutableSet[int]) == {1, 2, 3}
    assert c.unstructure({1, 2, 3}) == [1, 2, 3]

    # Second approach, using abc.MutableSet
    c = Converter(unstruct_collection_overrides={MutableSet: list})

    assert c.unstructure({1, 2, 3}, unstructure_as=Set[int]) == {1, 2, 3}
    assert c.unstructure({1, 2, 3}, unstructure_as=MutableSet[int]) == [1, 2, 3]
    assert c.unstructure({1, 2, 3}) == [1, 2, 3]

    # Second approach, using abc.Set
    c = Converter(unstruct_collection_overrides={Set: list})

    assert c.unstructure({1, 2, 3}, unstructure_as=Set[int]) == [1, 2, 3]
    assert c.unstructure({1, 2, 3}, unstructure_as=MutableSet[int]) == [1, 2, 3]
    assert c.unstructure({1, 2, 3}) == [1, 2, 3]


def test_collection_unstructure_override_seq():
    """Test overriding unstructuring seq."""

    # First approach, predicate hook
    c = Converter()

    c._unstructure_func.register_func_list(
        [(is_sequence, partial(c.gen_unstructure_iterable, unstructure_to=tuple), True)]
    )

    assert c.unstructure([1, 2, 3], unstructure_as=Sequence[int]) == (1, 2, 3)

    @define
    class MyList:
        args = field(converter=list)

    # Second approach, using abc.MutableSequence
    c = Converter(unstruct_collection_overrides={MutableSequence: MyList})

    assert c.unstructure([1, 2, 3], unstructure_as=Sequence[int]) == [1, 2, 3]
    assert c.unstructure([1, 2, 3], unstructure_as=MutableSequence[int]) == MyList(
        [1, 2, 3]
    )
    assert c.unstructure([1, 2, 3]) == MyList([1, 2, 3])
    assert c.unstructure((1, 2, 3)) == [1, 2, 3]

    # Second approach, using abc.Sequence
    c = Converter(unstruct_collection_overrides={Sequence: MyList})

    assert c.unstructure([1, 2, 3], unstructure_as=Sequence[int]) == MyList([1, 2, 3])
    assert c.unstructure([1, 2, 3], unstructure_as=MutableSequence[int]) == MyList(
        [1, 2, 3]
    )

    assert c.unstructure([1, 2, 3]) == MyList([1, 2, 3])

    assert c.unstructure((1, 2, 3), unstructure_as=tuple[int, ...]) == MyList([1, 2, 3])

    # Second approach, using __builtins__.list
    c = Converter(unstruct_collection_overrides={list: MyList})

    assert c.unstructure([1, 2, 3], unstructure_as=Sequence[int]) == [1, 2, 3]
    assert c.unstructure([1, 2, 3], unstructure_as=MutableSequence[int]) == [1, 2, 3]
    assert c.unstructure([1, 2, 3]) == MyList([1, 2, 3])
    assert c.unstructure((1, 2, 3)) == [1, 2, 3]

    # Second approach, using __builtins__.tuple
    c = Converter(unstruct_collection_overrides={tuple: MyList})

    assert c.unstructure([1, 2, 3], unstructure_as=Sequence[int]) == [1, 2, 3]
    assert c.unstructure([1, 2, 3], unstructure_as=MutableSequence[int]) == [1, 2, 3]
    assert c.unstructure([1, 2, 3]) == [1, 2, 3]
    assert c.unstructure((1, 2, 3)) == MyList([1, 2, 3])


def test_collection_unstructure_override_mapping():
    """Test overriding unstructuring mappings."""

    # Using Counter
    c = Converter(unstruct_collection_overrides={Counter: Map})
    assert c.unstructure(Counter({1: 2})) == Map({1: 2})
    assert c.unstructure(Counter({1: 2}), unstructure_as=Counter[int]) == Map({1: 2})
    assert c.unstructure({1: 2}) == {1: 2}
    assert c.unstructure({1: 2}, unstructure_as=MutableMapping[int, int]) == {1: 2}
    assert c.unstructure({1: 2}, unstructure_as=Mapping[int, int]) == {1: 2}

    # Using __builtins__.dict
    c = Converter(unstruct_collection_overrides={dict: Map})

    assert c.unstructure(Counter({1: 2})) == Map({1: 2})
    assert c.unstructure(Counter({1: 2}), unstructure_as=Counter[int]) == Map({1: 2})
    assert c.unstructure({1: 2}) == Map({1: 2})
    assert c.unstructure({1: 2}, unstructure_as=MutableMapping[int, int]) == {1: 2}
    assert c.unstructure({1: 2}, unstructure_as=Mapping[int, int]) == {1: 2}

    # Using MutableMapping
    c = Converter(unstruct_collection_overrides={MutableMapping: Map})

    assert c.unstructure(Counter({1: 2})) == Map({1: 2})
    assert c.unstructure(Counter({1: 2}), unstructure_as=Counter[int]) == Map({1: 2})
    assert c.unstructure({1: 2}) == Map({1: 2})
    assert c.unstructure({1: 2}, unstructure_as=MutableMapping[int, int]) == Map({1: 2})
    assert c.unstructure({1: 2}, unstructure_as=Mapping[int, int]) == {1: 2}

    # Using Mapping
    c = Converter(unstruct_collection_overrides={Mapping: Map})

    assert c.unstructure(Counter({1: 2})) == Map({1: 2})
    assert c.unstructure(Counter({1: 2}), unstructure_as=Counter[int]) == Map({1: 2})
    assert c.unstructure({1: 2}) == Map({1: 2})
    assert c.unstructure({1: 2}, unstructure_as=MutableMapping[int, int]) == Map({1: 2})
    assert c.unstructure({1: 2}, unstructure_as=Mapping[int, int]) == Map({1: 2})