0
# Deep Freezing System
1
2
Recursive immutability system that converts objects and all nested objects to their immutable counterparts. Provides extensible type conversion with custom converters and comprehensive support for deeply nested data structures.
3
4
## Capabilities
5
6
### Core Deep Freezing
7
8
Converts objects recursively to immutable versions, handling nested structures like lists, dicts, sets, and custom types.
9
10
```python { .api }
11
def deepfreeze(o, custom_converters=None, custom_inverse_converters=None):
12
"""
13
Convert object and all nested objects to immutable counterparts recursively.
14
15
Parameters:
16
- o: Object to freeze (any type)
17
- custom_converters: dict, optional custom type converters for freezing
18
- custom_inverse_converters: dict, optional custom inverse converters for thawing
19
20
Returns:
21
Immutable version of the object with all nested objects also made immutable
22
23
Built-in conversions:
24
- dict -> frozendict
25
- list/tuple -> tuple
26
- set -> frozenset
27
- Recursive application to all nested containers
28
"""
29
```
30
31
**Usage Example:**
32
33
```python
34
from frozendict import deepfreeze
35
36
# Freeze nested data structures
37
data = {
38
'users': [
39
{'name': 'Alice', 'roles': {'admin', 'user'}},
40
{'name': 'Bob', 'roles': {'user'}}
41
],
42
'settings': {
43
'debug': True,
44
'features': ['auth', 'logging']
45
}
46
}
47
48
frozen_data = deepfreeze(data)
49
# Result: frozendict with all nested dicts as frozendicts,
50
# lists as tuples, and sets as frozensets
51
52
# The frozen structure is completely immutable
53
print(type(frozen_data)) # frozendict
54
print(type(frozen_data['users'])) # tuple
55
print(type(frozen_data['users'][0])) # frozendict
56
print(type(frozen_data['users'][0]['roles'])) # frozenset
57
```
58
59
### Custom Type Registration
60
61
Register custom converters for specific types to extend deep freezing functionality.
62
63
```python { .api }
64
def register(to_convert, converter, *, inverse=False):
65
"""
66
Add a converter for a type used by deepfreeze().
67
68
Parameters:
69
- to_convert: type, the type to convert
70
- converter: callable, function to convert instances of the type
71
- inverse: bool, if True, register as inverse converter for thawing (default: False)
72
73
Returns:
74
None
75
"""
76
77
def unregister(type, inverse=False):
78
"""
79
Remove a type from custom conversion.
80
81
Parameters:
82
- type: type, the type to remove from conversion
83
- inverse: bool, if True, remove from inverse converters (default: False)
84
85
Returns:
86
None
87
"""
88
```
89
90
**Usage Example:**
91
92
```python
93
from frozendict import register, unregister, deepfreeze
94
from collections import namedtuple
95
96
# Define a custom type
97
class Point:
98
def __init__(self, x, y):
99
self.x, self.y = x, y
100
101
# Create an immutable version
102
FrozenPoint = namedtuple('FrozenPoint', ['x', 'y'])
103
104
def point_converter(point):
105
return FrozenPoint(point.x, point.y)
106
107
# Register the converter
108
register(Point, point_converter)
109
110
# Now deepfreeze can handle Point objects
111
data = {'center': Point(10, 20), 'radius': 5}
112
frozen = deepfreeze(data)
113
print(type(frozen['center'])) # FrozenPoint
114
115
# Remove the converter when no longer needed
116
unregister(Point)
117
```
118
119
### Conversion Map Access
120
121
Inspect and access the current type conversion mappings.
122
123
```python { .api }
124
def getFreezeConversionMap():
125
"""
126
Return the current freeze conversion map.
127
128
Returns:
129
dict: Mapping from types to their freeze converter functions
130
"""
131
132
def getFreezeConversionInverseMap():
133
"""
134
Return the current inverse freeze conversion map.
135
136
Returns:
137
dict: Mapping from types to their inverse converter functions
138
"""
139
```
140
141
**Usage Example:**
142
143
```python
144
from frozendict import getFreezeConversionMap, getFreezeConversionInverseMap
145
146
# Inspect current converters
147
freeze_map = getFreezeConversionMap()
148
print(freeze_map.keys()) # View registered types
149
150
inverse_map = getFreezeConversionInverseMap()
151
print(inverse_map.keys()) # View registered inverse types
152
```
153
154
## Exception Classes
155
156
```python { .api }
157
class FreezeError(Exception):
158
"""
159
Exception raised by freeze-related operations.
160
161
Raised when deepfreeze encounters an error during conversion,
162
such as unsupported types or circular references.
163
"""
164
165
class FreezeWarning(Warning):
166
"""
167
Warning for freeze-related operations.
168
169
Issued when deepfreeze encounters potentially problematic
170
situations that don't prevent operation completion.
171
"""
172
```
173
174
**Usage Example:**
175
176
```python
177
from frozendict import deepfreeze, FreezeError, FreezeWarning
178
import warnings
179
180
# Handle freeze errors
181
try:
182
# Some complex object that might fail to freeze
183
result = deepfreeze(some_complex_object)
184
except FreezeError as e:
185
print(f"Failed to freeze object: {e}")
186
187
# Monitor freeze warnings
188
with warnings.catch_warnings(record=True) as w:
189
warnings.simplefilter("always")
190
result = deepfreeze(some_object)
191
192
for warning in w:
193
if issubclass(warning.category, FreezeWarning):
194
print(f"Freeze warning: {warning.message}")
195
```
196
197
## Advanced Usage Patterns
198
199
### Bidirectional Conversion
200
201
Using both freeze and inverse converters for round-trip conversion:
202
203
```python
204
from frozendict import register, deepfreeze
205
from datetime import datetime, date
206
207
# Register bidirectional converters for datetime objects
208
def freeze_datetime(dt):
209
return dt.isoformat()
210
211
def thaw_datetime(iso_string):
212
return datetime.fromisoformat(iso_string)
213
214
register(datetime, freeze_datetime)
215
register(str, thaw_datetime, inverse=True)
216
217
# Now datetime objects are converted to strings when frozen
218
data = {'timestamp': datetime.now(), 'name': 'event'}
219
frozen = deepfreeze(data)
220
# frozen['timestamp'] is now a string
221
```
222
223
### Nested Custom Types
224
225
Handling complex nested structures with multiple custom types:
226
227
```python
228
from frozendict import register, deepfreeze
229
from collections import namedtuple
230
231
# Define custom types and their immutable versions
232
class User:
233
def __init__(self, name, email):
234
self.name, self.email = name, email
235
236
class Project:
237
def __init__(self, name, users):
238
self.name, self.users = name, users
239
240
FrozenUser = namedtuple('FrozenUser', ['name', 'email'])
241
FrozenProject = namedtuple('FrozenProject', ['name', 'users'])
242
243
# Register converters
244
register(User, lambda u: FrozenUser(u.name, u.email))
245
register(Project, lambda p: FrozenProject(p.name, deepfreeze(p.users)))
246
247
# Deep freeze complex nested structures
248
project = Project('MyApp', [User('Alice', 'alice@example.com')])
249
frozen_project = deepfreeze(project)
250
# All levels are now immutable
251
```