25
25
SNAPSHOT_LOGGER = logging .getLogger (__name__ )
26
26
SNAPSHOT_LOGGER .setLevel (logging .DEBUG if os .environ .get ("DEBUG_SNAPSHOT" ) else logging .WARNING )
27
27
28
+ _PLACEHOLDER_VALUE = "$__marker__$"
29
+
28
30
29
31
class SnapshotMatchResult :
30
32
def __init__ (self , a : dict , b : dict , key : str = "" ):
@@ -218,7 +220,7 @@ def _assert_all(
218
220
self .skip_verification_paths = skip_verification_paths or []
219
221
if skip_verification_paths :
220
222
SNAPSHOT_LOGGER .warning (
221
- f "Snapshot verification disabled for paths: { skip_verification_paths } "
223
+ "Snapshot verification disabled for paths: %s" , skip_verification_paths
222
224
)
223
225
224
226
if self .update :
@@ -306,7 +308,7 @@ def _transform(self, tmp: dict) -> dict:
306
308
try :
307
309
replaced_tmp [key ] = json .loads (dumped_value )
308
310
except JSONDecodeError :
309
- SNAPSHOT_LOGGER .error (f "could not decode json-string:\n { tmp } " )
311
+ SNAPSHOT_LOGGER .error ("could not decode json-string:\n %s" , tmp )
310
312
return {}
311
313
312
314
return replaced_tmp
@@ -365,6 +367,21 @@ def build_full_path_nodes(field_match: DatumInContext):
365
367
366
368
return full_path_nodes [::- 1 ][1 :] # reverse the list and remove Root()/$
367
369
370
+ def _remove_placeholder (_tmp ):
371
+ """Traverse the object and remove any values in a list that would be equal to the placeholder"""
372
+ if isinstance (_tmp , dict ):
373
+ for k , v in _tmp .items ():
374
+ if isinstance (v , dict ):
375
+ _remove_placeholder (v )
376
+ elif isinstance (v , list ):
377
+ _tmp [k ] = _remove_placeholder (v )
378
+ elif isinstance (_tmp , list ):
379
+ return [_remove_placeholder (item ) for item in _tmp if item != _PLACEHOLDER_VALUE ]
380
+
381
+ return _tmp
382
+
383
+ has_placeholder = False
384
+
368
385
for path in self .skip_verification_paths :
369
386
matches = parse (path ).find (tmp ) or []
370
387
for m in matches :
@@ -378,7 +395,24 @@ def build_full_path_nodes(field_match: DatumInContext):
378
395
helper = helper .get (p , None )
379
396
if not helper :
380
397
continue
398
+
381
399
if (
382
400
isinstance (helper , dict ) and full_path [- 1 ] in helper .keys ()
383
401
): # might have been deleted already
384
402
del helper [full_path [- 1 ]]
403
+ elif isinstance (helper , list ):
404
+ try :
405
+ index = int (full_path [- 1 ].lstrip ("[" ).rstrip ("]" ))
406
+ # we need to set a placeholder value as the skips are based on index
407
+ # if we are to pop the values, the next skip index will have shifted and won't be correct
408
+ helper [index ] = _PLACEHOLDER_VALUE
409
+ has_placeholder = True
410
+ except ValueError :
411
+ SNAPSHOT_LOGGER .warning (
412
+ "Snapshot skip path '%s' was not applied as it was invalid for that snapshot" ,
413
+ path ,
414
+ exc_info = SNAPSHOT_LOGGER .isEnabledFor (logging .DEBUG ),
415
+ )
416
+
417
+ if has_placeholder :
418
+ _remove_placeholder (tmp )
0 commit comments