operation not permitted error on Linux Python - python

I am using shutil copy to copy the text file from one location to other. But it is throwing exception:
Operation not permitted.
But surprisingly I can see that the file is copied to destination folder. Then why it is throwing exception? I am using below code.
import shutil
old_name='/test/test1.txt'
new_name='/test1/test1.txt'
try:
shutil.copy(old_name, new_name)
except IOError as e:
print(e)

Have you tried using sudo?
If you use /sudo rest_of_command it should stop giving you the error.
Using sudo can be dangerous so only use it if you feel confident and know what you are doing.

Related

How would you catch python Exception inside an except clause

How would you catch exception within exception in python ?
Consider the following case
bak_filename = filename + ".bak"
#This try is needed because if bak_filename existed, rename will fail
try:
os.rename(filename, bak_filename)
except WindowsError:
#However, os.remove may still fail e.g. file in use. How would you handle this exception within except clause ?
#try and except around this os.remove?
os.remove(bak_filename)
os.rename(filename, bak_filename)
Any thought of :
Rewriting to avoid double try?
Not necessarily this example, but in some case we cannot rewrite, how would you handle double try ?
A solution to avoid all this exception wrapping would be to use shutil.move
shutil.move(filename, bak_filename)
If the destination already exists but is not a directory, it may be overwritten depending on os.rename() semantics.
If the destination is on the current filesystem, then os.rename() is used. Otherwise, src is copied to dst using copy_function and then removed. In case of symlinks, a new symlink pointing to the target of src will be created in or as dst and src will be removed.
So it basically does what you're trying to do, but in a library which is available on all python distros.
Note that the performance may be bad if the file is big and the target file exists and os.rename refuses to overwrite it (completely depends on the operating system but for instance Windows will refuse to rename over an existing file), because the fallback when os.rename throws OSError is copying the source then deleting. The implementation doesn't try to remove the file then rename again, because if rename fails, Python assumes that we're trying to rename across filesystems, and a copy+delete is in order in that case (this is exactly how Unix mv works).
try:
os.rename(src, real_dst)
except OSError:
if os.path.islink(src):
...
else:
copy_function(src, real_dst)
os.unlink(src)
To workaround that possible file existence, a prior os.remove call wrapped in a try/except OSError statement could be done.
try:
os.remove(bak_filename)
except OSError:
pass
shutil.move(filename, bak_filename) # or os.rename(filename, bak_filename)
Of course if bak_filename is locked/not deletable, an exception can still be raised by shutil.mode. Also note that if we tried to delete the target file, os.rename will be as good as shutil.move. If the target file could not be deleted, the operation can't succeed anyway.
You can read more on Exception Chaining. But, that's for Python 3
In Python 2, you can store your exception in a variable, then raise it again explicitly like this:
try:
do something
except Exception as e:
try:
do something again
except:
pass
raise e

How to catch Permission Error with Popen process

This is the error:
Permission Error: Copying of text from this document is not allowed.
I am opening a .exe file on windows. So regular try except block does not seem to catch it. Neither does OSError.
I solved it with the following:
try:
"""code here"""
except subprocess.CalledProcessError:
"""unlock files and try again"""
Try
exception PermissionError
Raised when trying to run an operation without the adequate access rights - for example filesystem permissions. Corresponds to errno EACCES and EPERM.
If you specified irrelevant Exception while trying to catch permission error, I wouldn't be surprised they it is caught

List of exceptions for Python3 I/O operations for proper error handling

I'm trying to write to a file like this:
with open(filename), 'wb') as f:
f.write(data)
But when opening a file and writing to it many things might go wrong and I want to properly report what went wrong to the user. So I don't want to do:
try:
with open(filename), 'wb') as f:
f.write(data)
except:
print("something went wrong")
But instead I want to tell the user more specifics so that they can fix the problem on their end. So I started with catching the PermissionError to tell the user to fix their permissions. But soon I got a bugreport that the program would fail if filename pointed to a directory, so I also caught and reported the IsADirectoryError. But this is not all - it might be that the path to filename doesn't exist, so later I also added the FileNotFoundError.
Opening a file and writing to it is a very simple pattern but still many things can go wrong. I'm wondering whether there is an easy recipe that allows me to catch these errors and report them properly without giving a generic "some error happened" message. This kind of pattern has been used for decades, so there must be some list of things to check for, no?
I now caught a number of exceptions but I can imagine that even more are lurking around. Things probably become even worse when running this on non-Linux platforms...
What are the best practices for opening a file and writing to it in Python that give a maximum of information back to the user when things go wrong without ressorting to dumping the bare traceback?
On the operating system level there are only so many things that can go wrong when doing an open() and write() system call so there must exist a complete list?
You could catch the higher level exception OSError and then present the value of the strerror field to the user as the explanation. This relies on the fact that exceptions such as FileNotFoundError are subclasses of OSError and these subclasses can all be caught by using the base class.
Here's an example:
try:
filename = 'missing_file'
with open(filename) as f:
for line in f:
# whatever....
pass
except OSError as exc:
print('{!r}: {}'.format(filename, exc.strerror))
Running this code when missing_file does not exist produces this error message:
'missing_file': No such file or directory

Can anyone explain this weird behaviour of shutil.rmtree and shutil.copytree?

I'm building a relatively simple application that asks for directories, checks if they're correct, and then removes one of them and recreates it with contents of the other one. I'm encountering this weird behaviour, I'll try to explain:
When I've got the destination folder window open, AND it's empty, there's an access denied exception, then I get kicked out of the folder and it gets removed. But then if it's not empty, it works just fine, no exceptions, the destination directory (from what it seems) gets emptied then filled with files from the source directory. Which is strange because it's supposed to straight out remove the destination folder no matter what, and then recreate it with the same name and contents from the source destination.
This doesn't make sense to me, shouldn't there be the exact same exception when I'm browsing the directory when it's not empty as when it's empty? What's the difference, it's still supposed to just delete the folder. Is there any logical explanation to that? Also, if there's an exception, why does the directory get removed anyway?
Code for this particular part is pretty straightforward (please keep in mind I'm a beginner :) )
def Delete(self, dest):
try:
shutil.rmtree(dest)
self.Paste(self.src, dest)
except (IOError, os.error) as e:
print e
def Paste(self, src, dest):
try:
shutil.copytree(src, dest)
except (IOError, os.error) as e:
print e
This is expected behaviour on Windows.
Internally shutil.rmtree calls the windows API function DeleteFile which is documented on MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363915%28v=vs.85%29.aspx).
This function has the following property (highlight by me):
The DeleteFile function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed. Subsequent calls to CreateFile to open the file fail with ERROR_ACCESS_DENIED.
If any other process still has a handle open (e.g. virus scanners, windows explorer because you watch the directory or anything else that might still have a handle to that directory), it will not go away.
Usually you just catch the exception in your Paste operation and retry it a few times/for some dozend milliseconds, to handle all those weird virus scanner anomalies.
Little bonus: You can use windbg or ProcessExplorer to find out who still keeps an open handle to your file (just use Find Handle in Process explorer and search for the filename).

shutil.copy failure when the destination already exists and is read-only

I am using shutil.copy to copy files from one location to another. If a file with the same name already exists in the destination location, it is normally ok and overwrites. However, if the destination is read-only, it throws a permission denied error.
What is the most elegant way to deal with this? Is there another shutil function that will deal with the permissions issue, or must I check the permissions on ever file I copy?
smth like
import os
import shutil
def my_super_copy(what, where):
try:
shutil.copy(what, where)
except IOError:
os.chmod(where, 777) #?? still can raise exception
shutil.copy(what, where)
You don't have to check for permissions. Let the OS tell you there's a permission problem and then deal with it. I'm assuming that the PermissionDeniedError is the exception you're getting so your solution would look something like this.
try:
shutil.copy(blah,blah,blah)
except PermissionDeniedError:
<Code for whatever you want to do if there arent sufficient permissions>

Categories