def getsourcefallback(cls):
    """ Fallback for getting the source of interactively defined classes (typically in ipython)

    This is basically just a patched version of the inspect module, in which
    we get the code by calling inspect.findsource on an *instancemethod* of
    a class for which inspect.findsource fails.
    """
    for attr in cls.__dict__:
        if inspect.ismethod(getattr(cls, attr)):
            imethod = getattr(cls, attr)
            break
    else:
        raise AttributeError(
            "Cannot get this class' source; it does not appear to have any methods")

    ### This part is derived from inspect.findsource ###
    module = inspect.getmodule(cls)
    file = inspect.getfile(imethod)
    lines = linecache.getlines(file, module.__dict__)
    name = cls.__name__
    pat = re.compile(r'^(\s*)class\s*'+name+r'\b')

    # AMVMOD: find the encoding (necessary for python 2 only)
    #if PY2:
    #    with open(file, 'rb') as infile:
    #        encoding = detect_encoding(infile.readline)[0]

    # make some effort to find the best matching class definition:
    # use the one with the least indentation, which is the one
    # that's most probably not inside a function definition.
    candidates = []
    toplevel = False
    for i in range(len(lines)):
        match = pat.match(lines[i])
        if match:
            # if it's at toplevel, it's already the best one
            if lines[i][0] == 'c':
                flines, flnum = lines, i
                toplevel = True
                break
            # else add whitespace to candidate list
            candidates.append((match.group(1), i))
    if candidates and not toplevel:
        # this will sort by whitespace, and by line number,
        # less whitespace first
        candidates.sort()
        flines, flnum = lines, candidates[0][1]
    elif not candidates and not toplevel:
        raise IOError('could not find class definition')
    ### end modified inspect.findsource ###

    # this is what inspect.getsourcelines does
    glines = inspect.getblock(flines[flnum:])

    # And this is what inspect.getsource does
    if False: #if PY2:
        return ("".join(glines)).decode(encoding)
    else:
        return "".join(glines)