# Buggy code
def _create_client_for_kernel(self, connection_file, hostname, sshkey, password):
    # Verifying if the connection file exists
    try:
        cf_path = osp.dirname(connection_file)
        cf_filename = osp.basename(connection_file)
        # To change a possible empty string to None
        cf_path = cf_path if cf_path else None
        connection_file = find_connection_file(filename=cf_filename, path=cf_path)
    except (IOError, UnboundLocalError):
        QMessageBox.critical(
            self, _("IPython"), _("Unable to connect to <b>%s</b>") % connection_file
        )
        return

    # Getting the master id that corresponds to the client
    # (i.e. the i in i/A)
    master_id = None
    given_name = None
    external_kernel = False
    slave_ord = ord("A") - 1
    kernel_manager = None

    for cl in self.get_clients():
        if connection_file in cl.connection_file:
            if cl.get_kernel() is not None:
                kernel_manager = cl.get_kernel()
            connection_file = cl.connection_file
            if master_id is None:
                master_id = cl.id_["int_id"]
            given_name = cl.given_name
            new_slave_ord = ord(cl.id_["str_id"])
            if new_slave_ord > slave_ord:
                slave_ord = new_slave_ord

    # If we couldn't find a client with the same connection file,
    # it means this is a new master client
    if master_id is None:
        self.master_clients += 1
        master_id = to_text_string(self.master_clients)
        external_kernel = True

    # Set full client name
    client_id = dict(int_id=master_id, str_id=chr(slave_ord + 1))

    # Creating the client
    show_elapsed_time = self.get_option("show_elapsed_time")
    reset_warning = self.get_option("show_reset_namespace_warning")
    client = ClientWidget(
        self,
        id_=client_id,
        given_name=given_name,
        history_filename=get_conf_path("history.py"),
        config_options=self.config_options(),
        additional_options=self.additional_options(),
        interpreter_versions=self.interpreter_versions(),
        connection_file=connection_file,
        menu_actions=self.menu_actions,
        hostname=hostname,
        external_kernel=external_kernel,
        slave=True,
        show_elapsed_time=show_elapsed_time,
        reset_warning=reset_warning,
    )

    # Create kernel client
    kernel_client = QtKernelClient(connection_file=connection_file)
    kernel_client.load_connection_file()
    if hostname is not None:
        try:
            connection_info = dict(
                ip=kernel_client.ip,
                shell_port=kernel_client.shell_port,
                iopub_port=kernel_client.iopub_port,
                stdin_port=kernel_client.stdin_port,
                hb_port=kernel_client.hb_port,
            )
            newports = self.tunnel_to_kernel(
                connection_info, hostname, sshkey, password
            )
            (
                kernel_client.shell_port,
                kernel_client.iopub_port,
                kernel_client.stdin_port,
                kernel_client.hb_port,
            ) = newports
        except Exception as e:
            QMessageBox.critical(
                self,
                _("Connection error"),
                _("Could not open ssh tunnel. The error was:\n\n") + to_text_string(e),
            )
            return

    # Assign kernel manager and client to shellwidget
    client.shellwidget.kernel_client = kernel_client
    client.shellwidget.kernel_manager = kernel_manager
    kernel_client.start_channels()
    if external_kernel:
        client.shellwidget.sig_is_spykernel.connect(self.connect_external_kernel)
        client.shellwidget.is_spyder_kernel()

    # Set elapsed time, if possible
    if not external_kernel:
        self.set_elapsed_time(client)

    # Adding a new tab for the client
    self.add_tab(client, name=client.get_name())

    # Register client
    self.register_client(client)


# Traceback (AttributeError)
File "/usr/local/lib/python2.7/dist-packages/spyder/plugins/ipythonconsole.py", line 1060, in create_client_for_kernel
password)
File "/usr/local/lib/python2.7/dist-packages/spyder/plugins/ipythonconsole.py", line 1782, in _create_client_for_kernel
client.shellwidget.kernel_client = kernel_client
File "/usr/local/lib/python2.7/dist-packages/qtconsole/base_frontend_mixin.py", line 57, in kernel_client
kernel_client.iopub_channel.message_received.connect(self._dispatch)
AttributeError: 'QtKernelClient' object has no attribute 'iopub_channel'

# Fixed code
def _create_client_for_kernel(self, connection_file, hostname, sshkey, password):
    # Verifying if the connection file exists
    try:
        cf_path = osp.dirname(connection_file)
        cf_filename = osp.basename(connection_file)
        # To change a possible empty string to None
        cf_path = cf_path if cf_path else None
        connection_file = find_connection_file(filename=cf_filename, path=cf_path)
    except (IOError, UnboundLocalError):
        QMessageBox.critical(
            self, _("IPython"), _("Unable to connect to <b>%s</b>") % connection_file
        )
        return

    # Getting the master id that corresponds to the client
    # (i.e. the i in i/A)
    master_id = None
    given_name = None
    external_kernel = False
    slave_ord = ord("A") - 1
    kernel_manager = None

    for cl in self.get_clients():
        if connection_file in cl.connection_file:
            if cl.get_kernel() is not None:
                kernel_manager = cl.get_kernel()
            connection_file = cl.connection_file
            if master_id is None:
                master_id = cl.id_["int_id"]
            given_name = cl.given_name
            new_slave_ord = ord(cl.id_["str_id"])
            if new_slave_ord > slave_ord:
                slave_ord = new_slave_ord

    # If we couldn't find a client with the same connection file,
    # it means this is a new master client
    if master_id is None:
        self.master_clients += 1
        master_id = to_text_string(self.master_clients)
        external_kernel = True

    # Set full client name
    client_id = dict(int_id=master_id, str_id=chr(slave_ord + 1))

    # Creating the client
    show_elapsed_time = self.get_option("show_elapsed_time")
    reset_warning = self.get_option("show_reset_namespace_warning")
    client = ClientWidget(
        self,
        id_=client_id,
        given_name=given_name,
        history_filename=get_conf_path("history.py"),
        config_options=self.config_options(),
        additional_options=self.additional_options(),
        interpreter_versions=self.interpreter_versions(),
        connection_file=connection_file,
        menu_actions=self.menu_actions,
        hostname=hostname,
        external_kernel=external_kernel,
        slave=True,
        show_elapsed_time=show_elapsed_time,
        reset_warning=reset_warning,
    )

    # Create kernel client
    kernel_client = QtKernelClient(connection_file=connection_file)
    kernel_client.load_connection_file()
    if hostname is not None:
        try:
            connection_info = dict(
                ip=kernel_client.ip,
                shell_port=kernel_client.shell_port,
                iopub_port=kernel_client.iopub_port,
                stdin_port=kernel_client.stdin_port,
                hb_port=kernel_client.hb_port,
            )
            newports = self.tunnel_to_kernel(
                connection_info, hostname, sshkey, password
            )
            (
                kernel_client.shell_port,
                kernel_client.iopub_port,
                kernel_client.stdin_port,
                kernel_client.hb_port,
            ) = newports
        except Exception as e:
            QMessageBox.critical(
                self,
                _("Connection error"),
                _("Could not open ssh tunnel. The error was:\n\n") + to_text_string(e),
            )
            return

    # Assign kernel manager and client to shellwidget
    kernel_client.start_channels()
    client.shellwidget.kernel_client = kernel_client
    client.shellwidget.kernel_manager = kernel_manager
    if external_kernel:
        client.shellwidget.sig_is_spykernel.connect(self.connect_external_kernel)
        client.shellwidget.is_spyder_kernel()

    # Set elapsed time, if possible
    if not external_kernel:
        self.set_elapsed_time(client)

    # Adding a new tab for the client
    self.add_tab(client, name=client.get_name())

    # Register client
    self.register_client(client)