# Buggy code
def signature_toolbar(python_input):
    """
    Return the `Layout` for the signature.
    """

    def get_tokens(cli):
        result = []
        append = result.append
        Signature = Token.Toolbar.Signature

        if python_input.signatures:
            sig = python_input.signatures[0]  # Always take the first one.

            append((Signature, " "))
            try:
                append((Signature, sig.full_name))
            except IndexError:
                # Workaround for #37: https://github.com/jonathanslenders/python-prompt-toolkit/issues/37
                # See also: https://github.com/davidhalter/jedi/issues/490
                return []

            append((Signature.Operator, "("))

            for i, p in enumerate(sig.params):
                # Workaround for #47: 'p' is None when we hit the '*' in the signature.
                #                     and sig has no 'index' attribute.
                # See: https://github.com/jonathanslenders/ptpython/issues/47
                #      https://github.com/davidhalter/jedi/issues/598
                description = p.description if p else "*"  # or '*'
                sig_index = getattr(sig, "index", 0)

                if i == sig_index:
                    # Note: we use `_Param.description` instead of
                    #       `_Param.name`, that way we also get the '*' before args.
                    append((Signature.CurrentName, str(description)))
                else:
                    append((Signature, str(description)))
                append((Signature.Operator, ", "))

            if sig.params:
                # Pop last comma
                result.pop()

            append((Signature.Operator, ")"))
            append((Signature, " "))
        return result

    return ConditionalContainer(
        content=Window(TokenListControl(get_tokens), height=LayoutDimension.exact(1)),
        # Show only when there is a signature
        filter=HasSignature(python_input)
        &
        # And there are no completions to be shown. (would cover signature pop-up.)
        ~(
            HasCompletions()
            & (
                show_completions_menu(python_input)
                | show_multi_column_completions_menu(python_input)
            )
        )
        # Signature needs to be shown.
        & ShowSignature(python_input)
        &
        # Not done yet.
        ~IsDone(),
    )


# Traceback (KeyError)
from lxml.html import builder as E

E.HTML(
Traceback (most recent call last):
File "/usr/lib/python3.5/site-packages/prompt_toolkit/cache.py", line 32, in get
return self._data[key]
KeyError: 51

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/bin/ptpython", line 9, in <module>
load_entry_point('ptpython==0.35', 'console_scripts', 'ptpython')()
File "/usr/lib/python3.5/site-packages/ptpython/entry_points/run_ptpython.py", line 71, in run
title='Python REPL (ptpython)')
File "/usr/lib/python3.5/site-packages/ptpython/repl.py", line 315, in embed
cli.run()
File "/usr/lib/python3.5/site-packages/prompt_toolkit/interface.py", line 389, in run
self.eventloop.run(self.input, self.create_eventloop_callbacks())
File "/usr/lib/python3.5/site-packages/prompt_toolkit/eventloop/posix.py", line 154, in run
t()
File "/usr/lib/python3.5/site-packages/prompt_toolkit/interface.py", line 326, in redraw
self._redraw()
File "/usr/lib/python3.5/site-packages/prompt_toolkit/interface.py", line 346, in _redraw
self.renderer.render(self, self.layout, is_done=self.is_done)
File "/usr/lib/python3.5/site-packages/prompt_toolkit/renderer.py", line 429, in render
extended_height=size.rows,
File "/usr/lib/python3.5/site-packages/prompt_toolkit/layout/containers.py", line 157, in write_to_screen
c.write_to_screen(cli, screen, mouse_handlers, WritePosition(xpos, ypos, width, s))
File "/usr/lib/python3.5/site-packages/prompt_toolkit/layout/containers.py", line 348, in write_to_screen
c.write_to_screen(cli, screen, mouse_handlers, WritePosition(xpos, ypos, s, height))
File "/usr/lib/python3.5/site-packages/prompt_toolkit/layout/containers.py", line 157, in write_to_screen
c.write_to_screen(cli, screen, mouse_handlers, WritePosition(xpos, ypos, width, s))
File "/usr/lib/python3.5/site-packages/prompt_toolkit/layout/containers.py", line 428, in write_to_screen
width = fl.content.preferred_width(cli, write_position.width).preferred
File "/usr/lib/python3.5/site-packages/prompt_toolkit/layout/containers.py", line 1644, in preferred_width
return self.content.preferred_width(cli, max_available_width)
File "/usr/lib/python3.5/site-packages/prompt_toolkit/layout/containers.py", line 980, in preferred_width
cli, max_available_width - total_margin_width)
File "/usr/lib/python3.5/site-packages/prompt_toolkit/layout/controls.py", line 249, in preferred_width
text = token_list_to_text(self._get_tokens_cached(cli))
File "/usr/lib/python3.5/site-packages/prompt_toolkit/layout/controls.py", line 239, in _get_tokens_cached
cli.render_counter, lambda: self.get_tokens(cli))
File "/usr/lib/python3.5/site-packages/prompt_toolkit/cache.py", line 35, in get
value = getter_func()
File "/usr/lib/python3.5/site-packages/prompt_toolkit/layout/controls.py", line 239, in <lambda>
cli.render_counter, lambda: self.get_tokens(cli))
File "/usr/lib/python3.5/site-packages/ptpython/layout.py", line 211, in get_tokens
for i, p in enumerate(sig.params):
File "/usr/lib/python3.5/site-packages/jedi/evaluate/cache.py", line 41, in wrapper
rv = function(obj, *args, **kwargs)
File "/usr/lib/python3.5/site-packages/jedi/api/classes.py", line 348, in params
sub = followed.get_subscope_by_name('__init__')
File "/usr/lib/python3.5/site-packages/jedi/evaluate/representation.py", line 563, in __getattr__
return getattr(self.base_func, name)
AttributeError: 'Lambda' object has no attribute 'get_subscope_by_name'

# Fixed code
def signature_toolbar(python_input):
    """
    Return the `Layout` for the signature.
    """

    def get_tokens(cli):
        result = []
        append = result.append
        Signature = Token.Toolbar.Signature

        if python_input.signatures:
            sig = python_input.signatures[0]  # Always take the first one.

            append((Signature, " "))
            try:
                append((Signature, sig.full_name))
            except IndexError:
                # Workaround for #37: https://github.com/jonathanslenders/python-prompt-toolkit/issues/37
                # See also: https://github.com/davidhalter/jedi/issues/490
                return []

            append((Signature.Operator, "("))

            try:
                enumerated_params = enumerate(sig.params)
            except AttributeError:
                # Workaround for #136: https://github.com/jonathanslenders/ptpython/issues/136
                # AttributeError: 'Lambda' object has no attribute 'get_subscope_by_name'
                return []

            for i, p in enumerated_params:
                # Workaround for #47: 'p' is None when we hit the '*' in the signature.
                #                     and sig has no 'index' attribute.
                # See: https://github.com/jonathanslenders/ptpython/issues/47
                #      https://github.com/davidhalter/jedi/issues/598
                description = p.description if p else "*"  # or '*'
                sig_index = getattr(sig, "index", 0)

                if i == sig_index:
                    # Note: we use `_Param.description` instead of
                    #       `_Param.name`, that way we also get the '*' before args.
                    append((Signature.CurrentName, str(description)))
                else:
                    append((Signature, str(description)))
                append((Signature.Operator, ", "))

            if sig.params:
                # Pop last comma
                result.pop()

            append((Signature.Operator, ")"))
            append((Signature, " "))
        return result

    return ConditionalContainer(
        content=Window(TokenListControl(get_tokens), height=LayoutDimension.exact(1)),
        # Show only when there is a signature
        filter=HasSignature(python_input)
        &
        # And there are no completions to be shown. (would cover signature pop-up.)
        ~(
            HasCompletions()
            & (
                show_completions_menu(python_input)
                | show_multi_column_completions_menu(python_input)
            )
        )
        # Signature needs to be shown.
        & ShowSignature(python_input)
        &
        # Not done yet.
        ~IsDone(),
    )