def equal(value_a, value_b):
    """Determine if two **HasProperties** instances are equivalent

    Equivalence is determined by checking if (1) the two instances are
    the same class and (2) all Property values on two instances are
    equal, using :code:`Property.equal`. If the two values are the same
    HasProperties instance (eg. :code:`value_a is value_b`) this method
    returns True. Finally, if either value is not a HasProperties
    instance, equality is simply checked with ==.

    .. note::

        HasProperties objects with recursive self-references will not
        evaluate to equal, even if their property values and structure
        are equivalent.
    """
    if (
            not isinstance(value_a, HasProperties) or
            not isinstance(value_b, HasProperties)
    ):
        return value_a == value_b
    if getattr(value_a, '_testing_equality', False):
        return False
    value_a._testing_equality = True                                           #pylint: disable=protected-access
    try:
        if value_a is value_b:
            return True
        if value_a.__class__ is not value_b.__class__:
            return False
        for prop in itervalues(value_a._props):
            prop_a = getattr(value_a, prop.name)
            prop_b = getattr(value_b, prop.name)
            if prop_a is None and prop_b is None:
                continue
            if (
                    prop_a is not None and
                    prop_b is not None and
                    prop.equal(prop_a, prop_b)
            ):
                continue
            return False
        return True
    finally:
        value_a._testing_equality = False
def equal ( value_a , value_b ) : if ( not isinstance ( value_a , HasProperties ) or not isinstance ( value_b , HasProperties ) ) : return value_a == value_b if getattr ( value_a , '_testing_equality' , False ) : return False value_a . _testing_equality = True try : if value_a is value_b : return True if value_a . __class__ is not value_b . __class__ : return False for prop in itervalues ( value_a . _props ) : prop_a = getattr ( value_a , prop . name ) prop_b = getattr ( value_b , prop . name ) if prop_a is None and prop_b is None : continue if ( prop_a is not None and prop_b is not None and prop . equal ( prop_a , prop_b ) ) : continue return False return True finally : value_a . _testing_equality = False
Determine if two **HasProperties** instances are equivalent

    Equivalence is determined by checking if (1) the two instances are
    the same class and (2) all Property values on two instances are
    equal, using :code:`Property.equal`. If the two values are the same
    HasProperties instance (eg. :code:`value_a is value_b`) this method
    returns True. Finally, if either value is not a HasProperties
    instance, equality is simply checked with ==.

    .. note::

        HasProperties objects with recursive self-references will not
        evaluate to equal, even if their property values and structure
        are equivalent.