Coverage for tests/unit/misc/test_freeze.py: 100%
121 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-04-04 03:33 -0600
« prev ^ index » next coverage.py v7.6.1, created at 2025-04-04 03:33 -0600
1from __future__ import annotations
3import pytest
5from muutils.misc import freeze
7# TODO: there are a bunch of 'type: ignore' comments here which it would be nice to get rid of
10def test_freeze_basic_types():
11 freeze(True)
12 freeze(123)
13 freeze(45.67)
14 freeze("hello")
15 freeze(b"bytes")
17 assert True # No exceptions should be raised
20def test_freeze_list():
21 lst = [1, 2, 3]
22 lst = freeze(lst)
24 with pytest.raises(AttributeError):
25 lst[0] = 4
27 with pytest.raises(AttributeError):
28 lst.append(4)
30 with pytest.raises(AttributeError):
31 lst.extend([4, 5])
33 with pytest.raises(AttributeError):
34 lst.pop()
36 with pytest.raises(AttributeError):
37 lst.clear()
40def test_freeze_tuple():
41 tpl = (1, 2, 3)
42 frozen_tpl = freeze(tpl)
44 assert frozen_tpl == (1, 2, 3)
45 assert isinstance(frozen_tpl, tuple)
48def test_freeze_set():
49 st = {1, 2, 3}
50 frozen_st = freeze(st)
52 assert frozen_st == frozenset({1, 2, 3})
53 assert isinstance(frozen_st, frozenset)
56def test_freeze_dict():
57 dct = {"key1": 1, "key2": 2}
58 dct = freeze(dct)
60 with pytest.raises(AttributeError):
61 dct["key1"] = 3
63 with pytest.raises(AttributeError):
64 del dct["key2"]
67def test_freeze_nested_structures():
68 nested = {"key1": [1, 2, 3], "key2": {"subkey": 4}}
69 freeze(nested)
71 with pytest.raises(AttributeError):
72 nested["key1"][0] = 4 # type: ignore[index]
74 with pytest.raises(AttributeError):
75 nested["key2"]["subkey"] = 5 # type: ignore[index]
78def test_freeze_custom_class():
79 class CustomClass:
80 def __init__(self, value):
81 self.value = value
83 obj = CustomClass(10)
84 freeze(obj)
86 with pytest.raises(AttributeError):
87 obj.value = 20
90class CustomClass:
91 def __init__(self, value):
92 self.value = value
95def test_freeze_class_with_nested_structures():
96 class NestedClass:
97 def __init__(self):
98 self.lst = [1, 2, {"key": 3}, (4, 5)]
99 self.dct = {"key1": {1, 2, 3}, "key2": [6, 7, 8]}
100 self.st = {frozenset((9, 10)), (11, 12)}
101 self.tpl = (CustomClass(13), [14, 15], {"key3": 16})
103 obj_orig = NestedClass()
104 obj = freeze(obj_orig)
106 with pytest.raises(AttributeError):
107 obj.lst[0] = 10
109 with pytest.raises(AttributeError):
110 obj.lst[2]["key"] = 30 # type: ignore[index]
112 with pytest.raises(AttributeError):
113 obj.lst[3] = (40, 50)
115 with pytest.raises(AttributeError):
116 obj.dct["key1"] = {100, 200}
118 with pytest.raises(AttributeError):
119 obj.dct["key2"][1] = 70 # type: ignore[index]
121 with pytest.raises(AttributeError):
122 obj.st.add((13, 14))
124 with pytest.raises(AttributeError):
125 obj.tpl[1][0] = 140
127 with pytest.raises(AttributeError):
128 obj.tpl[2]["key3"] = 160
131def test_freeze_lists_with_classes_and_nested_structures():
132 lst = [CustomClass(1), [2, 3], {"key": (4, 5)}]
133 freeze(lst)
135 with pytest.raises(AttributeError):
136 lst[0].value = 10 # type: ignore[attr-defined]
138 with pytest.raises(AttributeError):
139 lst[1][1] = 30 # type: ignore[index]
141 with pytest.raises(AttributeError):
142 lst[2]["key"] = (40, 50) # type: ignore[index]
145def test_freeze_dicts_with_classes_and_nested_structures():
146 dct = {"class": CustomClass(6), "lst": [7, 8], "set": {9, (10, 11)}}
147 freeze(dct)
149 with pytest.raises(AttributeError):
150 dct["class"].value = 60 # type: ignore[attr-defined]
152 with pytest.raises(AttributeError):
153 dct["lst"][0] = 70 # type: ignore[index]
155 with pytest.raises(AttributeError):
156 dct["set"].add(12) # type: ignore[attr-defined]
159def test_freeze_sets_with_classes_and_nested_structures():
160 st = {CustomClass(1), frozenset({2, 3}), (4, 5)}
161 freeze(st)
163 for item in st:
164 if isinstance(item, CustomClass):
165 with pytest.raises(AttributeError):
166 item.value = 10
169def test_freeze_tuples_with_classes_and_nested_structures():
170 tpl = (CustomClass(1), [2, 3], {"key": 4})
171 frozen_tpl = freeze(tpl)
173 for item in frozen_tpl:
174 if isinstance(item, CustomClass):
175 with pytest.raises(AttributeError):
176 item.value = 10
177 elif isinstance(item, list):
178 with pytest.raises(AttributeError):
179 item[0] = 20
180 elif isinstance(item, dict):
181 with pytest.raises(AttributeError):
182 item["key"] = 40