Killing stdout in python breaks get_line_buffer()
<p>So I'm using some libraries that (unfortunately and much to my chagrin) print to stdout for certain debug info. Okay, no problem, I just disabled it with:</p>

<pre><code>import sys,os
sys.stdout = open(os.devnull,'wb')
</code></pre>

<p>I've recently added code for getting user input and printing output in the terminal, which of course needs stdout. But again, no problem, instead of <code>print</code> I can just do:</p>

<pre><code>sys.__stdout__.write('text\n')
</code></pre>

<p>Finally, since I'm doing <code>raw_input</code> in a separate thread and the program's output can interrupt the user typing, I wanted to re-echo the test as described <a href="http://stackoverflow.com/a/4653306/2258915">in the first part of this answer</a> to make it more or less seamless using <code>readline.get_line_buffer()</code>. For example, if the user entered <code>foobar</code>:</p>

<pre><code>&gt; foobar
</code></pre>

<p>And then another thread says <code>Interrupting text!</code> it should look like:</p>

<pre><code>Interrupting text!
&gt; foobar
</code></pre>

<p>But instead I observe:</p>

<pre><code>Interrupting text!
&gt;
</code></pre>

<p>It turns out that <code>readline.get_line_buffer()</code> is always blank, and the code fails to re-echo what the user had typed. If I remove the <code>sys.stdout</code> override, everything works as expected (except now the debug output from libraries isn't blocked).</p>

<p>I'm using Python 2.7 on Linux if that matters. Perhaps what I want to do is impossible, but I'd really like to know why this is happening. In my mind, doing things with <code>stdout</code> shouldn't affect the <code>stdin</code> line buffer, but I'm admittedly not familiar with the underlying libraries or implementation.</p>

<p>A minimum working example is below. Just type something and wait for the interrupting text. The prompt <code>"&gt; "</code> will be re-echoed, but the text you entered won't be. Simply comment out the second line to see it work correctly. When the thread prints, it logs the line buffer to <code>stdin.log</code>.</p>

<pre><code>import time,readline,thread,sys,os
sys.stdout = open(os.devnull,'wb')  # comment this line!

def noisy_thread():
  while True:
    time.sleep(5)
    line = readline.get_line_buffer()
    with open('stdin.log','a') as f:
      f.write(time.asctime()+' | "'+line+'"\n')
    sys.__stdout__.write('\r'+' '*(len(line)+2)+'\r')
    sys.__stdout__.write('Interrupting text!\n')
    sys.__stdout__.write('&gt; ' + line)
    sys.__stdout__.flush()

thread.start_new_thread(noisy_thread, ())
while True:
    sys.__stdout__.write('&gt; ')
    s = raw_input()
</code></pre>

<p>I've also tried <code>sys.stdout = sys.__stdout__</code> right before the <code>get_line_buffer()</code> call, but that doesn't work either. Any help or explanation is greatly appreciated.</p>

<p>Its the <code>raw_input()</code> that stops working when you redirect the stdout.
If you try <code>sys.stdout = sys.__stdout__</code> just before the <code>raw_input()</code> it works again. 
Both <code>stdin</code> and <code>stdout</code> need to be connected to the terminal in order for <code>raw_input</code> to work.</p>

python multithreading stdout raw-input