title: Python: Is this an ok way of overriding __eq__ and __hash__?
body: <p>I'm new to Python, and I wanted to make sure that I overrode <code>__eq__</code> and <code>__hash__</code> correctly, so as not to cause painful errors later:</p>
  
  <p>(I'm using Google App Engine.)</p>
  
  <pre><code>class Course(db.Model):
      dept_code = db.StringProperty()
      number = db.IntegerProperty()
      title = db.StringProperty()
      raw_pre_reqs = db.StringProperty(multiline=True)
      original_description = db.StringProperty()
  
      def getPreReqs(self):
          return pickle.loads(str(self.raw_pre_reqs))
  
      def __repr__(self):
          title_msg = self.title if self.title else "Untitled"
          return "%s %s: %s" % (self.dept_code, self.number, title_msg)
  
      def __attrs(self):
          return (self.dept_code, self.number, self.title, self.raw_pre_reqs, self.original_description)
  
      def __eq__(self, other):
          return isinstance(other, Course) and self.__attrs() == other.__attrs()
  
      def __hash__(self):
          return hash(self.__attrs())
  </code></pre>
  
  <p>A slightly more complicated type:</p>
  
  <pre><code>class DependencyArcTail(db.Model):
      ''' A list of courses that is a pre-req for something else '''
      courses = db.ListProperty(db.Key)
  
      ''' a list of heads that reference this one '''
      forwardLinks = db.ListProperty(db.Key)
  
      def __repr__(self):
          return "DepArcTail %d: courses='%s' forwardLinks='%s'" % (id(self), getReprOfKeys(self.courses), getIdOfKeys(self.forwardLinks))
  
      def __eq__(self, other):
          if not isinstance(other, DependencyArcTail):
              return False
  
          for this_course in self.courses:
              if not (this_course in other.courses):
                  return False
  
          for other_course in other.courses:
              if not (other_course in self.courses):
                  return False
  
          return True
  
      def __hash__(self):
          return hash((tuple(self.courses), tuple(self.forwardLinks)))
  </code></pre>
  
  <p>Everything look good?</p>
  
  <p><strong>Updated to reflect @Alex's comments</strong></p>
  
  <pre><code>class DependencyArcTail(db.Model):
      ''' A list of courses that is a pre-req for something else '''
      courses = db.ListProperty(db.Key)
  
      ''' a list of heads that reference this one '''
      forwardLinks = db.ListProperty(db.Key)
  
      def __repr__(self):
          return "DepArcTail %d: courses='%s' forwardLinks='%s'" % (id(self), getReprOfKeys(self.courses), getIdOfKeys(self.forwardLinks))
  
      def __eq__(self, other):
          return isinstance(other, DependencyArcTail) and set(self.courses) == set(other.courses) and set(self.forwardLinks) == set(other.forwardLinks)
  
      def __hash__(self):
          return hash((tuple(self.courses), tuple(self.forwardLinks)))
  </code></pre>