Python, Tkinter and popen problem

Piet van Oostrum piet at
Sat May 30 04:30:41 EDT 2009

>>>>> norseman <norseman at> (n) wrote:

>n> Piet van Oostrum wrote:
>>>>>>>> norseman <norseman at> (n) wrote:
>n> I have tried both and Popen2.popen2().
>n> os.popen runs both way, contrary to docs.
>>> What do you mean `os.popen runs both way'?

>n> It reads from child while console writes directly to child -  thus
>n> eliminating the problem of coding a pass through from master.

Yes, but that is not `both way': popen connects the parent to the child
through a pipe. The pipe works one way: from the child to the parent
with 'r' (default), from the parent to the child with 'w'. You can't
communicate the other way through the pipe. So the communication from
the parent process to the child through the popen is ONE WAY. If you
want TWO WAY communication you can use popen2, or better use

A child process always inherits stdin, stdout and stderr from the parent
unless you change that (e.g. by redirecting to a pipe, like popen does
for one of them). It doesn't matter whether you use os.popen,
subprocess.Popen, os.system, or os.fork to create the child process. So
in your case if the parent inputs from the console, so does the child.
But note: this is not communication from the parent process to the
child, but from YOU to the child. So the parent-child communication is

>n> "...
>>> doesn't work as the iterator for a file, including pipes, does a
>>> read ahead (see the doc on and therefore is not suitable
>>> for interactive use.
>n> ..."

>n> If I understand you the above can be stated as:

>n> The above does not work as an iterator for any file type, including
>n> pipes, but it does do read aheads .... and therefore is not suitable for
>n> interactive use.

For files in general it is no problem because the contents of the file
is not interactively generated. Read ahead on a file works as long as
you do'nt use readline() on the file in between the iterator actions.
For a socket it could be the same problem if the other side generates
the output interactively.

>n> If that is correct then read ahead is simply buffered file reads (grab a
>n> chunk, parcel it out on demand) - yes?

I don't know, I have looked into the source code but it isn't clear to
me. I noticed that iteration didn't work and then looked up the
documentation. It talks about read ahead for efficiency.
>n> As for "... not suitable for interactive ..." Really?  Except for
>n> special purpose use the current interactive components are all buffered
>n> for read ahead use.  Check the actual code for your keyboard, your mouse
>n> and so forth. It's the read ahead that allows faster time to completion.
>n> It's why C-code has the putch function.

Yes, but they only read what is available. The iterator apparently tries
to read more and then has to wait.

>n> Yes - Sync IS the bigger hammer!  If that is what is needed - so be it.
>n> All character readers (byte at a time) should obey a flush(). Depending
>n> on type, code for the reader controls whether or not it flushes
>n> incomplete "lines" in the in-buffer(s). Proper implementation limits lost
>n> data on system crash.

I don't understand what you say here. As I told before it has nothing to
do with sync(). Also for reading there is no flush(); the flush() is
done on the other side of the pipe. Yes, and sync() has to do with
system crashes but that is not what we are talking about in this thread.

>n> In trying to use flush at the master side I keep getting messages
>n> indicating strings (completed or not) are not flushable.  Strange practice.

If you print to the console in the master the flush is done

>n> ---
>n> from subprocess import Popen, PIPE
>n> xx = Popen([""], stdout=PIPE).stdout

>n> while True:
>n>     line = xx.readline()
>n>     if not line: break
>n>     print "\t" + line,
>n> ---
>n> DOES WORK on Python 2.5.2 on Slackware 10.2 - THANK YOU VERY MUCH!!!
>n> Isn't working on Windows. error message comes as one of two forms.
>n>   1- %1 not found       #as shown above
>n>   2- file not found     #as ...["python"]...
>n>         same            #as #2 even with full paths given

That should be Popen(["python", ""], stdout=PIPE).stdout
And then with both python and given as full paths.

>n> I get the impression subprocess ignores system things on Windows.
>n> The routines it purposes to replace do use them.  At any rate, subprocess
>n> is NOT consistent across platforms.

subprocess is, but Windows isn't. On Unix-like systems, the python
command is usually in your PATH, so just giving "python" works. In
Windows PATH is underused, and commands like python often are not in
PATH, unless you as a user has adapted the path, or maybe there is an
installation option to adapt the PATH. The reason probably is that in
Windows almost nobody uses the command line but only clicks and the PATH
is not relevant.

>n> Some questions:
>n> 	1) "...], stdout=PIPE).stdout
>n>                    ^            ^  why the double use?

It is not a double use. Popen([""], stdout=PIPE) gives you a Popen
object, not a file object. If you add .stdout you get the stdout
attribute of the Popen object of which you just before stated that it
should be a pipe. So the stdout=PIPE parameter makes it create a pipe,
and the .stdout returns you that pipe.

>n> 	2) "if not line: break"  what tells what to look for EOL
>n>                                    or is the use of 'line' missleading?
>n>                                    is it a byte at a time output?

No, line is a line, as indicated by the readline() call. The 
"if not line" is a test for end of file. In this case the end of the
child process (pipe closed).

>n>                                  how much CPU usage does the loop use?

Not much, It is mainly waiting for input but that doesn't consume CPU.

>n>                                  is there something in that loop that
>n>                                    uses the system pipe triggers to
>n>                                    reduce excessive CPU waste or does it
>n>                                    constantly poll?  If so where does
>n>                                    what code get put to signal (or set)
>n>                                    the courtesy semiphores so it does
>n>                                    not hog the system?

It doesn't poll or use semaphores. The beauty of a pipe is that it
automatically synchronises the reader and writer processes. If you do a
read on a pipe and it is empty the OS just blocks you. When the other
end writes something in the pipe, the OS will unblock you.

Piet van Oostrum <piet at>
URL: [PGP 8DAE142BE17999C4]
Private email: piet at

More information about the Python-list mailing list