file.close()

Jeff Epler jepler at unpythonic.net
Sun Jul 27 22:26:22 EDT 2003


On Sun, Jul 27, 2003 at 04:31:19PM -0700, Erik Max Francis wrote:
> You haven't
> demonstrated a case where there actually is an I/O error that occurs
> when .close gets called.

What makes you believe that a Python file object's "close" can never error?
"close" corresponds to the fclose() function of the C standard library,
and the manpages have plenty to say on the subject (see below).

I just created a small filesystem (1000 1k blocks, over half of which
was used by filesystem overhead) and got Python to do this:
>>> f = open("/mnt/tmp/x", "w")
>>> f.write("x" * (453*1024+511))
>>> f.close()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IOError: [Errno 28] No space left on device

Curiously enough, this doesn't even print the 'Exception in __del__ ignored' message:
>>> f = open("/mnt/tmp/x", "w")
>>> f.write("x" * (453*1024+511))
>>> del f
even though the failed stdio fclose must still have been called.

stdio buffering kept the last few bytes of the f.write() from actually
being sent to the disk, but the f.close() call must dump them to the disk,
at which time the "disk full" condition is actually seen.  While I had
to contrive this situation for this message, it's exactly the kind of
thing that will to happen to you when your software is at the customer's
site and you've left for a month in rural Honduras where there aren't
any easily-accessible phones, let alone easy internet access.

Jeff

[from `man fclose']
RETURN VALUE
       Upon  successful  completion 0 is returned.  Otherwise, EOF is returned
       and the global variable errno is set to indicate the error.  In  either
       case  any  further  access  (including another call to fclose()) to the
       stream results in undefined behaviour.
[...]
       The fclose function may also fail and set errno for any of  the  errors
       specified for the routines close(2), write(2) or fflush(3).

[from `man close']
ERRORS
       EBADF  fd isn’t a valid open file descriptor.

       EINTR  The close() call was interrupted by a signal.

       EIO    An I/O error occurred.

[from `man write']
ERRORS
       EBADF  fd is not a valid file descriptor or is not open for writing.

       EINVAL fd is attached to an object which is unsuitable for writing.

       EFAULT buf is outside your accessible address space.

       EFBIG  An attempt was made to write a file that exceeds the implementa-
              tion-defined maximum file size or the process’ file size  limit,
              or  to write at a position past than the maximum allowed offset.

       EPIPE  fd is connected to a pipe or socket whose reading end is closed.
              When  this  happens the writing process will also receive a SIG-
              PIPE signal.  (Thus, the write return value is seen only if  the
              program catches, blocks or ignores this signal.)

       EAGAIN Non-blocking  I/O  has  been  selected  using O_NONBLOCK and the
              write would block.

       EINTR  The call was interrupted by a signal before any data  was  writ-
              ten.

       ENOSPC The device containing the file referred to by fd has no room for
              the data.

       EIO    A low-level I/O error occurred while modifying the inode.

       Other errors may occur, depending on the object connected to fd.

[from `man fflush']
ERRORS
       EBADF  Stream is not an open stream, or is not open for writing.

       The  function  fflush may also fail and set errno for any of the errors
       specified for the routine write(2).







More information about the Python-list mailing list