Check if I can write a file to a directory or not with Python
Asked Answered
J

4

17

I need to check if I can write a file to a directory that user point to with Python.

Is there an way to check it in advance? I may be using try .. catch for this purpose, but I expect something better in the sense that I can check in advance.

Jerrome answered 12/9, 2010 at 18:47 Comment(7)
Why do you expect something better? Exceptions are cheap in Python and the standard way of error handling.Emmy
@Jim : Thanks for the comment, and I elaborated the post a little bit.Jerrome
Exceptions are not cheap in Python, but see my answer for more details - in particular, os.access and stat still buy you no real safety, and actually create an opportunity for a race condition. Despite that, they can still improve user experience.Duna
@S.Lott : I modified the sentence that has the word 'danger'.Jerrome
What does "better" mean? Your user privileges define what is allowed and not allowed. You can try to write a fancy if-statement to see if the effective user can perform the operation -- effectively duplicating what the OS is doing. Or you can just try it and handle the exception, allocating responsibility to the OS to do the checking. Are you trying to duplicate the OS privilege checking? Why bother? What's wrong with catching the error?Shively
@Shively : I said 'better' in the sense that exception is expensive. And, I have no problem in catching the error, as I do it frequently. I was just curious if there's a way to avoid the exception. I can understand what you want to say, and please don't be angry with my attempt to avoid exception :)Jerrome
"exception is expensive" is false. Exceptions are very, very fast. Why avoid them? Why take responsibility away from the OS? Why duplicate the logic already present in the OS to validate your request? "Anger" is your problem, not mine. I'm just asking questions -- why label that "anger"? Why duplicate the OS features that reject improper requests?Shively
D
22

Despite Jim Brissom's claim, exception handling is not cheap in Python compared to 'check then try' idioms if you expect the thing to fail more than a few percent of the time. (Read to the end for an exception!) However, the key thing here is that you need to check the exception anyway, because the permissions can change between the check and your write:

### !!! This is an example of what not to do!
### !!! Don't do this!
if os.access("test", os.W_OK):
    # And in here, some jerk does chmod 000 test
    open("test", "w").write(my_data)
    # Exception happens despite os.access!

os.access and the stat module are great if you're trying to, e.g., prepare a list of folders for the user to pick and want to exclude invalid ones a priori. However, when the rubber hits the road, it is not a replacement for exception handling if you want your program to be robust.

And now the exception to the exceptions-are-slow rule: Exceptions are slow, but disks are slower. And if your disk is under particularly heavy load, you might end up having the file you're interested in evicted from the OS or disk cache between the os.access and open call. In this case, you're going to experience a major slowdown as you have to go to disk (and these days, that can also mean network) twice.

Duna answered 12/9, 2010 at 19:3 Comment(0)
G
3

You will probably not find something better or more Pythonic. Python's philosophy is it is easier to ask forgiveness than permission.

You can use os.access if you like. Coupled with os.path.isfile to check if you have a file and not e.g. a directory. It will probably give you what you need. The exception path is much better.

Gerigerianna answered 12/9, 2010 at 18:50 Comment(4)
-1 for reiterating Python philosophy with no discussion of why exception handling is the better solution here.Duna
@Joe: I linked to the Python philosophy. Also, it is a philosophy because it works here and elsewhere in Python. It is useful for duck typing for example.Gerigerianna
The Python glossary doesn't explain why it's useful though; in fact it describes it as "clean and fast", and I disagree strongly with both of those.Duna
@Joe: I agree that it is not fast. It is clean in my opinion. More importantly, EAFP is coming at the problem from a different angle to you. Your answer is "because of the race condition" which is correct but is invariant to the programming language. My answer is "use EAFP" because it is useful for all sorts of things in Python, not just because of the race condition. The OP might find both answers useful in different ways.Gerigerianna
S
2

The pythonic way is to access it and catch the exception if it fails.

If you really have to check it, use os.access, but the results are not always true, beware of issues in Vista/Win7 with UAC, for example!

Example:

os.access(r'C:\Programme', os.R_OK)

This will tell you if you have read access.

Stratiform answered 12/9, 2010 at 18:48 Comment(0)
S
1

just use this:

def check_access(file, mode):
   try:
      open(file, mode)
      return True
   except PermissionError:
      return False
print(check_access("test", "w"))

output if no Permission:

False

output if Permission:

True

if you use os.access() then you have a chance of getting something like

   Traceback (most recent call last):
 File "/Users/lawrence/Library/Application Support/CodeRunner/Unsaved/Untitled.py", line 8, in <module>
   open("test", "w").write("test")
 PermissionError: [Errno 13] Permission denied: 'test'

you can still use os.access() but I don't recommend it

Sturm answered 29/4, 2022 at 6:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.