diff --git a/IPython/frontend/terminal/console/interactiveshell.py b/IPython/frontend/terminal/console/interactiveshell.py index 743537a..919c2e7 100644 --- a/IPython/frontend/terminal/console/interactiveshell.py +++ b/IPython/frontend/terminal/console/interactiveshell.py @@ -160,7 +160,7 @@ class ZMQTerminalInteractiveShell(TerminalInteractiveShell): self.km.shell_channel.get_msg() # shell_channel.execute takes 'hidden', which is the inverse of store_hist msg_id = self.km.shell_channel.execute(cell, not store_history) - while not self.km.shell_channel.msg_ready() and self.km.is_alive: + while not self.km.shell_channel.msg_ready() and self.km.is_alive(): try: self.handle_stdin_request(timeout=0.05) except Empty: @@ -389,7 +389,7 @@ class ZMQTerminalInteractiveShell(TerminalInteractiveShell): # ask_exit callback. while not self.exit_now: - if not self.km.is_alive: + if not self.km.is_alive(): # kernel died, prompt for action or exit action = "restart" if self.km.has_kernel else "wait for restart" ans = self.ask_yes_no("kernel died, %s ([y]/n)?" % action, default='y') diff --git a/IPython/kernel/inprocess/kernelmanager.py b/IPython/kernel/inprocess/kernelmanager.py index b31f271..cc103f4 100644 --- a/IPython/kernel/inprocess/kernelmanager.py +++ b/IPython/kernel/inprocess/kernelmanager.py @@ -298,7 +298,6 @@ class InProcessKernelManager(Configurable): def signal_kernel(self, signum): raise NotImplementedError("Cannot signal in-process kernel.") - @property def is_alive(self): return True diff --git a/IPython/kernel/kernelmanager.py b/IPython/kernel/kernelmanager.py index 384f183..9012d07 100644 --- a/IPython/kernel/kernelmanager.py +++ b/IPython/kernel/kernelmanager.py @@ -985,7 +985,7 @@ class KernelManager(Configurable): # most 1s, checking every 0.1s. self.shell_channel.shutdown(restart=restart) for i in range(10): - if self.is_alive: + if self.is_alive(): time.sleep(0.1) else: break @@ -1100,7 +1100,6 @@ class KernelManager(Configurable): else: raise RuntimeError("Cannot signal kernel. No kernel is running!") - @property def is_alive(self): """Is the kernel process still running?""" if self.has_kernel: diff --git a/IPython/kernel/kernelmanagerabc.py b/IPython/kernel/kernelmanagerabc.py index 038e4de..b3c4370 100644 --- a/IPython/kernel/kernelmanagerabc.py +++ b/IPython/kernel/kernelmanagerabc.py @@ -220,7 +220,7 @@ class KernelManagerABC(object): def signal_kernel(self, signum): pass - @abc.abstractproperty + @abc.abstractmethod def is_alive(self): pass diff --git a/IPython/kernel/multikernelmanager.py b/IPython/kernel/multikernelmanager.py index 9b148ed..9e4b130 100644 --- a/IPython/kernel/multikernelmanager.py +++ b/IPython/kernel/multikernelmanager.py @@ -154,6 +154,19 @@ class MultiKernelManager(LoggingConfigurable): """ return self.get_kernel(kernel_id).restart_kernel() + def is_alive(self, kernel_id): + """Is the kernel alive. + + This calls KernelManager.is_alive() which calls Popen.poll on the + actual kernel subprocess. + + Parameters + ========== + kernel_id : uuid + The id of the kernel. + """ + return self.get_kernel(kernel_id).is_alive() + def get_kernel(self, kernel_id): """Get the single KernelManager object for a kernel by its uuid. diff --git a/IPython/kernel/tests/test_kernelmanager.py b/IPython/kernel/tests/test_kernelmanager.py index 0d70da8..0bdec16 100644 --- a/IPython/kernel/tests/test_kernelmanager.py +++ b/IPython/kernel/tests/test_kernelmanager.py @@ -23,8 +23,10 @@ class TestKernelManager(TestCase): def _run_lifecycle(self, km): km.start_kernel(stdout=PIPE, stderr=PIPE) + self.assertTrue(km.is_alive()) km.start_channels(shell=True, iopub=False, stdin=False, hb=False) km.restart_kernel() + self.assertTrue(km.is_alive()) # We need a delay here to give the restarting kernel a chance to # restart. Otherwise, the interrupt will kill it, causing the test # suite to hang. The reason it *hangs* is that the shutdown diff --git a/IPython/kernel/tests/test_multikernelmanager.py b/IPython/kernel/tests/test_multikernelmanager.py index 49a5ac2..29a5f9b 100644 --- a/IPython/kernel/tests/test_multikernelmanager.py +++ b/IPython/kernel/tests/test_multikernelmanager.py @@ -25,10 +25,12 @@ class TestKernelManager(TestCase): def _run_lifecycle(self, km): kid = km.start_kernel(stdout=PIPE, stderr=PIPE) + self.assertTrue(km.is_alive(kid)) self.assertTrue(kid in km) self.assertTrue(kid in km.list_kernel_ids()) self.assertEqual(len(km),1) km.restart_kernel(kid) + self.assertTrue(km.is_alive(kid)) self.assertTrue(kid in km.list_kernel_ids()) # We need a delay here to give the restarting kernel a chance to # restart. Otherwise, the interrupt will kill it, causing the test