|
9 | 9 | np_ndarray, np_array_factory, numpy_dtypes, get_doc, |
10 | 10 | not_found, numpy_dtype_string_to_type, dict_, |
11 | 11 | ) |
12 | | -from deepdiff.path import _path_to_elements, _get_nested_obj, GET, GETATTR |
| 12 | +from deepdiff.path import _path_to_elements, _get_nested_obj, _get_nested_obj_and_force, GET, GETATTR |
13 | 13 | from deepdiff.anyset import AnySet |
14 | 14 |
|
15 | 15 |
|
@@ -70,6 +70,7 @@ def __init__( |
70 | 70 | safe_to_import=None, |
71 | 71 | serializer=pickle_dump, |
72 | 72 | verify_symmetry=False, |
| 73 | + force=False, |
73 | 74 | ): |
74 | 75 | if hasattr(deserializer, '__code__') and 'safe_to_import' in set(deserializer.__code__.co_varnames): |
75 | 76 | _deserializer = deserializer |
@@ -104,6 +105,11 @@ def _deserializer(obj, safe_to_import=None): |
104 | 105 | self._numpy_paths = self.diff.pop('_numpy_paths', False) |
105 | 106 | self.serializer = serializer |
106 | 107 | self.deserializer = deserializer |
| 108 | + self.force = force |
| 109 | + if force: |
| 110 | + self.get_nested_obj = _get_nested_obj_and_force |
| 111 | + else: |
| 112 | + self.get_nested_obj = _get_nested_obj |
107 | 113 | self.reset() |
108 | 114 |
|
109 | 115 | def __repr__(self): |
@@ -162,7 +168,14 @@ def _get_elem_and_compare_to_old_value(self, obj, path_for_err_reporting, expect |
162 | 168 | current_old_value = getattr(obj, elem) |
163 | 169 | else: |
164 | 170 | raise DeltaError(INVALID_ACTION_WHEN_CALLING_GET_ELEM.format(action)) |
165 | | - except (KeyError, IndexError, AttributeError, IndexError, TypeError) as e: |
| 171 | + except (KeyError, IndexError, AttributeError, TypeError) as e: |
| 172 | + if self.force: |
| 173 | + forced_old_value = {} |
| 174 | + if action == GET: |
| 175 | + obj[elem] = forced_old_value |
| 176 | + elif action == GETATTR: |
| 177 | + setattr(obj, elem, forced_old_value) |
| 178 | + return forced_old_value |
166 | 179 | current_old_value = not_found |
167 | 180 | if isinstance(path_for_err_reporting, (list, tuple)): |
168 | 181 | path_for_err_reporting = '.'.join([i[0] for i in path_for_err_reporting]) |
@@ -351,14 +364,14 @@ def _get_elements_and_details(self, path): |
351 | 364 | try: |
352 | 365 | elements = _path_to_elements(path) |
353 | 366 | if len(elements) > 1: |
354 | | - parent = _get_nested_obj(obj=self, elements=elements[:-2]) |
| 367 | + parent = self.get_nested_obj(obj=self, elements=elements[:-2]) |
355 | 368 | parent_to_obj_elem, parent_to_obj_action = elements[-2] |
356 | 369 | obj = self._get_elem_and_compare_to_old_value( |
357 | 370 | obj=parent, path_for_err_reporting=path, expected_old_value=None, |
358 | 371 | elem=parent_to_obj_elem, action=parent_to_obj_action) |
359 | 372 | else: |
360 | 373 | parent = parent_to_obj_elem = parent_to_obj_action = None |
361 | | - obj = _get_nested_obj(obj=self, elements=elements[:-1]) |
| 374 | + obj = self.get_nested_obj(obj=self, elements=elements[:-1]) |
362 | 375 | elem, action = elements[-1] |
363 | 376 | except Exception as e: |
364 | 377 | self._raise_or_log(UNABLE_TO_GET_ITEM_MSG.format(path, e)) |
@@ -458,7 +471,7 @@ def _do_set_item_removed(self): |
458 | 471 | def _do_set_or_frozenset_item(self, items, func): |
459 | 472 | for path, value in items.items(): |
460 | 473 | elements = _path_to_elements(path) |
461 | | - parent = _get_nested_obj(obj=self, elements=elements[:-1]) |
| 474 | + parent = self.get_nested_obj(obj=self, elements=elements[:-1]) |
462 | 475 | elem, action = elements[-1] |
463 | 476 | obj = self._get_elem_and_compare_to_old_value( |
464 | 477 | parent, path_for_err_reporting=path, expected_old_value=None, elem=elem, action=action) |
|
0 commit comments