pitfall
pitfall

Reputation: 2621

Why a file is writtable but os.access( file, os.W_OK ) return false?

I am not quite sure what's going here. Based on the explanation on python

> os.W_OK: Value to include in the mode parameter of access() to test the writability of path.

I suppose this check should return True, even if a file does not exist, but its path is valid and I have the permission to write this file.

But this is what happens when I try to check whether a file path is writeable.

import os, subprocess
pwd = os.getcwd();
temp_file_to_write = os.path.join( pwd, "temp_file" );
# use os.access to check 
say = "";
if ( os.access( temp_file_to_write, os.W_OK ) ) :
    say = "writeable";
else :
    say = "NOT writeable";

print "L10", temp_file_to_write, "is", say
# use try/except
try :
    with open( temp_file_to_write, "w" ) as F :
        F.write( "L14 I am a temp file which is said " + say + "\n" );
    print "L15", temp_file_to_write, "is written";
    print subprocess.check_output( ['cat', temp_file_to_write ] );
except Exception, e:
    print "L18", temp_file_to_write, "is NOT writeable";

It produces the following results

L10 /home/rex/python_code/sandbox/temp_file is NOT writeable
L15 /home/rex/python_code/sandbox/temp_file is written
L14 I am a temp file which is said NOT writeable

Does anyone know why? If my understanding of os.W_OK is wrong, could you tell me the right way in python to check the following both things together 1) whether a file path is valid; and 2) whether I have permissions to write.

Upvotes: 4

Views: 3294

Answers (3)

Nathan Garabedian
Nathan Garabedian

Reputation: 737

The original question asked how to check permissions to write a file. However, in Python it is better to use a try-except block to attempt to write to a file, instead of testing for access, when possible. The reason is given in the os.access() documentation on the Python.org website: https://docs.python.org/3/library/os.html

From the website:

Note: Using access() to check if a user is authorized to e.g. open a file before actually doing so using open() creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it. It’s preferable to use EAFP techniques. For example:

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()
return "some default data"

is better written as:

try:
    fp = open("myfile")
except PermissionError:
    return "some default data"
else:
    with fp:
        return fp.read()

Note: I/O operations may fail even when access() indicates that they would succeed, particularly for operations on network filesystems which may have permissions semantics beyond the usual POSIX permission-bit model.

Upvotes: 0

jfs
jfs

Reputation: 414645

Whether or not you can create a new file depends what permissions the directory has, not the new non-existent (yet) file.

Once the file is created (exists) then access(W_OK) may return true if you can modify its content.

Upvotes: 2

Sergius
Sergius

Reputation: 986

Maybe you run your script with sudo (or something like this on Windows)? I have this on linux (I gave chmod 400):

>>> os.access(fn, os.W_OK)
False
>>> f = open(fn, 'w')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 13] Permission denied: '/tmp/non-writable'

Upvotes: 0

Related Questions