python: why does os.makedirs cause WindowsError? - python

In python, I have made a function to make a directory if does not already exist.
def make_directory_if_not_exists(path):
try:
os.makedirs(path)
break
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
On Windows, sometimes I will get the following exception:
WindowsError: [Error 5] Access is denied: 'C:\\...\\my_path'
It seems to happen when the directory is open in the Windows File Browser, but I can't reliably reproduce it. So instead I just made the following workaround.
def make_directory_if_not_exists(path):
while not os.path.isdir(path):
try:
os.makedirs(path)
break
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
except WindowsError:
print "got WindowsError"
pass
What's going on here, i.e. when does Windows mkdir give such an access error? Is there a better solution?

You should use OSError as well as IOError. See this answer, you'll use something like:
def make_directory_if_not_exists(path):
try:
os.makedirs(path)
except (IOError, OSError) as exception:
if exception.errno != errno.EEXIST:
...

A little googling reveals that this error is raised in various different contexts, but most of them have to do with permissions errors. The script may need to be run as administrator, or there may be another program open using one of the directories that you are trying to use.

on your question on a better solution i would use simple and clear three lines code here:
def make_directory_if_not_exists(path):
if not os.path.isdir(path):
os.makedirs(path)

Related

Correcting except: pass warnings in python - what exceptions may open and os.remove raise?

In the following piece of code, some_path is a string that corresponds to a path (may be a relative path)
def editable(some_path):
"""Safely check whether a file is editable."""
delete = not os.path.exists(some_path)
try:
with open(some_path, 'ab'):
return True
except:
return False
finally:
# If the file didn't exist before, remove the created version
if delete:
try:
os.remove(some_path)
except:
pass
In open's docs we read:
If the file cannot be opened, IOError is raised
Is IOError the only possible error I can get (UnicodeError comes to mind, or OSError etc) ?
os.remove docs are even more vague:
If path is a directory, OSError is raised
So what if the file is in use, or protected or...
UPDATE: How about shutil.move ? This seems to raise yet another shutil.Error(StandardError) - if I read the source right

How to handle FileNotFoundError when "try .. except IOError" does not catch it?

How can I catch an error on python 3? I've googled a lot but none of the answers seem to be working. The file open.txt doesn't exist so it should print e.errno.
This is what I tried now:
This is in my defined function
try:
with open(file, 'r') as file:
file = file.read()
return file.encode('UTF-8')
except OSError as e:
print(e.errno)
However I does not print anything when I get this error
FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'
FileNotFoundError is a subclass of OSError, catch that or the exception itself:
except OSError as e:
Operating System exceptions have been reworked in Python 3.3; IOError has been merged into OSError. See the PEP 3151: Reworking the OS and IO exception hierarchy section in the What's New documentation.
For more details the OS Exceptions section for more information, scroll down for a class hierarchy.
That said, your code should still just work as IOError is now an alias for OSError:
>>> IOError
<class 'OSError'>
Make sure you are placing your exception handler in the correct location. Take a close look at the traceback for the exception to make sure you didn't miss where it is actually being raised. Last but not least, you did restart your Python script, right?
Change your OSError to (IOError, OSError) that should work.
#Thomas Wagenaar

Python's "open()" throws different errors for "file not found" - how to handle both exceptions?

I have a script where a user is prompted to type a filename (of a file that is to be opened), and if the file doesn't exist in the current directory, the user is prompted again. Here is the short version:
file = input("Type filename: ")
...
try:
fileContent = open(filename, "r")
...
except FileNotFoundError:
...
When I tested my script on my MacOS X in Python 3.3x it worked perfectly fine when I type the wrong filename on purpose (it executes the suite under "expect").
However, when I wanted to run my code
on a Windows computer in Python 3.2x, I get an error that says that "FileNotFoundError" is not defined. So, Python 3.2 on Windows thinks "FileNotFoundError" is a variable and the programs quits with an error.
I figured out that Python 3.2 on Windows throws an "IOError" if the input filename is not valid. I tested it on my Linux machine in Python 2.7, and it's also an IOError.
My problem is now, that the code with
except "FileNotFoundError":
won't run on Windows's Python 3.2, but if I change it to
except "IOError":
it won't work on my Mac anymore.
How could I work around it? The only way I can think of is to use just
except, which I usually don't want.
In 3.3, IOError became an alias for OSError, and FileNotFoundError is a subclass of OSError. So you might try
except (OSError, IOError) as e:
...
This will cast a pretty wide net, and you can't assume that the exception is "file not found" without inspecting e.errno, but it may cover your use case.
PEP 3151 discusses the rationale for the change in detail.
This strikes me as better than a simple except:, but I'm not sure if it is the best solution:
error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError)
try:
f = open('.....')
except error_to_catch:
print('!')
So to exactly catch only when a file is not found, I do:
import errno
try:
open(filename, 'r')
except (OSError, IOError) as e: # FileNotFoundError does not exist on Python < 3.3
if getattr(e, 'errno', 0) == errno.ENOENT:
... # file not found
raise
you can catch 2 errors at the same time
except (FileNotFoundError, IOError):
I didn't realize that is what you were asking. I hope there is a more eloquent solution then to manually inspect
try:
error_to_catch = FileNotFoundError
except NameError:
error_to_catch = IOError
except error_to_catch
cwallenpoole does this conditional more eloquently in his answer
(error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError))

obtaining error number of an error

I need to obtain the error number from an error that has occurred in Python.
Ex; When trying to transfer a directory via the Paramiko package, an error is caught with this piece of code:
try:
sftp.put(local_path,target_path)
except (IOError,OSError),errno:
print "Error:",errno
For which I get the output,
Error: [Errno 21] Is a directory
I want to utilize the error number to go into some more code to transfer the directory and the directory contents.
Thanks for clarifying your question.
Most Exceptions in Python don't have "error numbers". One exception (no pun intended) are HTTPError exceptions, for example:
import urllib2
try:
page = urllib2.urlopen("some url")
except urllib2.HTTPError, err:
if err.code == 404:
print "Page not found!"
else:
...
Another exception (as noted by bobince) are EnvironmentErrors:
import os
try:
f=open("hello")
except IOError, err:
print err
print err.errno
print err.strerror
print err.filename
outputs
[Errno 2] No such file or directory: 'hello'
2
No such file or directory
hello
If you're talking about errno.h error numbers, you can get them from the errno property on the exception object, but only on EnvironmentError (which includes OSError, IOError and WindowsError).
Specifically on WindowsError you'll also get a winerror property with a Windows-specific error number. (You don't often see one of these though, as Python uses the Win32 API directly relatively rarely.)
There is also the errno package, which allows working with error codes with out having to handle magic numbers in the code. See an example here: Are Python error numbers associated with IOError stable?

How can I make an error verifiy with os.makedirs in Python?

How can I make a verify error for this command?
if blablablabla:
os.makedirs('C:\\test\\')
If the folder already exists, he return me an error... how can I make it ignore this error? and move on ?
try:
os.makedirs('C:\\test\\')
except OSError:
pass
You also might want to check the specific "already exists" error (since OSError could mean other things, like permission denied...
import errno
try:
os.makedirs('C:\\test\\')
except OSError as e:
if e.errno != errno.EEXIST:
raise # raises the error again
In Python3.2 and above, just add exist_ok=True will solve this problem.
If exist_ok is False (the default), an FileExistsError is raised if the target directory already exists.
os.makedirs('C:\\test\\',exist_ok=True)
you can try/except?
try:
os.makedirs('C:\\test\\')
except: pass

Categories

Resources