def __ne__(self, other):
    return not self == other

def __hash__(self):
    return hash(self._vals())

def __setattr__(self, attr, val):
    if attr in self.__slots__:
        raise AttributeError("%s slot '%s' is read-only" % (type(self).
            __name__, attr))
super(ValueObject, self).__setattr__(attr, val)
How to define PyCharm-friendly value object in Python?