# Buggy code
def python_func_kw_matches(self, text):
    """Match named parameters (kwargs) of the last open function"""

    if "." in text:  # a parameter cannot be dotted
        return []
    try:
        regexp = self.__funcParamsRegex
    except AttributeError:
        regexp = self.__funcParamsRegex = re.compile(
            r"""
                '.*?(?<!\\)' |    # single quoted strings or
                ".*?(?<!\\)" |    # double quoted strings or
                \w+          |    # identifier
                \S                # other characters
                """,
            re.VERBOSE | re.DOTALL,
        )
    # 1. find the nearest identifier that comes before an unclosed
    # parenthesis before the cursor
    # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
    tokens = regexp.findall(self.text_until_cursor)
    tokens.reverse()
    iterTokens = iter(tokens)
    openPar = 0

    for token in iterTokens:
        if token == ")":
            openPar -= 1
        elif token == "(":
            openPar += 1
            if openPar > 0:
                # found the last unclosed parenthesis
                break
    else:
        return []
    # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
    ids = []
    isId = re.compile(r"\w+$").match

    while True:
        try:
            ids.append(next(iterTokens))
            if not isId(ids[-1]):
                ids.pop()
                break
            if not next(iterTokens) == ".":
                break
        except StopIteration:
            break
    # lookup the candidate callable matches either using global_matches
    # or attr_matches for dotted names
    if len(ids) == 1:
        callableMatches = self.global_matches(ids[0])
    else:
        callableMatches = self.attr_matches(".".join(ids[::-1]))
    argMatches = []
    for callableMatch in callableMatches:
        try:
            namedArgs = self._default_arguments(eval(callableMatch, self.namespace))
        except:
            continue

        for namedArg in namedArgs:
            if namedArg.startswith(text):
                argMatches.append("%s=" % namedArg)
    return argMatches


# 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 python_func_kw_matches(self, text):
    """Match named parameters (kwargs) of the last open function"""

    if "." in text:  # a parameter cannot be dotted
        return []
    try:
        regexp = self.__funcParamsRegex
    except AttributeError:
        regexp = self.__funcParamsRegex = re.compile(
            r"""
                '.*?(?<!\\)' |    # single quoted strings or
                ".*?(?<!\\)" |    # double quoted strings or
                \w+          |    # identifier
                \S                # other characters
                """,
            re.VERBOSE | re.DOTALL,
        )
    # 1. find the nearest identifier that comes before an unclosed
    # parenthesis before the cursor
    # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
    tokens = regexp.findall(self.text_until_cursor)
    tokens.reverse()
    iterTokens = iter(tokens)
    openPar = 0

    for token in iterTokens:
        if token == ")":
            openPar -= 1
        elif token == "(":
            openPar += 1
            if openPar > 0:
                # found the last unclosed parenthesis
                break
    else:
        return []
    # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
    ids = []
    isId = re.compile(r"\w+$").match

    while True:
        try:
            ids.append(next(iterTokens))
            if not isId(ids[-1]):
                ids.pop()
                break
            if not next(iterTokens) == ".":
                break
        except StopIteration:
            break
    # lookup the candidate callable matches either using global_matches
    # or attr_matches for dotted names
    if len(ids) == 1:
        callableMatches = self.global_matches(ids[0])
    else:
        callableMatches = self.attr_matches(".".join(ids[::-1]))
    argMatches = []
    for callableMatch in callableMatches:
        try:
            namedArgs = self._default_arguments(eval(callableMatch, self.namespace))
        except:
            continue

        for namedArg in namedArgs:
            if namedArg.startswith(text):
                argMatches.append("%s=" % namedArg)
    return argMatches