import ConfigParser
config = ConfigParser.ConfigParser()
config.read('test.ini')
This is how we read a configuration file in Python. But what if the 'test.ini' file doesn't exist? Why doesn't this method throw an exception?
How can I make it throw exception if the file doesn't exist?
You could also explicitly open it as a file.
try:
with open('test.ini') as f:
config.read_file(f)
except IOError:
raise MyError()
EDIT: Updated for python 3.
From the docs:
If none of the named files exist, the ConfigParser instance will
contain an empty dataset.
If you want to raise an error in case any of the files is not found then you can try:
files = ['test1.ini', 'test2.ini']
dataset = config.read(files)
if len(dataset) != len(files):
raise ValueError("Failed to open/find all config files")
Related
I am trying some operation in the loop
from obspy import read
for file in glob.glob('*.*'):
st=read(file)
But some particular files in the directory can't be read,and it gives some error.
I want to make a log file which lists the filenames(with path) of files which gives me the error using the logging module.
I was trying something like open a text file and writing the filename on that ( somehow sometimes I ended up with an empty file even though there was error),
f=open('log_response.txt','w')
for file in glob.glob('*.*'):
try:
# block raising an exception
st=read(file)
except:
#If there is any error write the filename to the file or pass
f.write('{}\n'.format(os.path.abspath(file)))
pass
else:
print(st)
f.close()
But I would like to use the logging module
How can I do that?
Try this:
import logging
logging.basicConfig(handlers=[logging.FileHandler(filename="log_response.txt",
encoding='utf-8', mode='a+')],
format="%(asctime)s %(name)s:%(levelname)s:%(message)s",
datefmt="%F %A %T",
level=logging.INFO)
for file in glob.glob('*.*'):
try:
st = read(file)
except:
logging.error('{}'.format(os.path.abspath(file)))
pass
I have project structure is like
Root
|--config
|---settings.cfg
|--utilities
|---ConfigReader.py
ConfigReader.py
import ConfigParser
config = ConfigParser.ConfigParser()
try:
with open('./config/settings.cfg') as f:
config.readfp(f)
except IOError as e:
raise Exception('Error reading settings.cfg file. '+format(str(e)))
When run above ConfigReader.py, I get always;
raise Exception('Error reading settings.cfg file. '+format(str(e)))
Exception: Error reading settings.cfg file. [Errno 2] No such file or directory: './config/settings.cfg'
I changed providing filepath with back slash/front slash and dots.None working to me.
What Im doing wrong here?
read like this, also make sure that the file is in path.
config = configparser.ConfigParser()
config.read('./config/settings.cfg')
I am writing a program which stores some JSON-encoded data in a file, but sometimes the resulting file is blank (because there wasn't found any new data). When the program finds data and stores it, I do this:
with open('data.tmp') as f:
data = json.load(f)
os.remove('data.tmp')
Of course, if the file is blank this will raise an exception, which I can catch but does not let me to remove the file. I have tried:
try:
with open('data.tmp') as f:
data = json.load(f)
except:
os.remove('data.tmp')
And I get this error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "MyScript.py", line 50, in run
os.remove('data.tmp')
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process
How could I delete the file when the exception occurs?
How about separating out file reading and json loading? json.loads behaves exactly same as json.load but uses a string.
with open('data.tmp') as f:
dataread = f.read()
os.remove('data.tmp')
#handle exceptions as needed here...
data = json.loads(dataread)
I am late to the party. But the json dump and load modules seem to keep using files even after writing or reading data from them. What you can do is use dumps or loads modules to get the string representation and then use normal file.write() or file.read() on the result.
For example:
with open('file_path.json'), 'w') as file:
file.write(json.dumps(json_data))
os.remove('file_path.json')
Not the best alternative but it saves me a lot especially when using temp dir.
you need to edit the remove part, so it handles the non-existing case gracefully.
import os
try:
fn = 'data.tmp'
with open(fn) as f:
data = json.load(f)
except:
try:
if os.stat(fn).st_size > 0:
os.remove(fn) if os.path.exists(fn) else None
except OSError as e: # this would be "except OSError, e:" before Python 2.6
if e.errno != errno.ENOENT:
raise
see also Most pythonic way to delete a file which may not exist
you could extract the silent removal in a separate function.
also, from the same other SO question:
# python3.4 and above
import contextlib, os
try:
fn = 'data.tmp'
with open(fn) as f:
data = json.load(f)
except:
with contextlib.suppress(FileNotFoundError):
if os.stat(fn).st_size > 0:
os.remove(fn)
I personally like the latter approach better - it's explicit.
I have an assignment to write a Python script which "detects whether the file is readable or not".
I am stuck as to which exceptions I should run. Let's say the input file is intended to be a text file, with extension *.txt
What is the exception I should raise? I suspect there should be multiple. At the moment, I have:
with open('example_file.txt") as textfile:
if not textfile.lower().endswith('.txt'):
raise argparse.ArgumentTypeError(
'Not a text file! Argument filename must be of type *.txt')
return textfile
However, that only checks the file extension. What else could I possibly check? What is the standard for file I/O in Python?
To check whether the file exists:
import os.path
if os.path.exists('example_file.txt'):
print('it exists!')
Beyond this, successfully opening the file will demonstrate readability. The built-in open raises an IOError exception if it fails. Failure can occur for more than one reason, so we must check whether it failed due to readability:
import errno
try:
textfile = open('example_file.txt', 'r')
textfile.close()
print("file is readable")
except IOError as e:
if e.errno == errno.EACCES:
print("file exists, but isn't readable")
elif e.errno == errno.ENOENT:
print("files isn't readable because it isn't there")
The relevant section of the docs on file permissions. Note that the use of os.access to check readability before calling open is discouraged.
How can you create a temporary FIFO (named pipe) in Python? This should work:
import tempfile
temp_file_name = mktemp()
os.mkfifo(temp_file_name)
open(temp_file_name, os.O_WRONLY)
# ... some process, somewhere, will read it ...
However, I'm hesitant because of the big warning in Python Docs 11.6 and potential removal because it's deprecated.
EDIT: It's noteworthy that I've tried tempfile.NamedTemporaryFile (and by extension tempfile.mkstemp), but os.mkfifo throws:
OSError -17: File already exists
when you run it on the files that mkstemp/NamedTemporaryFile have created.
os.mkfifo() will fail with exception OSError: [Errno 17] File exists if the file already exists, so there is no security issue here. The security issue with using tempfile.mktemp() is the race condition where it is possible for an attacker to create a file with the same name before you open it yourself, but since os.mkfifo() fails if the file already exists this is not a problem.
However, since mktemp() is deprecated you shouldn't use it. You can use tempfile.mkdtemp() instead:
import os, tempfile
tmpdir = tempfile.mkdtemp()
filename = os.path.join(tmpdir, 'myfifo')
print filename
try:
os.mkfifo(filename)
except OSError, e:
print "Failed to create FIFO: %s" % e
else:
fifo = open(filename, 'w')
# write stuff to fifo
print >> fifo, "hello"
fifo.close()
os.remove(filename)
os.rmdir(tmpdir)
EDIT: I should make it clear that, just because the mktemp() vulnerability is averted by this, there are still the other usual security issues that need to be considered; e.g. an attacker could create the fifo (if they had suitable permissions) before your program did which could cause your program to crash if errors/exceptions are not properly handled.
You may find it handy to use the following context manager, which creates and removes the temporary file for you:
import os
import tempfile
from contextlib import contextmanager
#contextmanager
def temp_fifo():
"""Context Manager for creating named pipes with temporary names."""
tmpdir = tempfile.mkdtemp()
filename = os.path.join(tmpdir, 'fifo') # Temporary filename
os.mkfifo(filename) # Create FIFO
try:
yield filename
finally:
os.unlink(filename) # Remove file
os.rmdir(tmpdir) # Remove directory
You can use it, for example, like this:
with temp_fifo() as fifo_file:
# Pass the fifo_file filename e.g. to some other process to read from.
# Write something to the pipe
with open(fifo_file, 'w') as f:
f.write("Hello\n")
How about using
d = mkdtemp()
t = os.path.join(d, 'fifo')
If it's for use within your program, and not with any externals, have a look at the Queue module. As an added benefit, python queues are thread-safe.
Effectively, all that mkstemp does is run mktemp in a loop and keeps attempting to exclusively create until it succeeds (see stdlib source code here). You can do the same with os.mkfifo:
import os, errno, tempfile
def mkftemp(*args, **kwargs):
for attempt in xrange(1024):
tpath = tempfile.mktemp(*args, **kwargs)
try:
os.mkfifo(tpath, 0600)
except OSError as e:
if e.errno == errno.EEXIST:
# lets try again
continue
else:
raise
else:
# NOTE: we only return the path because opening with
# os.open here would block indefinitely since there
# isn't anyone on the other end of the fifo.
return tpath
else:
raise IOError(errno.EEXIST, "No usable temporary file name found")
Why not just use mkstemp()?
For example:
import tempfile
import os
handle, filename = tempfile.mkstemp()
os.mkfifo(filename)
writer = open(filename, os.O_WRONLY)
reader = open(filename, os.O_RDONLY)
os.close(handle)