Browse Source

Handle non-string types in the conf loader.

master
poikilos 3 years ago
parent
commit
f5878551f6
  1. 120
      utilities/pyissuesyncd

120
utilities/pyissuesyncd

@ -235,7 +235,8 @@ def start_issuesyncd(src_options, dst_options):
"".format(issue_no, reason_msg)) "".format(issue_no, reason_msg))
continue continue
else: else:
error("#{}: Error 404: \"{}\" (Are there no more?)" error("#{}: Error 404: \"{}\""
" (The end of the list is assumed.)"
"".format(issue_no, reason_msg)) "".format(issue_no, reason_msg))
# error(" * reason: {}".format(err.get('reason'))) # error(" * reason: {}".format(err.get('reason')))
# error(" * headers: {}".format(err.get('headers'))) # error(" * headers: {}".format(err.get('headers')))
@ -480,12 +481,112 @@ def usage():
print("") print("")
trues = ["true", "on", "yes"]
falses = ["false", "off", "no"]
def str_to_value(valueStr, typeName=None, lineN=-1, path="(generated)"):
'''
Convert a string such as from a conf file to a value that may be of
a different type than string. The type will be detected by the
content of the string as follows (in order):
- If it is the string "None" then it will become None.
- It is int if it converts to int without ValueError.
- It is float if it converts to float without ValueError.
- It is bool if the string is (case insensitively) in the trues or
falses list.
- It is a string in all other cases. typeStr = None
Keyword arguments:
typeName -- Force it to be this type, otherwise raise ValueError.
If typeName is "bool", a number 0 or 1 will be converted to
False or True, respectively. Otherwise, the value has to be in
the global trues or falses list (case-insensitive). The typeName
must be: int, str, float, or bool, such as obtained via
`type(anotherValue).__name__`.
path -- The file (used for error reporting only).
lineN -- The line number in the file (used for error reporting only).
'''
valueL = None
if valueStr is not None:
valueL = valueStr.lower()
if typeName is not None:
if valueStr == "None":
error("{}:{}: WARNING: The program expected a(n) '{}' but"
" the value was 'None' and will become"
" None."
"".format(conf_path, lineN, typeName))
return None
elif typeName == "bool":
moreTrues = ['1'] + trues
moreFalses = ['0'] + falses
if valueL in moreTrues:
return True
elif valueL in moreFalses:
return False
else:
raise ValueError("{}:{}: A bool value is expected:"
" {} or {} (case insensitive) and if"
" the typeName is defined by the"
" program as 'bool' (which it is in"
" this case) then '0' or '1'"
" are also ok)."
"".format(conf_path, lineN, trues,
falses))
elif typeName == 'int':
try:
return int(valueStr)
except ValueError:
raise ValueError("{}:{}: An int value is expected:"
" the typeName is defined by the"
" program as 'int'."
"".format(conf_path, lineN, trues,
falses))
elif typeName == 'float':
try:
return float(valueStr)
except ValueError:
raise ValueError("{}:{}: A float value is expected:"
" the typeName is defined by the"
" program as 'float'."
"".format(conf_path, lineN, trues,
falses))
elif typeName == "str":
return valueStr
else:
raise NotImplementedError("The type {} isn't implemented"
" in str_to_value."
"".format(typeName))
if valueStr == "None":
return None
try:
return int(valueStr)
except ValueError:
pass
try:
return float(valueStr)
except ValueError:
pass
if valueL in trues:
return True
elif valueL in falses:
return False
return valueStr
def modify_dict_by_conf(options, conf_path, always_lower=False, def modify_dict_by_conf(options, conf_path, always_lower=False,
no_file_error=True, no_value_error=True, no_file_error=True, no_value_error=True,
quiet=True): quiet=True):
''' '''
Set values in the options dict using conf assignment operations Set values in the options dict using conf assignment operations
in the file at conf_path. in the file at conf_path. If the key is in the dict, that will
determine the type. Otherwise, the type will be detected by
str_to_value. If there is nothing after the equal sign on the line,
the value will be None (or if no_value_error is True it will be
ignored and an error will be displayed).
Keyword arguments: Keyword arguments:
always_lower -- If True, options in the conf file won't be added always_lower -- If True, options in the conf file won't be added
@ -511,21 +612,28 @@ def modify_dict_by_conf(options, conf_path, always_lower=False,
error("{}:{}: A value is expected before '='." error("{}:{}: A value is expected before '='."
"".format(conf_path, lineN)) "".format(conf_path, lineN))
name = line[:signI].strip() name = line[:signI].strip()
value = line[signI+1:].strip() valueStr = line[signI+1:].strip()
if value == "": value = None
if valueStr == "":
value = None value = None
if always_lower: if always_lower:
if name.lower() != name: if name.lower() != name:
error("{}:{}: A lowercase name is expected." error("{}:{}: A lowercase name is expected."
"".format(conf_path, lineN)) "".format(conf_path, lineN))
continue continue
if (value is None) and no_value_error: if (valueStr is None) and no_value_error:
error("{}:{}: A value is expected." error("{}:{}: A value is expected."
"".format(conf_path, lineN)) "".format(conf_path, lineN))
else: else:
typeName = None
oldValue = options.get(name)
if oldValue is not None:
typeName = type(oldValue).__name__
value = str_to_value(valueStr, typeName=typeName,
path=conf_path, lineN=lineN)
options[name] = value options[name] = value
if not quiet: if not quiet:
error("{}: Set {} to {}" error("[settings] {}: Set {} to {}"
"".format(conf_name, name, value)) "".format(conf_name, name, value))
else: else:
if no_file_error: if no_file_error:

Loading…
Cancel
Save