views:

452

answers:

1

My python program has two calls to raw_input()

The first raw_input() is to take multiline input from the user. The user can issue Ctrl+D (Ctrl+Z in windows) for the end of input.

Second raw_input() should take another input from user with (y/n) type prompt.

Unfortunately (in Mac OS X only?), second raw_input() raises EOFError when the stdin is terminated (with Ctrl+D) at first raw_input() prompt.

Please see my example code below for more explanation -

mailBody = ''
signature = 'Later!'
print 'Compose your mail:'
while True:
    try:
        # Hit ^D after entering some text
        mailBody+= raw_input()
        mailBody+='\n'
    except EOFError:
        break

# This raw_input() throws EOFError too. Because, stdin is terminated for the session
# when EOF (^D) is issues at first raw_input() method (Where as, it doesn't raise EOFError in Linux)
opt = raw_input("Do you want to add signature to your mail? (y/N): ").lower()
print '-'*10+'Your Mail'
if opt == 'y':
    print mailBody+"\n"+signature
else:
    print mailBody
print '-'*19

The program output:

-1- abhinay@MacBook code/py % python prompt.py                                                        
Compose your mail:
hello there!
how is everybody?
Do you want to add signature to your mail? (y/N): Traceback (most recent call last):
  File "prompt.py", line 11, in <module>
    opt = raw_input("Do you want to add signature to your mail? (y/N): ").lower()
EOFError

How can I make second prompt not to raise EOFError. Please help!

EDIT:

I've edited my question to keep it simple.

I ran my above code in Linux System, it works without any issue. That is, the user was prompted at second raw_input() to receive '(y/N)' choice.

+2  A: 

It's quite normal that when standard input is terminated (by hitting control-D, in Unix-derived systems -- I think it's control-Z in Windows), it stays terminated thereafter (unless you close and re-open it in the meantime, of course).

Alex Martelli
@Alex Thanks for your response! Does it mean, the terminal keeps sending EOF to the prompt once we enter ^D (EOF)? Is there a way to handle this in Python with exception? as you can see I need to receive one more input from user (i.e., y/n) after issuing 'Compose your mail:' prompt.
abhiomkar
I think you misunderstood this answer. When you hit control-D, you are closing standard input. This means that you can no longer input anything to your program for the rest of its lifetime without some workaround.
Clueless
@Clueless Thanks! It makes sense now. But, still is there a workaround for my above scenario? or am I missing something?
abhiomkar
@abhiomkar, one "workaround" is to reopen standard-input (`sys.stdin`) after the `while` (I think the name of the "file" corresponding to the current terminal is `'CON:'` on a Windows command shell, `'/dev/tty'` on Unix-y machines such as the Mac). Simpler would be to have the user use some _other_ means than closing standard input to tell you he's done (a Unix-y classic is a line containing only a full-stop character `'.'` then immediately a newline/end-of-line), so that standard input stays available!
Alex Martelli
@Alex I've just ran the my above code in Linux System, it works without any issue. That is, the user was prompted at second raw_input() to receive '(y/N)' choice. Will try to implement your suggestion for Mac OS X Terminal. Thanks.
abhiomkar