Check file permissions in python

I am trying to check the readability of a file at a given path. Here's what I have:

def read_permissions(filepath):
    '''Checks the read permissions of the specified file'''
    try:
        os.access(filepath, os.R_OK) # Find the permissions using os.access
    except IOError:
        return False

    return True

      

This works and returns True or False as the result on startup. However, I want the error messages from to errno

accompany it. This is what I think I will have to do (but I know there is something wrong):

def read_permissions(filepath):
    '''Checks the read permissions of the specified file'''
    try:
        os.access(filepath, os.R_OK) # Find the permissions using os.access
    except IOError as e:
        print(os.strerror(e)) # Print the error message from errno as a string

    print("File exists.")

      

However, if I had to enter a file that does not exist, it tells me that the file exists. Can anyone help me on what I did wrong (and what I can do to stay away from this problem in the future)? I haven't seen anyone try to use this with os.access

. I am also open to other options for checking file permissions. Can anyone help me on how to bring up the appropriate error message if something goes wrong?

Also, this probably applies to my other functions (they still use os.access

when checking for other things like file existence using os.F_OK

and file write permission using os.W_OK

). Here's an example of what I am trying to simulate:

>>> read_permissions("located-in-restricted-directory.txt") # Because of a permission error (perhaps due to the directory)
[errno 13] Permission Denied
>>> read_permissions("does-not-exist.txt") # File does not exist
[errno 2] No such file or directory

      

This is what I am trying to simulate by returning an appropriate error message. Hope this helps to avoid confusion in my question.

I should probably point out that although I read the documentation os.access

, I am not trying to open the file later. I am just trying to create a module where some components need to check the permissions of a specific file. I have a baseline (the first piece of code I mentioned) that serves as a base for making decisions for the rest of my code. Here I am just trying to write it again, but in a user-friendly way (not just True

or simply False

, but rather in full posts). Since it IOError

can be called in a couple of different ways (like a resolved permission or a missing directory), I'm trying to get my module to identify and post this issue. Hope this helps you identify possible solutions.

+3


source to share


1 answer


os.access

returns False

when the file does not exist, regardless of the passed mode parameter.

This is not explicitly documented foros.access

, but it is not terribly shocking behavior; after all, if the file doesn't exist, you can't get it. Checking the access page (2) as suggested by the docs gives another clue as it access

returns -1

over a wide range of conditions. Anyway, you can just do the same as me and check the return value in IDLE:

>>> import os
>>> os.access('does_not_exist.txt', os.R_OK)
False

      

In Python, it is generally discouraged to check for types, etc., before trying to do useful things. This philosophy is often expressed in the EAFP initialism, which means "It's easier to ask for forgiveness than permission." If you go back to the docs, you'll see that this is especially true in this case:

Note. ... Using access()

to check if the user is allowed eg. open the file before doing so, using open()

creates protection because the user can use a short amount of time between checking and opening the file to manipulate it. Its preferred to use EAFP . For example:

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

      

better to write like:

try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

      

If you have other reasons for checking permissions than the second user before calling open()

, you can look at How to check if a file exists using Python? for some suggestions. Remember, if you really need the exception to be raised, you can always do raise

it yourself; no need to look for hunting one in the wild.




Since the IOError can be raised in several different ways (for example permission denied or non-existent directory), I am trying to get a module to identify and post the issue.

This is what the second approach above does. Cm:

>>> try:
...     open('file_no_existy.gif')
... except IOError as e:
...     pass
...
>>> e.args
(2, 'No such file or directory')
>>> try:
...     open('unreadable.txt')
... except IOError as e:
...     pass
...
>>> e.args
(13, 'Permission denied')
>>> e.args == (e.errno, e.strerror)
True

      

But you have to choose one approach or the other. If you're sorry, do so (open the file) in a try-except block and handle the consequences accordingly. If you succeed, then you know that you succeeded, because there is no exception.

On the other hand, if you ask permission (aka LBYL, Look Before You Leap) in this and the other, you still don't know if you can successfully open the file until you do. What if a file is moved after checking its rights? What if there is a problem that you didn't think to check?

If you still want to ask permission, don't use try-except; you don't do this to avoid throwing mistakes. Instead, use conditional statements with calls as a condition os.access

.

+7


source







All Articles