code: def connect_client_to_kernel(self, client, is_cython=False,
                                   is_pylab=False, is_sympy=False):
          
          connection_file = client.connection_file
          stderr_handle = None if self.test_no_stderr else client.stderr_handle
          km, kc = self.create_kernel_manager_and_kernel_client(
                       connection_file,
                       stderr_handle,
                       is_cython=is_cython,
                       is_pylab=is_pylab,
                       is_sympy=is_sympy)
  
          # An error occurred if this is True
          if is_string(km) and kc is None:
              client.shellwidget.kernel_manager = None
              client.show_kernel_error(km)
              return
  
          # This avoids a recurrent, spurious NameError when running our
          # tests in our CIs
          if not self.testing:
              kc.started_channels.connect(
                  lambda c=client: self.process_started(c))
              kc.stopped_channels.connect(
                  lambda c=client: self.process_finished(c))
          kc.start_channels(shell=True, iopub=True)
  
          shellwidget = client.shellwidget
          shellwidget.kernel_manager = km
          shellwidget.kernel_client = kc
docs: Connect a client to its kernel