0
# Delta Operations
1
2
Store differences as delta objects and apply them to create new objects or modify existing ones. Delta provides a powerful system for capturing, serializing, and applying changes between objects, enabling version control-like functionality and patch operations for Python data structures.
3
4
## Capabilities
5
6
### Delta Creation and Management
7
8
Create delta objects from DeepDiff results and manage their lifecycle with various configuration options.
9
10
```python { .api }
11
class Delta:
12
def __init__(
13
self,
14
diff: Union[DeepDiff, Mapping, str, bytes, None] = None,
15
delta_path: Optional[str] = None,
16
delta_file: Optional[IO] = None,
17
delta_diff: Optional[dict] = None,
18
flat_dict_list: Optional[List[Dict]] = None,
19
flat_rows_list: Optional[List[FlatDeltaRow]] = None,
20
deserializer: Callable = pickle_load,
21
log_errors: bool = True,
22
mutate: bool = False,
23
raise_errors: bool = False,
24
safe_to_import: Optional[Set[str]] = None,
25
serializer: Callable = pickle_dump,
26
verify_symmetry: Optional[bool] = None,
27
bidirectional: bool = False,
28
always_include_values: bool = False,
29
iterable_compare_func_was_used: Optional[bool] = None,
30
force: bool = False,
31
fill: Any = not_found
32
):
33
"""
34
Create a Delta object from a DeepDiff result or other sources.
35
36
Parameters:
37
- diff: DeepDiff object, dictionary, or serialized difference data
38
- delta_path: Path to delta file to load
39
- delta_file: File object containing delta data
40
- delta_diff: Dictionary containing diff data
41
- flat_dict_list: List of flat dictionaries for delta creation
42
- flat_rows_list: List of flat row objects for delta creation
43
- deserializer: Function to deserialize delta data
44
- log_errors: Whether to log errors during delta operations
45
- mutate: Whether to mutate the original object when applying delta
46
- raise_errors: Whether to raise errors instead of logging them
47
- safe_to_import: Set of modules that are safe to import during deserialization
48
- serializer: Function to serialize delta data
49
- verify_symmetry: Whether to verify symmetry of bidirectional deltas
50
- bidirectional: Whether delta can be applied in both directions
51
- always_include_values: Whether to always include values in delta
52
- iterable_compare_func_was_used: Whether custom iterable comparison was used
53
- force: Force delta creation even with warnings
54
- fill: Fill value for missing items
55
"""
56
```
57
58
### Delta Serialization
59
60
Serialize delta objects to various formats for storage, transmission, and persistence.
61
62
```python { .api }
63
def dump(self, file) -> None:
64
"""
65
Serialize delta to a file object.
66
67
Parameters:
68
- file: File object to write delta to
69
"""
70
71
def dumps(self) -> bytes:
72
"""
73
Serialize delta to bytes.
74
75
Returns:
76
Bytes representation of the serialized delta.
77
"""
78
79
def to_dict(self) -> Dict:
80
"""
81
Convert delta to dictionary representation.
82
83
Returns:
84
Dictionary representation of the delta.
85
"""
86
87
def to_flat_dicts(self, include_action_in_path: bool = False, report_type_changes: bool = True) -> List[FlatDeltaRow]:
88
"""
89
Convert delta to flat dictionary format.
90
91
Parameters:
92
- include_action_in_path: Whether to include action in path
93
- report_type_changes: Whether to report type changes
94
95
Returns:
96
List of flat delta row dictionaries.
97
"""
98
99
def to_flat_rows(self, include_action_in_path: bool = False, report_type_changes: bool = True) -> List[FlatDeltaRow]:
100
"""
101
Convert delta to flat row format.
102
103
Parameters:
104
- include_action_in_path: Whether to include action in path
105
- report_type_changes: Whether to report type changes
106
107
Returns:
108
List of flat delta rows.
109
"""
110
111
def reset(self) -> None:
112
"""
113
Reset the delta to its initial state.
114
"""
115
```
116
117
### Delta Deserialization
118
119
Load delta objects from various serialized formats.
120
121
```python { .api }
122
@staticmethod
123
def _from_flat_rows(flat_rows_list: List[FlatDeltaRow]) -> 'Delta':
124
"""
125
Create Delta from flat rows list.
126
127
Parameters:
128
- flat_rows_list: List of flat delta rows
129
130
Returns:
131
Delta object created from flat rows.
132
"""
133
134
@staticmethod
135
def _from_flat_dicts(flat_dict_list: List[Dict]) -> 'Delta':
136
"""
137
Create Delta from flat dictionaries list.
138
139
Parameters:
140
- flat_dict_list: List of flat dictionaries
141
142
Returns:
143
Delta object created from flat dictionaries.
144
"""
145
```
146
147
### Delta Application
148
149
Apply delta objects to create modified versions of objects.
150
151
```python { .api }
152
def apply_to(self, obj: Any) -> Any:
153
"""
154
Apply delta to an object, potentially mutating it.
155
156
Parameters:
157
- obj: Object to apply delta to
158
159
Returns:
160
Modified object (same object if mutate=True, new object if mutate=False).
161
"""
162
163
def create_new_from(self, obj: Any) -> Any:
164
"""
165
Create a new object by applying delta to the provided object.
166
167
Parameters:
168
- obj: Base object to apply delta to
169
170
Returns:
171
New object with delta applied (never mutates original).
172
"""
173
```
174
175
### Operator Support
176
177
Delta objects support mathematical operators for easy application.
178
179
```python { .api }
180
def __add__(self, other: Any) -> Any:
181
"""
182
Apply delta using + operator.
183
184
Usage: result = delta + original_object
185
186
Parameters:
187
- other: Object to apply delta to
188
189
Returns:
190
Object with delta applied.
191
"""
192
193
def __radd__(self, other: Any) -> Any:
194
"""
195
Apply delta using + operator (reverse).
196
197
Usage: result = original_object + delta
198
199
Parameters:
200
- other: Object to apply delta to
201
202
Returns:
203
Object with delta applied.
204
"""
205
```
206
207
## Usage Examples
208
209
### Basic Delta Operations
210
211
```python
212
from deepdiff import DeepDiff, Delta
213
214
# Create objects
215
original = {"name": "John", "age": 30, "city": "New York"}
216
modified = {"name": "John", "age": 31, "city": "Boston"}
217
218
# Create diff and delta
219
diff = DeepDiff(original, modified)
220
delta = Delta(diff)
221
222
# Apply delta to recreate modified object
223
result = delta + original
224
print(result == modified) # True
225
226
# Alternative application method
227
result2 = delta.apply_to(original.copy())
228
print(result2 == modified) # True
229
```
230
231
### Delta Serialization and Storage
232
233
```python
234
# Serialize delta to JSON
235
delta_json = delta.dumps()
236
print(delta_json)
237
238
# Save delta to file
239
delta.dump("changes.json")
240
241
# Load delta from file
242
loaded_delta = Delta.load("changes.json")
243
244
# Apply loaded delta
245
result = loaded_delta + original
246
```
247
248
### Bidirectional Deltas
249
250
```python
251
# Create bidirectional delta for reverse operations
252
diff = DeepDiff(original, modified)
253
bidirectional_delta = Delta(diff, bidirectional=True)
254
255
# Apply forward
256
forward_result = bidirectional_delta + original
257
print(forward_result == modified) # True
258
259
# Apply reverse (if supported by the changes)
260
reverse_result = bidirectional_delta + modified
261
print(reverse_result == original) # May be True depending on change types
262
```
263
264
### Mutation Control
265
266
```python
267
# Non-mutating delta (default)
268
delta = Delta(diff, mutate=False)
269
original_copy = original.copy()
270
result = delta.apply_to(original_copy)
271
print(original_copy == original) # True - original not modified
272
273
# Mutating delta
274
delta_mutating = Delta(diff, mutate=True)
275
original_copy = original.copy()
276
result = delta_mutating.apply_to(original_copy)
277
print(original_copy == modified) # True - original was modified
278
print(result is original_copy) # True - same object returned
279
```
280
281
### Complex Delta Operations
282
283
```python
284
# Work with nested structures
285
nested_original = {
286
"user": {"name": "John", "profile": {"age": 30, "interests": ["reading"]}},
287
"settings": {"theme": "light", "notifications": True}
288
}
289
290
nested_modified = {
291
"user": {"name": "John", "profile": {"age": 31, "interests": ["reading", "coding"]}},
292
"settings": {"theme": "dark", "notifications": True},
293
"metadata": {"last_updated": "2023-01-01"}
294
}
295
296
diff = DeepDiff(nested_original, nested_modified)
297
delta = Delta(diff)
298
299
# Apply complex changes
300
result = delta + nested_original
301
print(result == nested_modified) # True
302
```
303
304
### Error Handling
305
306
```python
307
# Enable error logging
308
delta = Delta(diff, log_errors=True)
309
310
try:
311
# Apply delta to incompatible object
312
incompatible = {"completely": "different", "structure": True}
313
result = delta + incompatible
314
except Exception as e:
315
print(f"Delta application failed: {e}")
316
```
317
318
### Safe Deserialization
319
320
```python
321
# Control what modules can be imported during deserialization
322
safe_modules = ["datetime", "collections", "json"]
323
delta = Delta(diff, safe_to_import=safe_modules)
324
325
# Serialize with custom objects
326
delta_str = delta.dumps()
327
328
# Load with safety restrictions
329
loaded_delta = Delta.loads(delta_str, safe_to_import=safe_modules)
330
```
331
332
### Working with Lists and Arrays
333
334
```python
335
# Delta operations on lists
336
list_original = [1, 2, 3, 4, 5]
337
list_modified = [1, 2, 4, 5, 6] # Removed 3, added 6
338
339
diff = DeepDiff(list_original, list_modified)
340
delta = Delta(diff)
341
342
result = delta + list_original
343
print(result) # [1, 2, 4, 5, 6]
344
```
345
346
### Chaining Deltas
347
348
```python
349
# Create multiple deltas and chain them
350
step1 = {"value": 10}
351
step2 = {"value": 20}
352
step3 = {"value": 30}
353
354
# Create deltas for each step
355
delta1 = Delta(DeepDiff(step1, step2))
356
delta2 = Delta(DeepDiff(step2, step3))
357
358
# Apply deltas sequentially
359
result = delta2 + (delta1 + step1)
360
print(result == step3) # True
361
```
362
363
## Types
364
365
```python { .api }
366
# Delta serialization formats
367
SerializationFormat = Union['json', 'pickle', 'dill']
368
369
# Delta application modes
370
ApplicationMode = Union['mutate', 'create_new']
371
372
# Delta direction for bidirectional operations
373
DeltaDirection = Union['forward', 'reverse']
374
375
# Safe import configuration
376
SafeImportList = List[str]
377
378
# Delta error information
379
class DeltaError(Exception):
380
"""Base exception for Delta operations."""
381
382
class DeltaUnflattenError(DeltaError):
383
"""Exception raised when Delta cannot be unflattened."""
384
385
# Delta serialization options
386
class DeltaSerializationOptions:
387
format: SerializationFormat
388
pretty_print: bool
389
compression: bool
390
safe_to_import: SafeImportList
391
```