0

This little helper function writes results to an excel file. If the file already exists and the overwrite flag is set, the file should be overwritten if possible - that is when the file is not opened by any other application (Excel in this case):

def writeXls(results, fname, overwrite=False):
  if os.path.isfile(fname) and not overwrite:
    print("Error: can't write to {} because it already exists and overwrite flag is false".format(fname))
    return

  # doesn't work as intended but write access should be checked first. Fix this.
  if not os.access(fname, os.W_OK):
    print("Error: can't write to {} because write access is not allowed. It might be already opened by other software.".format(fname))

The problem is that the test for W_OK passes, even if the file is opened in Excel:

f = open(file_name_or_filelike_obj, 'w+b')
IOError: [Errno 13] Permission denied: <fname here>
  • Why is that so
  • and how should I test for write access to the file instead?
Christoph
  • 1,040
  • 3
  • 14
  • 29
  • 1
    "Check if file is writable, then write the file" is a [TOCTOU bug](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use). Just write the file. You have to handle errors anyway. Doing X to see if Y is going to work later is wrong - X isn't Y so it doesn't replicate everything that Y does, and things can change between the check and the actual attempt. Even if the file is writable in all ways, you may not have space to actually write the data. – Andrew Henle Mar 26 '18 at 09:46
  • Given that I can influence what happens between "test if writable" and "write", I'd still like to know why the test fails in the first place - even if it's pointless to just write later without catching write errors then. – Christoph Mar 26 '18 at 12:13
  • 2
    *I'd still like to know why the test fails in the first place* There are many reasons it can fail, because `os.access` isn't `os.open`. See https://docs.python.org/3.3/library/os.html The Python documentation itself says not to do what you're trying to do, and adds "I/O operations may fail even when `access()` indicates that they would succeed.". If someone asks you "Will this car start?", the answer isn't, "Yes, there's gas in the tank." That's only part of the answer. How do you check if a car can start? You start it. Nothing elase suffices. – Andrew Henle Mar 26 '18 at 12:32
  • Both of your comments were helpful, thanks! Then the bottom line seems to be that my question is not constructive. – Christoph Mar 26 '18 at 12:34

0 Answers0