InProcessKernel fails to start with `pythonw` #10658

Open
polwel opened this Issue Jun 12, 2017 · 3 comments

Comments

Projects
None yet
2 participants

polwel commented Jun 12, 2017

The code below runs fine when I run it via python, but not via pythonw.
It is adapted from a stackexchange post.

Anyhow, I traced the crash down to the kernel_manager.start_kernel() line. The traceback is also given below.

For what it's worth, I am on Windows, Python 3.5.2, IPython 5.1.0, PyQt 5.6. I use the Anaconda distribution.

from PyQt5.QtWidgets import QApplication
from qtconsole.rich_jupyter_widget import RichJupyterWidget
from qtconsole.inprocess import QtInProcessKernelManager
from IPython.lib import guisupport
import sys


class ConsoleWidget(RichJupyterWidget):

    def __init__(self, customBanner=None, *args, **kwargs):
        super(ConsoleWidget, self).__init__(*args, **kwargs)

        if customBanner is not None:
            self.banner = customBanner

        self.kernel_manager = kernel_manager = QtInProcessKernelManager()
        kernel_manager.start_kernel(show_banner=False)  # This fails
        kernel_manager.kernel.gui = 'qt'
        self.kernel_client = kernel_client = self._kernel_manager.client()
        kernel_client.start_channels()

        def stop():
            kernel_client.stop_channels()
            kernel_manager.shutdown_kernel()
            guisupport.get_app_qt().exit()
        self.exit_requested.connect(stop)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = ConsoleWidget()
    w.show()
    sys.exit(app.exec())
  File "xxxxxxxxxxxxx", line 19, in __init__
    kernel_manager.start_kernel(show_banner=False)
  File "C:\Program Files\Anaconda3\lib\site-packages\ipykernel\inprocess\manager.py", line 46, in start_kernel
    self.kernel = InProcessKernel(parent=self, session=self.session)
  File "C:\Program Files\Anaconda3\lib\site-packages\ipykernel\inprocess\ipkernel.py", line 72, in __init__
    super(InProcessKernel, self).__init__(**traits)
  File "C:\Program Files\Anaconda3\lib\site-packages\ipykernel\ipkernel.py", line 46, in __init__
    kernel      = self,
  File "C:\Program Files\Anaconda3\lib\site-packages\traitlets\config\configurable.py", line 412, in instance
    inst = cls(*args, **kwargs)
  File "C:\Program Files\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 499, in __init__
    self.init_io()
  File "C:\Program Files\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 658, in init_io
    io.stdout = io.IOStream(sys.stdout)
  File "C:\Program Files\Anaconda3\lib\site-packages\IPython\utils\io.py", line 34, in __init__
    raise ValueError("fallback required, but not specified")
ValueError: fallback required, but not specified

Owner

takluyver commented Jun 12, 2017

It's trying to set up some deprecated functionality. I think that setting sys.stdout = sys.stderr = io.StringIO() beforehand should work.

Heads up, though, the in process kernel machinery doesn't work terribly well and is not a focus of development.

polwel commented Jun 13, 2017

Thanks for the super quick response. That was awesome.

Ok, I think I see the issue. When running pythonw, sys.stdout is None, causing the failure. What I have done now is the following:

if sys.executable.endswith('pythonw.exe'):
    sys.stdout = open(self.logFilePath + '/stdout.txt', 'w')
    sys.stderr = open(self.logFilePath + '/stderr.txt', 'w')

Anyway, do you actually discourage the use of InProcessKernel? Can you suggest an alternative?

I am looking for a way to include a scripting tool into my application. I require access to some functionality of the app obviously. I don't exactly need all the bells and whistles of IPython, but it struck me as an easy and straightforward way.

Thanks again for the help,, much appreciated.

Owner

takluyver commented Jun 13, 2017

Anyway, do you actually discourage the use of InProcessKernel?

Yes, I've started a thread on the mailing list to consider officially deprecating it. It's kind of de facto deprecated already.

Can you suggest an alternative?

You can embed the kernel in your application and run the Qt console to talk to it as a separate window:
https://github.com/ipython/ipykernel/blob/master/examples/embedding/ipkernel_qtapp.py

It should also be possible to have the Qt console embedded in the application and talking over a ZMQ channel to the same process (i.e. not using InProcessKernel), but I don't think we have an example for this yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment