docs: def getsource(classorfunc):
      """ Return the source code for a class or function.
  
      Notes:
          Returned source will not include any decorators for the object.
          This will only return the explicit declaration of the object, not any dependencies
  
      Args:
          classorfunc (type or function): the object to get the source code for
  
      Returns:
          str: text of source code (without any decorators). Note: in python 2, this returns unicode
      """
      if _isbuiltin(classorfunc):
          return ''
  
      try:
          source = inspect.getsource(classorfunc)
      except TypeError:  # raised if defined in __main__ - use fallback to get the source instead
          source = getsourcefallback(classorfunc)
  
      declaration = []
  
      lines = source.splitlines()
      if PY2 and not isinstance(source, unicode):
          encoding = detect_encoding(iter(lines).next)[0]
          sourcelines = (s.decode(encoding) for s in lines)
      else:
          sourcelines = iter(lines)
  
      # First, get the declaration
      found_keyword = False
      for line in sourcelines:
          words = line.split()
          if not words:
              continue
          if words[0] in ('def', 'class'):
              found_keyword = True
          if found_keyword:
              cind = line.find(':')
              if cind > 0:
                  declaration.append(line[:cind + 1])
                  after_decl = line[cind + 1:].strip()
                  break
              else:
                  declaration.append(line)
  
      bodylines = list(sourcelines)  # the rest of the lines are body
  
      # If it's a class, make sure we import its superclasses
      # Unfortunately, we need to modify the code to make sure the
      # parent classes have the correct names
      # TODO: find a better way to do this without having to parse code
      if type(classorfunc) == type:
          cls = classorfunc
          base_imports = {}
          for base in cls.__bases__:
              if base.__name__ == 'object' and base.__module__ == 'builtins':  # don't import `object`
                  continue
              if base in base_imports:
                  continue
              if base.__module__ == '__main__':
                  continue
              base_imports[base] = 'from %s import %s' % (base.__module__, base.__name__)
          cind = declaration[0].index('class ')
  
          declstring = declaration[0][:cind] + 'class %s(%s):%s' % (
              cls.__name__,
              ','.join([base.__name__ for base in cls.__bases__]),
              after_decl)
          declaration = [impstring for c, impstring in base_imports.items()
                         if c.__module__ != '__builtin__']
          declaration.append(declstring)
  
      else:
          declaration[-1] += after_decl
  
      return '\n'.join(declaration + bodylines)