Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't set sys.stdout when using IPython. #12989

Open
LucLabarriere opened this issue May 23, 2021 · 2 comments
Open

Can't set sys.stdout when using IPython. #12989

LucLabarriere opened this issue May 23, 2021 · 2 comments

Comments

@LucLabarriere
Copy link

Hi everyone
It's the first time I write an issue, so not sure this is the correct way to do it..
I embedded an IPython console inside a PyQt5 application. Everything was working correctly until I started to implement a better logging system for my app. Now when I change my sys.stdout to output to some widget, an exception is raised originating from the IOStream class: ValueError: fallback required, but not specified. Actually, i found a fix: in the IPython/core/interactiveshell.py and in the init_io method, if i add fallback=sys.__stdout__ as an argument to the IOStream constructor, the error disappears

  • original code:
    io.stdout = io.IOStream(sys.stdout)
    io.stderr = io.IOStream(sys.stderr)
  • my fix:
    io.stdout = io.IOStream(sys.stdout, fallback=sys.__stdout__)
    io.stderr = io.IOStream(sys.stderr, fallback=sys.__stdout__)

note: I can't set my sys.stdout to IOStream(myWidget, fallback=sys.__stdout__) in my own code because myWidget is ignored, and sys.__stdout__ is used instead.
Is this behavior intended ? Am I doing something wrong ?
Thanks in advance

@Carreau
Copy link
Member

Carreau commented May 28, 2021

Thanks a lot for your question and apologies for the delay in the response.

From the top of my head I'm not quite sure, I'd have to dig in the part of the code, which may take me some time.

IOStream should not be used and is here for legacy reason, so I'm curious why you get messages about it.

@LucLabarriere
Copy link
Author

Thank you for your answer. I managed to write a minimal example reproducing the error:

from PyQt5.QtCore import QTimer
from qtconsole.rich_jupyter_widget import RichJupyterWidget
from qtconsole.inprocess import QtInProcessKernelManager
from PyQt5 import QtWidgets
import sys
import time

class Application(QtWidgets.QApplication):
    def __init__(self, *args):
        super().__init__(*args)
        self.main_window = QtWidgets.QMainWindow()
        
        self.widget_container = QtWidgets.QWidget()
        self.widget_output = Output()

        self.widget_console = QIPythonWidget(self)  # line 1
        sys.stdout = self.widget_output  # line 2
        
        self.widget_container.setLayout(QtWidgets.QVBoxLayout())
        self.main_window.setCentralWidget(self.widget_container)
        self.widget_container.layout().addWidget(self.widget_console)
        self.widget_container.layout().addWidget(self.widget_output)
        self.main_window.show()
        
        self.timer = QTimer()
        self.timer.setInterval(500)
        self.timer.timeout.connect(lambda: print(time.time()))
        self.timer.start()
    
class QIPythonWidget(RichJupyterWidget):
    def __init__(self,  app: Application, *args, **kwargs):
        super(RichJupyterWidget, self).__init__(*args, **kwargs)
        self.kernel_manager = QtInProcessKernelManager()
        self.kernel_manager.start_kernel()
        self.kernel_manager.kernel.gui = 'qt'
        self.kernel_client = self._kernel_manager.client()
        self.kernel_client.start_channels()
        
class Output(QtWidgets.QTextEdit):
    def __init__(self):
        super().__init__()
    
    def write(self, msg):
        self.insertPlainText(msg)
        
if __name__ == '__main__':
    app = Application([])
    sys.exit(app.exec_())

This works fine, however, if i swap the lines 1 and 2, the error reappears. I'm not sure yet if i can reorder my code to initialize IPython before my logging system

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants