I am writing a method which takes path and file_name as arguments and looks for the specific file in the path (also in sub directories in path). In case the file is found, it is read properly. But if it is not there, I am unable to raise an exception. I have tried it like this:
def get_file_data(src_path, file_name):
try:
for root, _, files in os.walk(src_path):
for file in files:
if file.endswith(file_name):
print("File Found: ", os.path.join(root, file))
with open(os.path.join(root, file), "r+", encoding="utf-8") as data_file:
return json.load(data_file)
except FileNotFoundError as err:
return f"{file_name} doesn't exist"
but it never raised.I realized that if the ifcondition is not satisfied, it wouldn’t raise as the file will only be opened if found. Then I tried the code below in order to skip the files which don’t end with the file_name:
def get_file_data(src_path, file_name):
for root, _, files in os.walk(src_path):
for file in files:
if not file.endswith(file_name):
continue
if file.endswith(file_name):
print("File Found: ", os.path.join(root, file))
with open(os.path.join(root, file), "r+", encoding="utf-8") as data_file:
return json.load(data_file)
else:
raise FileNotFoundError(f"{file_name} doesn't exist")
My pytest looks something like:
def test_get_file_data_file_not_found():
with pytest.raises(FileNotFoundError):
get_file_data(os.getcwd(), "ABSENT")
I am not sure which method is better to use after fixing the issue of raising. Also, how to raise an exception if file not found. Any help is much appreciated. Thanks in advance! Good day!
>Solution :
Your first code doesn’t raise exception, it catches it. And as you noticed, code in loop won’t raise it anyways, so you either get None or the correct data. Then, the second thing raises the error inside the loop in a condition that is never satisfied – you already continue in that case! So again, you get only None or data, no exception.
If you want to raise exception if file is not found, you should just do raise FileNotFoundError("optional message here, probably with additional info") after the loop (so after all searching is done and nothing is found).
Like this:
def get_file_data(src_path, file_name):
for root, _, files in os.walk(src_path):
for file in files:
if file.endswith(file_name):
print("File Found: ", os.path.join(root, file))
with open(os.path.join(root, file), "r+", encoding="utf-8") as data_file:
return json.load(data_file)
raise FileNotFoundError(f"{file_name} doesn't exist in {src_path}")
Now the pytest should work because you actually raise the error.
Quick demonstration in REPL:
>>> def get_file_data(src_path, file_name):
... for root, _, files in os.walk(src_path):
... for file in files:
... if file.endswith(file_name):
... print("File Found: ", os.path.join(root, file))
... with open(os.path.join(root, file), "r+", encoding="utf-8") as data_file:
... return json.load(data_file)
... raise FileNotFoundError(f"{file_name} doesn't exist in {src_path}")
...
>>> import os
>>> get_file_data(os.getcwd(), "ABSENT")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in get_file_data
FileNotFoundError: ABSENT doesn't exist in /home/myusername
>>>