To be exact, it does not update until everything it contains has been read(but only if the stream has been read at least once), which makes it effectively dysfunctional.
Pardon the weird example, but I'm presently trying to write a simple graphical ping monitor:
import tkinter as tk
from subprocess import Popen, PIPE, STDOUT
import shlex, re
from sys import stdout, platform
class Ping(object):
def __init__(self):
if platform == "win32":
command = shlex.split("ping -w 999 -t 8.8.8.8")
elif platform == "linux" or platform == "osx":
command = shlex.split("ping -W 1 8.8.8.8")
self.ping = Popen(command, stdout=PIPE, stderr=STDOUT, shell=True)
self.ping.stdout.readline()
self.ping.stdout.readline()
def get_next_ping(self):
has_line = str.find(self.ping.stdout.peek().decode("ascii", "ignore"), "\n") != -1
if not has_line:
print(self.ping.stdout.peek()) # Debug statement
return None
else:
line = self.ping.stdout.readline().decode("ascii", "ignore")
print(line) # Debug statement
try: return int(float(re.findall("([0-9]+)[^m]?ms", line)[0]))
except IndexError: return -1
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.pingmon = Ping()
self.bind("<ButtonPress-1>", self.check_buffer)
def check_buffer(self, event):
print(self.pingmon.get_next_ping())
app=App()
app.mainloop()
In this example, when you click, the subprocess is polled to see if a new line(containing output ping, or timeout message) is available. If you run the project and begin clicking immediately, you will notice that output of peek()
has stopped updating and is always b'Reply from 8.8.8.8: '
.
I have also tried an alternative method of checking the length of peek
's output, but it is apparently never equal to zero, so that is worthless as well.
Further, I attempted to invoke flush()
method of the stream, but it does not appear to in any way help the situation either
The final result is that subprocess.Popen.stdout.peek()
appears to be dysfunctional, and not usable for its intended purpose of peeking into the output bufer, but Python is a mature language, and I would not expect to find this kind of bug in it, is there anything I am missing? If not, how can I work around this issue?