prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  AttributeError: 'BlockingKernelClient' object has no attribute 'started_channels'
  I have an app that is centered around IPython running in qt (https://github.com/neuropy/neuropy/blob/master/neuropy/main.py). Yesterday I updated IPython from git, and have had to change a few things since the refactoring about 3 months ago, which split a kernel client off of the kernel manager (see #3011). In the process, I came across the error in the title. This error only happens when I try to create a normal two-process app, but not when creating an inprocess app, ie, it happens with QtKernelManager, but not with QtInProcessKernelManager. I think a BlockingKernelClient happens to be the default for QtKernelClient, which may be due to #3222. Not sure how to fix this in IPython, but to get around it, I set the client_factory to QtKernelClient, and then calling QtKernelManager.client() works fine. My minimalist example is in this gist: https://gist.github.com/mspacek/6018206
  
  Can this be fixed so that setting up the 2-process app doesn't require the extra step of changing the client_factory?
  
  
  </issue>
  <code>
  [start of IPython/qt/manager.py]
  1 """ Defines a KernelClient that provides signals and slots.
  2 """
  3 
  4 from IPython.external.qt import QtCore
  5 
  6 # Local imports
  7 from IPython.utils.traitlets import Bool
  8 
  9 from IPython.kernel import KernelManager
  10 from IPython.kernel.restarter import KernelRestarter
  11 
  12 from .kernel_mixins import QtKernelManagerMixin, QtKernelRestarterMixin
  13 
  14 
  15 class QtKernelRestarter(KernelRestarter, QtKernelRestarterMixin):
  16 
  17     def start(self):
  18         if self._timer is None:
  19             self._timer = QtCore.QTimer()
  20             self._timer.timeout.connect(self.poll)
  21         self._timer.start(self.time_to_dead * 1000)
  22 
  23     def stop(self):
  24         self._timer.stop()
  25 
  26     def poll(self):
  27         super(QtKernelRestarter, self).poll()
  28 
  29 
  30 class QtKernelManager(KernelManager, QtKernelManagerMixin):
  31     """A KernelManager with Qt signals for restart"""
  32 
  33     autorestart = Bool(True, config=True)
  34 
  35     def start_restarter(self):
  36         if self.autorestart and self.has_kernel:
  37             if self._restarter is None:
  38                 self._restarter = QtKernelRestarter(
  39                     kernel_manager=self,
  40                     parent=self,
  41                     log=self.log,
  42                 )
  43                 self._restarter.add_callback(self._handle_kernel_restarted)
  44             self._restarter.start()
  45 
  46     def stop_restarter(self):
  47         if self.autorestart:
  48             if self._restarter is not None:
  49                 self._restarter.stop()
  50 
  51     def _handle_kernel_restarted(self):
  52         self.kernel_restarted.emit()
  53
  [end of IPython/qt/manager.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/IPython/qt/manager.py b/IPython/qt/manager.py
  --- a/IPython/qt/manager.py
  +++ b/IPython/qt/manager.py
  @@ -4,7 +4,7 @@
   from IPython.external.qt import QtCore
   
   # Local imports
  -from IPython.utils.traitlets import Bool
  +from IPython.utils.traitlets import Bool, DottedObjectName
   
   from IPython.kernel import KernelManager
   from IPython.kernel.restarter import KernelRestarter
  @@ -30,6 +30,7 @@
   class QtKernelManager(KernelManager, QtKernelManagerMixin):
       """A KernelManager with Qt signals for restart"""
   
  +    client_class = DottedObjectName('IPython.qt.client.QtKernelClient')
       autorestart = Bool(True, config=True)
   
       def start_restarter(self):
  
verification_info: {"golden_diff": "diff --git a/IPython/qt/manager.py b/IPython/qt/manager.py\n--- a/IPython/qt/manager.py\n+++ b/IPython/qt/manager.py\n@@ -4,7 +4,7 @@\n from IPython.external.qt import QtCore\n \n # Local imports\n-from IPython.utils.traitlets import Bool\n+from IPython.utils.traitlets import Bool, DottedObjectName\n \n from IPython.kernel import KernelManager\n from IPython.kernel.restarter import KernelRestarter\n@@ -30,6 +30,7 @@\n class QtKernelManager(KernelManager, QtKernelManagerMixin):\n     \"\"\"A KernelManager with Qt signals for restart\"\"\"\n \n+    client_class = DottedObjectName('IPython.qt.client.QtKernelClient')\n     autorestart = Bool(True, config=True)\n \n     def start_restarter(self):\n", "issue": "AttributeError: 'BlockingKernelClient' object has no attribute 'started_channels'\nI have an app that is centered around IPython running in qt (https://github.com/neuropy/neuropy/blob/master/neuropy/main.py). Yesterday I updated IPython from git, and have had to change a few things since the refactoring about 3 months ago, which split a kernel client off of the kernel manager (see #3011). In the process, I came across the error in the title. This error only happens when I try to create a normal two-process app, but not when creating an inprocess app, ie, it happens with QtKernelManager, but not with QtInProcessKernelManager. I think a BlockingKernelClient happens to be the default for QtKernelClient, which may be due to #3222. Not sure how to fix this in IPython, but to get around it, I set the client_factory to QtKernelClient, and then calling QtKernelManager.client() works fine. My minimalist example is in this gist: https://gist.github.com/mspacek/6018206\n\nCan this be fixed so that setting up the 2-process app doesn't require the extra step of changing the client_factory?\n\n", "before_files": [{"content": "\"\"\" Defines a KernelClient that provides signals and slots.\n\"\"\"\n\nfrom IPython.external.qt import QtCore\n\n# Local imports\nfrom IPython.utils.traitlets import Bool\n\nfrom IPython.kernel import KernelManager\nfrom IPython.kernel.restarter import KernelRestarter\n\nfrom .kernel_mixins import QtKernelManagerMixin, QtKernelRestarterMixin\n\n\nclass QtKernelRestarter(KernelRestarter, QtKernelRestarterMixin):\n\n    def start(self):\n        if self._timer is None:\n            self._timer = QtCore.QTimer()\n            self._timer.timeout.connect(self.poll)\n        self._timer.start(self.time_to_dead * 1000)\n\n    def stop(self):\n        self._timer.stop()\n\n    def poll(self):\n        super(QtKernelRestarter, self).poll()\n\n\nclass QtKernelManager(KernelManager, QtKernelManagerMixin):\n    \"\"\"A KernelManager with Qt signals for restart\"\"\"\n\n    autorestart = Bool(True, config=True)\n\n    def start_restarter(self):\n        if self.autorestart and self.has_kernel:\n            if self._restarter is None:\n                self._restarter = QtKernelRestarter(\n                    kernel_manager=self,\n                    parent=self,\n                    log=self.log,\n                )\n                self._restarter.add_callback(self._handle_kernel_restarted)\n            self._restarter.start()\n\n    def stop_restarter(self):\n        if self.autorestart:\n            if self._restarter is not None:\n                self._restarter.stop()\n\n    def _handle_kernel_restarted(self):\n        self.kernel_restarted.emit()\n", "path": "IPython/qt/manager.py"}]}