Displaying print messages- Emacs

D

Darren Dale

I am using Emacs Python mode, and my project involves reading large
datafiles and processing large arrays. I have some code that reports the
progress during these time consuming processes. It works fine from the
dos shell, but I would really like to work entirely within Emacs. I have
two questions:

1) Is it possible to have the *Python Output* in Emacs report the
progress during execution? Right now, *Python Output* does not update
until after the script completes.

2) If #1 is possible, can I simulate a progress bar using some character
and '\b'? This works in the dos shell, but the Emacs ouput interprets
'\b' to print '^H' rather than a backspace. (Why does it do that?)

Thank you,
Darren
 
D

Dave Benjamin

Hi Darren - not sure about the second question, but I might have an answer
for the first...

1) Is it possible to have the *Python Output* in Emacs report the
progress during execution? Right now, *Python Output* does not update
until after the script completes.

Try using sys.stdout.flush() at regular intervals in your code. I've had
similar problems using Python+Emacs+Cygwin, and flushing the output buffer
usually solved the problem.
 
D

David Bolen

Dave Benjamin said:
Hi Darren - not sure about the second question, but I might have an answer
for the first...



Try using sys.stdout.flush() at regular intervals in your code. I've had
similar problems using Python+Emacs+Cygwin, and flushing the output buffer
usually solved the problem.

Or just start Python with -u (unbuffered) or -i (interactive) from
within the shell. Avoids the need to change the script.

The root cause is probably that Emacs' shell is not considered a TTY,
so it gets buffered output by default.

-- David
 
D

Darren Dale

Or just start Python with -u (unbuffered) or -i (interactive) from
within the shell. Avoids the need to change the script.

I forgot to ask, how would I do this from Emacs?
 
D

David Bolen

Darren Dale said:
I forgot to ask, how would I do this from Emacs?

Well, let's assume that you're at the shell prompt from inside Emacs
(how you got there could depend on your Emacs setup, whether M-x shell
or some keystrokes). Then, instead of doing something like:

(shell prompt) python yourscript.py

do

(shell prompt) python -u yourscript.py

It'll run your script just as before but forceably disabling any
output buffering, which it would otherwise enable automatically when
detecting that its output did not appear to be a interactive (a TTY).
You should see anything produced by your script in the Emacs buffer as
soon as the script generates it.

To answer your other question, short answer is that saying "is a tty"
is more or less a shorthand for saying whether the output is being
displayed to a user on an interactive device.

Longer answer is that historically TTY was a teletypewriter (and still
can mean that in the context of hearing impaired phone devices today),
the idea being that a keyboard and display was used for communication.
Over time, and particular with it's use in Unix systems, it's come to
encompass the general idea of a terminal I/O device. More
specifically it is common (in the Unix world) to use the term TTY to
refer to an actual physical output device as opposed to other devices
like pipes, files, network sockets, etc...

So saying that output "appears to be a TTY" is a shorthand way of
saying that the output device appears to be a true interactive display
device rather than output being redirected to a file or other
connection. There's even a (fairly portable) C library routine called
"isatty" (is a tty) that Python uses to determine this. It's not
uncommon for an application (generally through default behavior of the
platform C library) to adjust buffering based on that status, so as to
be more efficient in the non-TTY case where interactive latency of
display is not as important as utilizing the bandwidth to the output
device most effectively.

Generally speaking, when one process opens a pipe or otherwise
controls another process, it won't appear to be a TTY to the other
process, since that process' output is going through some system
object (for example, a pipe). There are packages that in fact exist
soley to simulate TTYs (or provide PTTYs, Pseudo-TTYs) to better
simulate a user running an application, such as Expect.

Anyway, when Emacs is running the child shell, it executes that shell
as a child process for which it controls the I/O, but the connection
between Emacs and that child process is not perceived as a TTY by the
system, and thus nor by Python, so it permits more efficient buffering
to take place. Unfortunately, that more efficient buffering is not
what you want when you are working with something interatively.

Using the -u command line option tells Python to disable all output
buffering regardless of the TTY status of it's output. This is
actually even less efficient than the default TTY state (which is
typically line buffered) but it ensures you'll see everything on the
output as soon as it is generated. You can also get the same effect
by having the PYTHONUNBUFFERED environment variable set when you start
python.

-- David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top