12

I know that in Python the file.close() method doesn't have any return value, but I can't find any information on whether in some cases it throws an exception. If it doesn't do that either, then I guess the second part of this question is superfluous.

If it does, then what would be the "correct" way to handle the file.close() method throwing an exception inside a "with" statement used to open the file?

Is there a situation where file.close() could fail immediately after a file has been open and read from successfully?

Daniel
  • 2,345
  • 4
  • 19
  • 36
MattyZ
  • 1,541
  • 4
  • 24
  • 41
  • If you're using Python 2.5 or higher, a `with` block will automatically close the file for you. There's no need to explicitly state `close()` in that case. – Daniel Aug 01 '15 at 21:45
  • 1
    @Daniel, OP uses python 3.x tag. @Bitrex you can print the error if it does happen by wrapping your `with` statement with a `try: except Exception,e: print (e)` – awbemauler Aug 01 '15 at 21:53
  • 2
    with statements can throw exceptions with no way to handle them except by wrapping in try/except. with/except was proposed but shot down. with statements are syntactic sugar for simple use cases where no exception is expected. See http://stackoverflow.com/questions/8774830/how-with-is-better-than-try-catch-to-open-a-file-in-python for extended discussion. –  Aug 01 '15 at 22:02

3 Answers3

9

Yes, file.close() can throw an IOError exception. This can happen when the file system uses quotas, for example. See the C close() function man page:

Not checking the return value of close() is a common but nevertheless serious programming error. It is quite possible that errors on a previous write(2) operation are first reported at the final close(). Not checking the return value when closing the file may lead to silent loss of data. This can especially be observed with NFS and with disk quota.

A non-zero return value of the C close() function leads to Python raising an IOError exception.

If you wanted to handle this exception, put a try...except block around the with statement:

try:
    with open(filename, mode) as fileobj:
        # do something with the open file object
except IOError as exc:
    # handle the exception

Of course, the IOError could also have been thrown during opening.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • `Of course, the IOError could also have been thrown during opening.` In which case you use an [`ExitStack`](https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack) to make sure it was [raised when exiting](https://docs.python.org/3/library/contextlib.html#catching-exceptions-from-enter-methods). – Navith Aug 01 '15 at 23:23
  • 1
    @Navith or open the file object first and *then* use it as a context manager. – Martijn Pieters Aug 01 '15 at 23:53
1

close can throw exceptions, for example, if you run out of disk space while it's trying to flush your last writes, or if you pulled out the USB stick the file was on.

As for the correct way to deal with this, that depends on the details of your application. Maybe you want to show the user an error message. Maybe you want to shut down your program. Maybe you want to retry whatever you were doing, but with a different file. Whatever the response you choose, it'll probably be implemented with a try-except block in whatever layer of your program is best equipped to deal with it.

user2357112
  • 260,549
  • 28
  • 431
  • 505
-1

You can use

file object = open(file_name [, access_mode][, buffering])

Then you check

file.closed

It's return True if file is closed and false otherwise.

Mahmoud Elgindy
  • 114
  • 1
  • 11
  • This doesn't even begin to answer the question *does `file.close()` throw any exceptions?* The OP is **not** asking how to check if a file object is open or closed. – Martijn Pieters Aug 01 '15 at 22:11
  • It's all good; welcome to SO. As you answer questions on the site, just remember to read them carefully before submitting an answer. Alternatively, you can leave a comment on the question, when you earn enough reputation. – Daniel Aug 01 '15 at 22:36