If the file exists, but all keys do not exist - I want there to be an error telling me which keys do not exist.
This refers to the check_ini function;
This is what I have so far, but because I used a for loop above my try - I am unsure how to make number 3 happen. What I would like to happen is - check the six keys exist, add the values into my dataclass, and return that datacalss. Here is what I have so far. Any thoughts on how to do the try piece? Any thoughts / direction appreciated.
import os
from os.path import exists
from configparser import ConfigParser
from configparser import NoOptionError
from dataclasses import dataclass
from typing import Optional
from mypackage import config
@dataclass
class config_data:
success: bool
source_path: Optional[str] = None
def read_ini():
default_path = os.path.expanduser(config.CONFIG_INI_PATH)
final_path = os.environ.get('INI_PATH', default_path)
parser = ConfigParser()
parser.read(final_path)
return parser
def check_ini():
default_path = os.path.expanduser(config.CONFIG_INI_PATH)
final_path = os.environ.get('INI_PATH', default_path)
parser = ConfigParser()
parser.read(final_path)
ini = read_ini()
bad_keys = []
if exists(final_path):
keys = ("app", "source_path", "good", "conf_path", "rad", "suffix")
for option in keys:
try:
ini.get("default", option)
#config_data('True', 'source_oath')
except NoOptionError:
#print(NoOptionError(option, "default"))
print(f'This key is missing: {option}')
Hello, @swills1. I hope the code below will help you.
import os
from os.path import exists
from configparser import ConfigParser,NoOptionError
from dataclasses import dataclass
from typing import Optional
from mypackage import config
@dataclass
class config_data:
success: bool
data: dict
source_path: Optional[str] = None
def read_ini():
default_path = os.path.expanduser(config.CONFIG_INI_PATH)
final_path = os.environ.get('INI_PATH', default_path)
parser = ConfigParser()
parser.read(final_path)
return (parser,final_path)
def check_ini():
iniKeysAndValues = {}
iniAndFinalPath = read_ini()
ini = iniAndFinalPath[0]
final_path = iniAndFinalPath[1]
if exists(final_path):
keys = ("app", "source_path", "good", "conf_path", "rad", "suffix")
for option in keys:
try:
keyValue = ini.get("default", option)
iniKeysAndValues.setdefault(option,keyValue)
except NoOptionError:
iniKeysAndValues.setdefault(option,None)#If you like, you can remove this line. Removing may be more sensible in some case.
print(f'This key is missing: {option}')
return config_data(True,iniKeysAndValues,final_path)
print(check_ini())#Check if it works
Note: This code uses a dictionary to collect data.
Thank you, @soil. This is brilliant! One final question, since the return always returns even if the except is triggered, would it make sense to add a finally so that if the except was triggered, it fails / gives the error instead of returning the data? Or is there a better way? Thank you.
The source_path is a value in the ini file so the data dict encompasses it. I didn’t think to use a dict in the dataclass. That makes everything a lot easier. Thank you very much.
You are welcome. You can remove this line. This way, it won’t add a new key to the dictionary if except is triggered.(I hope I understood your question well)
iniKeysAndValues.setdefault(option,None)#If you like, you can remove this line. Removing may be more sensible in some case.
But raising a real error will crash your program. If you are still sure you want to raise, you can remove the except block and its inner code. You can also raise an exception manually, just updating your for-loop code like that:
if option in ini["default"]:#checks if "option" key exists in "default" section
keyValue = ini.get("default", option)
iniKeysAndValues.setdefault(option,keyValue)
else:
raise Exception(f"We couldn't find this key in your file:{option}")
Thanks. Yes, it needs to break if the keys aren’t found. The keys are needed for the program, so if they aren’t there - it will break anyway. Thanks again!
But, that line may create an “error”. If your ini file has a key which hasn’t got a value, {key_name:None} may confuse everything. So, make sure that you haven’t got any empty keys(they generally has this syntax: keyName= ) in your ini file before using this code line.(Using empty variables can also cause a kind of real parserError. You can see this documentation about it.)
Okay. Good luck in your project!(If you still have questions or something to say, you can just write it)
Note:You still should be careful about that line.