# Buggy code
def file_matches(self, text):
    """Match filenames, expanding ~USER type strings.

    Most of the seemingly convoluted logic in this completer is an
    attempt to handle filenames with spaces in them.  And yet it's not
    quite perfect, because Python's readline doesn't expose all of the
    GNU readline details needed for this to be done correctly.

    For a filename with a space in it, the printed completions will be
    only the parts after what's already been typed (instead of the
    full completions, as is normally done).  I don't think with the
    current (as of Python 2.3) Python readline it's possible to do
    better."""

    # io.rprint('Completer->file_matches: <%r>' % text) # dbg

    # chars that require escaping with backslash - i.e. chars
    # that readline treats incorrectly as delimiters, but we
    # don't want to treat as delimiters in filename matching
    # when escaped with backslash
    if text.startswith("!"):
        text = text[1:]
        text_prefix = "!"
    else:
        text_prefix = ""

    text_until_cursor = self.text_until_cursor
    # track strings with open quotes
    open_quotes = has_open_quotes(text_until_cursor)

    if "(" in text_until_cursor or "[" in text_until_cursor:
        lsplit = text
    else:
        try:
            # arg_split ~ shlex.split, but with unicode bugs fixed by us
            lsplit = arg_split(text_until_cursor)[-1]
        except ValueError:
            # typically an unmatched ", or backslash without escaped char.
            if open_quotes:
                lsplit = text_until_cursor.split(open_quotes)[-1]
            else:
                return []
        except IndexError:
            # tab pressed on empty line
            lsplit = ""

    if not open_quotes and lsplit != protect_filename(lsplit):
        # if protectables are found, do matching on the whole escaped name
        has_protectables = True
        text0, text = text, lsplit
    else:
        has_protectables = False
        text = os.path.expanduser(text)

    if text == "":
        return [text_prefix + protect_filename(f) for f in self.glob("*")]

    # Compute the matches from the filesystem
    m0 = self.clean_glob(text.replace("\\", ""))

    if has_protectables:
        # If we had protectables, we need to revert our changes to the
        # beginning of filename so that we don't double-write the part
        # of the filename we have so far
        len_lsplit = len(lsplit)
        matches = [text_prefix + text0 + protect_filename(f[len_lsplit:]) for f in m0]
    else:
        if open_quotes:
            # if we have a string with an open quote, we don't need to
            # protect the names at all (and we _shouldn't_, as it
            # would cause bugs when the filesystem call is made).
            matches = m0
        else:
            matches = [text_prefix + protect_filename(f) for f in m0]

    # io.rprint('mm', matches)  # dbg

    # Mark directories in input list by appending '/' to their names.
    matches = [x + "/" if os.path.isdir(x) else x for x in matches]
    return matches


# Traceback (TypeError)
Python 2.7.11+ (default, Mar 30 2016, 21:00:42)
Type "copyright", "credits" or "license" for more information.

IPython 5.0.0.dev -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: dException in thread Thread-7:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/local/lib/python2.7/dist-packages/prompt_toolkit/interface.py", line 742, in run
completions = list(buffer.completer.get_completions(document, complete_event))
File "/home/bwillar0/projects/python/ipython/IPython/terminal/ptshell.py", line 55, in gets
m = unicodedata.normalize('NFC', m)
TypeError: normalize() argument 2 must be unicode, not str

# Fixed code
def file_matches(self, text):
    """Match filenames, expanding ~USER type strings.

    Most of the seemingly convoluted logic in this completer is an
    attempt to handle filenames with spaces in them.  And yet it's not
    quite perfect, because Python's readline doesn't expose all of the
    GNU readline details needed for this to be done correctly.

    For a filename with a space in it, the printed completions will be
    only the parts after what's already been typed (instead of the
    full completions, as is normally done).  I don't think with the
    current (as of Python 2.3) Python readline it's possible to do
    better."""

    # io.rprint('Completer->file_matches: <%r>' % text) # dbg

    # chars that require escaping with backslash - i.e. chars
    # that readline treats incorrectly as delimiters, but we
    # don't want to treat as delimiters in filename matching
    # when escaped with backslash
    if text.startswith("!"):
        text = text[1:]
        text_prefix = "!"
    else:
        text_prefix = ""

    text_until_cursor = self.text_until_cursor
    # track strings with open quotes
    open_quotes = has_open_quotes(text_until_cursor)

    if "(" in text_until_cursor or "[" in text_until_cursor:
        lsplit = text
    else:
        try:
            # arg_split ~ shlex.split, but with unicode bugs fixed by us
            lsplit = arg_split(text_until_cursor)[-1]
        except ValueError:
            # typically an unmatched ", or backslash without escaped char.
            if open_quotes:
                lsplit = text_until_cursor.split(open_quotes)[-1]
            else:
                return []
        except IndexError:
            # tab pressed on empty line
            lsplit = ""

    if not open_quotes and lsplit != protect_filename(lsplit):
        # if protectables are found, do matching on the whole escaped name
        has_protectables = True
        text0, text = text, lsplit
    else:
        has_protectables = False
        text = os.path.expanduser(text)

    if text == "":
        return [
            text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")
        ]

    # Compute the matches from the filesystem
    m0 = self.clean_glob(text.replace("\\", ""))

    if has_protectables:
        # If we had protectables, we need to revert our changes to the
        # beginning of filename so that we don't double-write the part
        # of the filename we have so far
        len_lsplit = len(lsplit)
        matches = [text_prefix + text0 + protect_filename(f[len_lsplit:]) for f in m0]
    else:
        if open_quotes:
            # if we have a string with an open quote, we don't need to
            # protect the names at all (and we _shouldn't_, as it
            # would cause bugs when the filesystem call is made).
            matches = m0
        else:
            matches = [text_prefix + protect_filename(f) for f in m0]

    # Mark directories in input list by appending '/' to their names.
    return [cast_unicode_py2(x + "/") if os.path.isdir(x) else x for x in matches]