def blocks_are_equivalent(block1, block2):
 if (block1.__class__ != block2.__class__):
  return False
 if (set(block1.fields) != set(block2.fields)):
  return False
 for field_name in block1.fields:
  if (field_name in ('parent', 'children')):
   continue
  if (getattr(block1, field_name) != getattr(block2, field_name)):
   return False
 if (block1.has_children != block2.has_children):
  return False
 if block1.has_children:
  if (len(block1.children) != len(block2.children)):
   return False
  for (child_id1, child_id2) in zip(block1.children, block2.children):
   if (child_id1 == child_id2):
    continue
   child1 = block1.runtime.get_block(child_id1)
   child2 = block2.runtime.get_block(child_id2)
   if (not blocks_are_equivalent(child1, child2)):
    return False
 return True

def blocks_are_equivalent ( block1 , block2 ) : if ( block1 . __class__ != block2 . __class__ ) : return False if ( set ( block1 . fields ) != set ( block2 . fields ) ) : return False for field_name in block1 . fields : if ( field_name in ( 'parent' , 'children' ) ) : continue if ( getattr ( block1 , field_name ) != getattr ( block2 , field_name ) ) : return False if ( block1 . has_children != block2 . has_children ) : return False if block1 . has_children : if ( len ( block1 . children ) != len ( block2 . children ) ) : return False for ( child_id1 , child_id2 ) in zip ( block1 . children , block2 . children ) : if ( child_id1 == child_id2 ) : continue child1 = block1 . runtime . get_block ( child_id1 ) child2 = block2 . runtime . get_block ( child_id2 ) if ( not blocks_are_equivalent ( child1 , child2 ) ) : return False return True
compare two blocks for equivalence .