Repository: ipython/ipython

Issue:
%run filename autocompletion "The kernel heartbeat has been inactive ... " error
It only happens when I run it as an application, with "Run in terminal" unchecked.
(When I run it in terminal, it does not happen)

When I press tab to autocomplete during the input of the argument of the run magic command, for example:

In [2]: %run 'work[TAB]

ipython-qtconsole hangs for a while, and then gives me the following error:

The kernel heartbeat has been inactive for 3.00 seconds. Do you want to restart the kernel? You may first want to check the network connection.



Discussion:
In addition, I'm using openSUSE 11.4 x64 and KDE. ipython is installed on top of Python 2.7.1 |EPD 7.0-1 (64-bit)

When you run it from a terminal, does it complete successfully? Does any message appear at the terminal?

When you run it as an application, what's the working directory (`%pwd` in IPython)?

Yes if I fire up the qtconsole in terminal, it completes fine without any message on the terminal.

In qtconsole application, 

%pwd 
Out[1]: '/home/joon/documents'

Thank you,
Joon

Hmm, nothing obvious there, then. I can't make a launcher for it work properly at the moment, so I can't try to replicate it.

OK, I've managed to get a launcher that works, by having the entry point create a PYTHONPATH environment variable. But I can't replicate the problem you're having - `%run 'wha<tab>` worked for me, with the Terminal parameter of the .desktop file true or false. This is with Ubuntu 11.04, Python 2.7.1

When I make it an application, do I have to do something with PYTHONPATH? 
Also I will install ipython on top of the python comes with my openSUSE  distribution and see if it still happens.

Yes. ipython-qtconsole I installed on top of my system python does not show this. It seems it only happens with the one with EPD. Interesting.

If you install the dev version of IPython, you shouldn't have to do anything with your PYTHONPATH. I usually use the dev version inside a virtualenv, so the script called by the launcher had to change the PYTHONPATH so it could import the dev version.

@fperez: Do you know of any EPD-on-Linux users who could replicate this? And any way to debug a kernel crash that only occurs when the terminal isn't there to display the traceback?

I'm not sure I'm reading this correctly, but are you using _current_ IPython with EPD Python, or the IPython that ships with EPD when you see the problem?  If it's the IPython that ships with EPD, this may well be a bug that's been fixed since then.

Of course this is IPython 0.11.dev - which I installed on top of EPD with python setup.py install. (After getting rid of older ipython)
And I don't think the version with EPD has qtconsole. :)

@takluyver, I don't use EPD on linux, unfortunately.  I'm pinging @rkern in case he can get in touch with someone at Enthought who does the linux epd work who could help.

One thing that could be done would be to instrument the code to log everything to a file instead of to stdout.  Right now we don't have an easy flag for that, so it would need to be done manually.  But replacing `sys.stdout/err` with an open file object by hand in the kernel should do the trick as a temporary hack, and might provide useful info. @joonpy, if you are willing to play with that and can get any diagnostics, do send them our way.  Unfortunately I don't have the time/bandwidth right now to set up an EPD/linux environment to try and replicate this...

@joonpy - a lot of app code has been rewritten recently, can you check to make sure this still happens with current master?

Will do. Sorry I have an important exam next Wednesday so I won't be able to test it by then. Anyway thanks!

I've reproduced this on Ubuntu.  I've also had reports of the qtconsole not working when run from pythonw on Windows, which may be related.

My guess is there's something not properly checking for the existence of stdout/err, which are nonexistent or closed in these situations.

Glad that you were able to reproduce this. :)


Resolving patch:
diff --git a/IPython/config/application.py b/IPython/config/application.py
--- a/IPython/config/application.py
+++ b/IPython/config/application.py
@@ -161,7 +161,12 @@ def init_logging(self):
         """
         self.log = logging.getLogger(self.__class__.__name__)
         self.log.setLevel(self.log_level)
-        self._log_handler = logging.StreamHandler()
+        if sys.executable.endswith('pythonw.exe'):
+            # this should really go to a file, but file-logging is only
+            # hooked up in parallel applications
+            self._log_handler = logging.StreamHandler(open(os.devnull, 'w'))
+        else:
+            self._log_handler = logging.StreamHandler()
         self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
         self._log_handler.setFormatter(self._log_formatter)
         self.log.addHandler(self._log_handler)
diff --git a/IPython/core/completerlib.py b/IPython/core/completerlib.py
--- a/IPython/core/completerlib.py
+++ b/IPython/core/completerlib.py
@@ -68,7 +68,8 @@ def shlex_split(x):
 
     # shlex.split has unicode bugs, so encode first to str
     if isinstance(x, unicode):
-        x = x.encode(sys.stdin.encoding)
+        # don't raise errors on encoding:
+        x = x.encode(sys.stdin.encoding or sys.getdefaultencoding(), 'replace')
 
     endofline = []
     while x != '':
diff --git a/IPython/zmq/kernelapp.py b/IPython/zmq/kernelapp.py
--- a/IPython/zmq/kernelapp.py
+++ b/IPython/zmq/kernelapp.py
@@ -166,18 +166,17 @@ def init_session(self):
         """create our session object"""
         self.session = Session(config=self.config, username=u'kernel')
 
-    def init_io(self):
-        """redirects stdout/stderr, and installs a display hook"""
-        # Re-direct stdout/stderr, if necessary.
+    def init_blackhole(self):
+        """redirects stdout/stderr to devnull if necessary"""
         if self.no_stdout or self.no_stderr:
             blackhole = file(os.devnull, 'w')
             if self.no_stdout:
                 sys.stdout = sys.__stdout__ = blackhole
             if self.no_stderr:
                 sys.stderr = sys.__stderr__ = blackhole
-
-        # Redirect input streams and set a display hook.
-
+    
+    def init_io(self):
+        """Redirect input streams and set a display hook."""
         if self.outstream_class:
             outstream_factory = import_item(str(self.outstream_class))
             sys.stdout = outstream_factory(self.session, self.iopub_socket, u'stdout')
@@ -199,6 +198,7 @@ def init_kernel(self):
 
     def initialize(self, argv=None):
         super(KernelApp, self).initialize(argv)
+        self.init_blackhole()
         self.init_session()
         self.init_poller()
         self.init_sockets()


Test patch: