code: def _class_type(klass, ancestors=None):
      
      # XXX we have to store ancestors in case we have an ancestor loop
      if klass._type is not None:
          return klass._type
      if _is_metaclass(klass):
          klass._type = "metaclass"
      elif klass.name.endswith("Exception"):
          klass._type = "exception"
      else:
          if ancestors is None:
              ancestors = set()
          klass_name = klass.qname()
          if klass_name in ancestors:
              # XXX we are in loop ancestors, and have found no type
              klass._type = "class"
              return "class"
          ancestors.add(klass_name)
          for base in klass.ancestors(recurs=False):
              name = _class_type(base, ancestors)
              if name != "class":
                  if name == "metaclass" and not _is_metaclass(klass):
                      # don't propagate it if the current class
                      # can't be a metaclass
                      continue
                  klass._type = base.type
                  break
      if klass._type is None:
          klass._type = "class"
      return klass._type
docs: return a ClassDef node type to differ metaclass and exception
      from 'regular' classes