@@ -155,7 +155,7 @@ def validate_objects_for_diff(object_pairs: Iterable[Tuple[Optional["DiffSyncMod
155155 if src_obj .get_identifiers () != dst_obj .get_identifiers ():
156156 raise ValueError (f"Keys mismatch: { src_obj .get_identifiers ()} vs { dst_obj .get_identifiers ()} " )
157157
158- def diff_object_pair (
158+ def diff_object_pair ( # pylint: disable=too-many-return-statements
159159 self , src_obj : Optional ["DiffSyncModel" ], dst_obj : Optional ["DiffSyncModel" ]
160160 ) -> Optional [DiffElement ]:
161161 """Diff the two provided DiffSyncModel objects and return a DiffElement or None.
@@ -180,11 +180,19 @@ def diff_object_pair(
180180
181181 log = self .logger .bind (model = model , unique_id = unique_id )
182182 if self .flags & DiffSyncFlags .SKIP_UNMATCHED_SRC and not dst_obj :
183- log .debug ("Skipping unmatched source object " )
183+ log .debug ("Skipping due to SKIP_UNMATCHED_SRC flag on source adapter " )
184184 self .incr_models_processed ()
185185 return None
186186 if self .flags & DiffSyncFlags .SKIP_UNMATCHED_DST and not src_obj :
187- log .debug ("Skipping unmatched dest object" )
187+ log .debug ("Skipping due to SKIP_UNMATCHED_DST flag on source adapter" )
188+ self .incr_models_processed ()
189+ return None
190+ if src_obj and not dst_obj and src_obj .model_flags & DiffSyncModelFlags .SKIP_UNMATCHED_SRC :
191+ log .debug ("Skipping due to SKIP_UNMATCHED_SRC flag on model" )
192+ self .incr_models_processed ()
193+ return None
194+ if dst_obj and not src_obj and dst_obj .model_flags & DiffSyncModelFlags .SKIP_UNMATCHED_DST :
195+ log .debug ("Skipping due to SKIP_UNMATCHED_DST flag on model" )
188196 self .incr_models_processed ()
189197 return None
190198 if src_obj and src_obj .model_flags & DiffSyncModelFlags .IGNORE :
@@ -284,6 +292,7 @@ def __init__( # pylint: disable=too-many-arguments
284292 ):
285293 """Create a DiffSyncSyncer instance, ready to call `perform_sync()` against."""
286294 self .diff = diff
295+ self .src_diffsync = src_diffsync
287296 self .dst_diffsync = dst_diffsync
288297 self .flags = flags
289298 self .callback = callback
@@ -339,42 +348,51 @@ def sync_diff_element(self, element: DiffElement, parent_model: "DiffSyncModel"
339348 # We only actually need the "new" attrs to perform a create/update operation, and don't need any for a delete
340349 attrs = diffs .get ("+" , {})
341350
342- model : Optional ["DiffSyncModel" ]
351+ # Retrieve Source Object to get its flags
352+ src_model : Optional ["DiffSyncModel" ]
343353 try :
344- model = self .dst_diffsync .get (self .model_class , ids )
345- model .set_status (DiffSyncStatus .UNKNOWN )
354+ src_model = self .src_diffsync .get (self .model_class , ids )
346355 except ObjectNotFound :
347- model = None
356+ src_model = None
348357
349- changed , modified_model = self .sync_model (model , ids , attrs )
350- model = modified_model or model
358+ # Retrieve Dest (and primary) Object
359+ dst_model : Optional ["DiffSyncModel" ]
360+ try :
361+ dst_model = self .dst_diffsync .get (self .model_class , ids )
362+ dst_model .set_status (DiffSyncStatus .UNKNOWN )
363+ except ObjectNotFound :
364+ dst_model = None
365+
366+ changed , modified_model = self .sync_model (src_model = src_model , dst_model = dst_model , ids = ids , attrs = attrs )
367+ dst_model = modified_model or dst_model
351368
352- if not modified_model or not model :
369+ if not modified_model or not dst_model :
353370 self .logger .warning ("No object resulted from sync, will not process child objects." )
354371 return changed
355372
356- if self .action == DiffSyncActions .CREATE :
373+ if self .action == DiffSyncActions .CREATE : # type: ignore
357374 if parent_model :
358- parent_model .add_child (model )
359- self .dst_diffsync .add (model )
375+ parent_model .add_child (dst_model )
376+ self .dst_diffsync .add (dst_model )
360377 elif self .action == DiffSyncActions .DELETE :
361378 if parent_model :
362- parent_model .remove_child (model )
363- if model .model_flags & DiffSyncModelFlags .SKIP_CHILDREN_ON_DELETE :
364- # We don't need to process the child objects, but we do need to discard them from the dst_diffsync
365- self .dst_diffsync .remove (model , remove_children = True )
379+ parent_model .remove_child (dst_model )
380+
381+ skip_children = bool (dst_model .model_flags & DiffSyncModelFlags .SKIP_CHILDREN_ON_DELETE )
382+ self .dst_diffsync .remove (dst_model , remove_children = skip_children )
383+
384+ if skip_children :
366385 return changed
367- self .dst_diffsync .remove (model )
368386
369387 self .incr_elements_processed ()
370388
371389 for child in element .get_children ():
372- changed |= self .sync_diff_element (child , parent_model = model )
390+ changed |= self .sync_diff_element (child , parent_model = dst_model )
373391
374392 return changed
375393
376- def sync_model (
377- self , model : Optional ["DiffSyncModel" ], ids : Mapping , attrs : Mapping
394+ def sync_model ( # pylint: disable=too-many-branches, unused-argument
395+ self , src_model : Optional [ "DiffSyncModel" ], dst_model : Optional ["DiffSyncModel" ], ids : Mapping , attrs : Mapping
378396 ) -> Tuple [bool , Optional ["DiffSyncModel" ]]:
379397 """Create/update/delete the current DiffSyncModel with current ids/attrs, and update self.status and self.message.
380398
@@ -387,27 +405,27 @@ def sync_model(
387405 status = DiffSyncStatus .SUCCESS
388406 message = "No changes to apply; no action needed"
389407 self .log_sync_status (self .action , status , message )
390- return (False , model )
408+ return (False , dst_model )
391409
392410 try :
393- self .logger .debug (f"Attempting model { self .action . value } " )
411+ self .logger .debug (f"Attempting model { self .action } " )
394412 if self .action == DiffSyncActions .CREATE :
395- if model is not None :
413+ if dst_model is not None :
396414 raise ObjectNotCreated (f"Failed to create { self .model_class .get_type ()} { ids } - it already exists!" )
397- model = self .model_class .create (diffsync = self .dst_diffsync , ids = ids , attrs = attrs )
415+ dst_model = self .model_class .create (diffsync = self .dst_diffsync , ids = ids , attrs = attrs )
398416 elif self .action == DiffSyncActions .UPDATE :
399- if model is None :
417+ if dst_model is None :
400418 raise ObjectNotUpdated (f"Failed to update { self .model_class .get_type ()} { ids } - not found!" )
401- model = model .update (attrs = attrs )
419+ dst_model = dst_model .update (attrs = attrs )
402420 elif self .action == DiffSyncActions .DELETE :
403- if model is None :
421+ if dst_model is None :
404422 raise ObjectNotDeleted (f"Failed to delete { self .model_class .get_type ()} { ids } - not found!" )
405- model = model .delete ()
423+ dst_model = dst_model .delete ()
406424 else :
407425 raise ObjectCrudException (f'Unknown action "{ self .action } "!' )
408426
409- if model is not None :
410- status , message = model .get_status ()
427+ if dst_model is not None :
428+ status , message = dst_model .get_status ()
411429 else :
412430 status = DiffSyncStatus .FAILURE
413431 message = f"{ self .model_class .get_type ()} { self .action .value } did not return the model object."
@@ -422,7 +440,7 @@ def sync_model(
422440
423441 self .log_sync_status (self .action , status , message )
424442
425- return (True , model )
443+ return (True , dst_model )
426444
427445 def log_sync_status (self , action : Optional [DiffSyncActions ], status : DiffSyncStatus , message : str ):
428446 """Log the current sync status at the appropriate verbosity with appropriate context.
0 commit comments