Killing stdout in python breaks get_line_buffer ()

So, I use some libraries, which (unfortunately, to my chagrin) print to stdout for some debugging information. Okay, no problem, I just turned it off:

import sys,os
sys.stdout = open(os.devnull,'wb')

I recently added code to input data input and output to the terminal, which of course requires stdout. But then again, no problem, instead printI can just do:

sys.__stdout__.write('text\n')

Finally, since I am doing it raw_inputin a separate thread, and the program output may interrupt user input, I wanted to repeat the test as described in the first part of this answer to make it more or less seamless with readline.get_line_buffer(). For example, if the user entered foobar:

> foobar

And then another thread says Interrupting text!it should look like this:

Interrupting text!
> foobar

But instead, I observe:

Interrupting text!
>

It turns out that it is readline.get_line_buffer()always empty, and the code cannot repeat what the user typed. If I remove the override sys.stdout, everything will work as expected (except that the debug output from the libraries is not blocked).

I use Python 2.7 for Linux, if that matters. Perhaps what I want to do is impossible, but I would really like to know why this is happening. In my opinion, doing things with stdoutshould not affect the string buffer stdin, but I'm admittedly not familiar with the underlying libraries or implementation.

. - . "> " , . , , . , stdin.log.

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('> ' + line)
    sys.__stdout__.flush()

thread.start_new_thread(noisy_thread, ())
while True:
    sys.__stdout__.write('> ')
    s = raw_input()

sys.stdout = sys.__stdout__ get_line_buffer(), . .

+4
1

raw_input(), , stdout. sys.stdout = sys.__stdout__ raw_input(), . stdin stdout , raw_input .

+1

Source: https://habr.com/ru/post/1655098/


All Articles