open() and EOFError

Roy Smith roy at
Mon Jul 7 14:39:04 CEST 2014

In article <53ba538d$0$2926$c3e8da3$76491128 at>,
 Steven D'Aprano <steve at> wrote:

> On Mon, 07 Jul 2014 17:04:12 +1200, Gregory Ewing wrote:
> > Steven D'Aprano wrote:
> >> Are there any circumstances where merely *opening* a file (before
> >> reading it) can raise EOFError?
> > 
> > I don't think so. As far as I know, the only built-in thing that raises
> > EOFError is input() (and raw_input() in Py2).
> Thanks. That's what I thought.
> How do people feel about code like this?
> try:
>     name = input("Enter file name, or Ctrl-D to exit")
>     # On Windows, use Ctrl-Z [enter] instead.
>     fp = open(name)
> except EOFError:
>     sys.exit()
> except IOError:
>     handle_bad_file(name)
> else:
>     handle_good_file(fp)

I really dislike putting more than one statement inside a try block.  
Breaking this up into two try statements, one catching the EOF, the 
other catching the IOError, is better.  More verbose, to be sure, but 
the flow of control is a lot more obvious.

On a different topic, I've always disliked embedding instructions to 
"type Ctrl-D".  The problem is, how to generate an EOF (or interrupt, or 
whatever) is configurable in the tty driver (see below).  In theory, the 
user could have remapped EOF to be something else.  Maybe they're a 
die-hard Windows fan, and insist on being able to type Ctrl-Z for EOF.  
Not to mention that things like readline are probably running the 
terminal in raw mode and remapping everything all over again.

On the other hand, telling the user to "generate EOF", while technically 
more correct, is not very useful for most people.  I suppose you could 
interrogate the tty driver to find out what the current EOF character 
is, and stick that in your prompt.  I don't even know if that's possible 
with the standard Python library, and I doubt it would be very portable.    
I'm not sure what the best solution is here.

$ stty -e
speed 9600 baud; 24 rows; 80 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
   -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
   -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
   -dtrflow -mdmbuf
discard dsusp   eof     eol     eol2    erase   intr    kill    lnext   
^O      ^Y      ^D      <undef> <undef> ^?      ^C      ^U      ^V      
min     quit    reprint start   status  stop    susp    time    werase  
1       ^\      ^R      ^Q      ^T      ^S      ^Z      0       ^W      

More information about the Python-list mailing list