blob: 882e31de0d264c53eedf7b9c4d8b115ca5971b85 [file] [log] [blame]
#!/usr/bin/env python
r"""
This module provides valuable argument processing functions like
gen_get_options and sprint_args.
"""
import os
import gen_print as gp
exit_on_error = False
def set_exit_on_error(value):
r"""
Set the exit_on_error value to either True or False.
If exit_on_error is set, validation functions like valid_value will exit
the program on error instead of returning False.
Description of argument(s):
value Value to set global exit_on_error to.
"""
global exit_on_error
exit_on_error = value
def get_var_name(var_name):
r"""
If var_name has a value, simply return it. Otherwise, get the variable
name of the first argument used to call the validation function (e.g.
valid_value, valid_integer, etc.) and return it.
This function is designed solely for use by other functions in this file.
Example:
A programmer codes this:
valid_value(last_name)
Which results in the following call stack:
valid_value(last_name)
-> svalid_value(var_value...)
-> get_var_name(var_name)
In this example, this function will return "last_name".
Example:
err_msg = svalid_value(last_name, var_name="some_other_name")
Which results in the following call stack:
svalid_value(var_value, var_name="some_other_name")
-> get_var_name(var_name)
In this example, this function will return "some_other_name".
Description of argument(s):
var_name The name of the variable.
"""
if var_name != "":
return var_name
# Calculate stack_frame_ix. The validation functions in this file come
# in pairs. There is an "s" version of each validation function (e.g.
# svalid_value) whose job is to return an error message string. Then
# there is a wrapper function (e.g. valid_value) that will call the "s"
# version and print the result if there is an error. See examples 1 and 2
# above for illustration. This function must be cognizant of both
# scenarios to accurately determine the name of the variable being
# validated. Where the "s" function is being called directly, the
# stack_frame_ix should be set to 3. Where the wrapper function is being
# called, the stack_frame_ix should be incremented to 4.
stack_frame_ix = 3
parent_func_name = gp.sprint_func_name(2)
grandparent_func_name = gp.sprint_func_name(3)
if parent_func_name == "s" + grandparent_func_name:
stack_frame_ix += 1
var_name = gp.get_arg_name(0, 1, stack_frame_ix)
return var_name
def process_error_message(error_message):
r"""
Process the error_message as follows:
- If the error_message is blank, return True.
- If the error_message contains a value:
- Print the error_message as part of a full error report.
- If global exit_on_error is set, then exit the program with a return
code of 1.
- If exit_on_error is not set, return False.
This function is designed solely for use by wrapper functions in this file
(e.g. "valid_value").
Description of argument(s):
error_message An error message.
"""
if error_message == "":
return True
gp.print_error_report(error_message)
if exit_on_error:
exit(1)
return False
def svalid_value(var_value,
invalid_values=[],
valid_values=[],
var_name=""):
r"""
Return an empty string if var_value is a valid value. Otherwise, return
an error string.
Description of arguments:
var_value The value being validated.
invalid_values A list of invalid values. If var_value is
equal to any of these, it is invalid.
Note that if you specify anything for
invalid_values (below), the valid_values
list is not even processed. If you
specify nothing for both invalid_values
and valid_values, invalid_values will be
set to a default value of [""].
valid_values A list of valid values. var_value must be
equal to one of these values to be
considered valid.
var_name The name of the variable whose value is
passed in var_value. This parameter is
normally unnecessary as this function can
figure out the var_name. This is provided
for Robot callers. In this scenario, we
are unable to get the variable name
ourselves.
"""
success_message = ""
error_message = ""
# Validate this function's arguments.
len_valid_values = len(valid_values)
len_invalid_values = len(invalid_values)
if len_valid_values > 0 and len_invalid_values > 0:
error_message += "Programmer error - You must provide either an" +\
" invalid_values list or a valid_values" +\
" list but NOT both.\n" +\
gp.sprint_var(invalid_values) +\
gp.sprint_var(valid_values)
return error_message
if len_valid_values > 0:
# Processing the valid_values list.
if var_value in valid_values:
return success_message
error_message += "The following variable has an invalid" +\
" value:\n" +\
gp.sprint_varx(get_var_name(var_name), var_value,
gp.blank()) +\
"\nIt must be one of the following values:\n" +\
gp.sprint_var(valid_values, gp.blank())
return error_message
if len_invalid_values == 0:
# Assign default value.
invalid_values = [""]
# Assertion: We have an invalid_values list. Processing it now.
if var_value not in invalid_values:
return success_message
error_message += "The following variable has an invalid value:\n" +\
gp.sprint_varx(get_var_name(var_name), var_value,
gp.blank()) +\
"\nIt must NOT be one of the following values:\n" +\
gp.sprint_var(invalid_values, gp.blank())
return error_message
def valid_value(var_value,
invalid_values=[],
valid_values=[],
var_name=""):
r"""
Return True if var_value is valid. Otherwise, print an error message and
either return False or exit(1) depending on the value of exit_on_error.
Description of arguments:
(See description of arguments for svalid_value (above)).
"""
error_message = svalid_value(var_value, invalid_values, valid_values,
var_name)
return process_error_message(error_message)
def svalid_integer(var_value,
var_name=""):
r"""
Return an empty string if var_value is a valid integer. Otherwise, return
an error string.
Description of arguments:
var_value The value being validated.
var_name The name of the variable whose value is
passed in var_value. This parameter is
normally unnecessary as this function can
figure out the var_name. This is provided
for Robot callers. In this scenario, we
are unable to get the variable name
ourselves.
"""
success_message = ""
error_message = ""
try:
if isinstance(int(str(var_value), 0), int):
return success_message
except ValueError:
pass
# If we get to this point, the validation has failed.
error_message +=\
"Invalid integer value:\n" +\
gp.sprint_varx(get_var_name(var_name), var_value, gp.blank())
return error_message
def valid_integer(var_value,
var_name=""):
r"""
Return True if var_value is a valid integer. Otherwise, print an error
message and either return False or exit(1) depending on the value of
exit_on_error.
Description of arguments:
(See description of arguments for svalid_integer (above)).
"""
error_message = svalid_integer(var_value, var_name)
return process_error_message(error_message)
def svalid_dir_path(var_value,
var_name=""):
r"""
Return an empty string if var_value is a valid directory path. Otherwise,
return an error string.
Description of arguments:
var_value The value being validated.
var_name The name of the variable whose value is
passed in var_value. This parameter is
normally unnecessary as this function can
figure out the var_name. This is provided
for Robot callers. In this scenario, we
are unable to get the variable name
ourselves.
"""
error_message = ""
if not os.path.isdir(str(var_value)):
error_message += "The following directory does not exist:\n" +\
gp.sprint_varx(get_var_name(var_name), var_value)
return error_message
def valid_dir_path(var_value,
var_name=""):
r"""
Return True if var_value is a valid directory path. Otherwise, print an
error message and either return False or exit(1) depending on the value of
exit_on_error.
Valid means that the directory path exists.
Description of arguments:
(See description of arguments for svalid_dir_path (above)).
"""
error_message = svalid_dir_path(var_value, var_name)
return process_error_message(error_message)
def svalid_file_path(var_value,
var_name=""):
r"""
Return an empty string if var_value is a valid file path. Otherwise,
return an error string.
Description of arguments:
var_value The value being validated.
var_name The name of the variable whose value is
passed in var_value. This parameter is
normally unnecessary as this function can
figure out the var_name. This is provided
for Robot callers. In this scenario, we
are unable to get the variable name
ourselves.
"""
error_message = ""
if not os.path.isfile(str(var_value)):
error_message += "Invalid file (does not exist):\n" +\
gp.sprint_varx(get_var_name(var_name), var_value)
return error_message
def valid_file_path(var_value,
var_name=""):
r"""
Return True if var_value is a valid file path. Otherwise, print an error
message and either return False or exit(1) depending on the value of
exit_on_error.
Valid means that the file exists.
Description of arguments:
(See description of arguments for svalid_file_path (above)).
"""
error_message = svalid_file_path(var_value, var_name)
return process_error_message(error_message)
def svalid_path(var_value,
var_name=""):
r"""
Return an empty string if var_value is either a valid file path or
directory path. Otherwise, return an error string.
Description of arguments:
var_value The value being validated.
var_name The name of the variable whose value is
passed in var_value. This parameter is
normally unnecessary as this function can
figure out the var_name. This is provided
for Robot callers. In this scenario, we
are unable to get the variable name
ourselves.
"""
error_message = ""
if not (os.path.isfile(str(var_value)) or os.path.isdir(str(var_value))):
error_message = "Invalid path (file or directory does not exist):\n" +\
gp.sprint_varx(get_var_name(var_name), var_value)
return error_message
def valid_path(var_value,
var_name=""):
r"""
Return True if var_value is a valid file path. Otherwise, print an error
message and either return False or exit(1) depending on the value of
exit_on_error.
Valid means that the file exists.
Description of arguments:
(See description of arguments for svalid_path (above)).
"""
error_message = svalid_path(var_value, var_name)
return process_error_message(error_message)
def svalid_range(var_value,
valid_range=[],
var_name=""):
r"""
Return an empty string if var_value is within the range. Otherwise,
return an error string.
Description of arguments:
var_value The value being validated. This value
must be an integer.
valid_range A list comprised of one or two elements
which are the lower and upper ends of a
range. These values must be integers
except where noted. Valid specifications
may be of the following forms: [lower,
upper], [lower] or [None, upper].
var_name The name of the variable whose value is
passed in var_value. This parameter is
normally unnecessary as this function can
figure out the var_name. This is provided
for Robot callers. In this scenario, we
are unable to get the variable name
ourselves.
"""
error_message = ""
# Validate this function's parms:
# First, ensure that the value is an integer.
error_message = svalid_integer(var_value, var_name)
if not error_message == "":
return error_message
var_value = int(var_value)
len_valid_range = len(valid_range)
if len_valid_range == 0 or len_valid_range > 2:
error_message += "Programmer error - For the valid_range parameter," +\
" you must provide a list consisting of one or two" +\
" elements.\n" +\
gp.sprint_var(valid_range)
return error_message
if len_valid_range == 1 or valid_range[0] is not None:
# Make sure lower valid_range value is an integer.
error_message = svalid_integer(valid_range[0], "valid_range[0]")
if not error_message == "":
error_message = "Programmer error:\n" + error_message
return error_message
if valid_range[0] is not None:
valid_range[0] = int(valid_range[0])
if len_valid_range == 2:
# Make sure upper valid_range value is an integer.
error_message = svalid_integer(valid_range[1], "valid_range[1]")
if not error_message == "":
error_message = "Programmer error:\n" + error_message
return error_message
valid_range[1] = int(valid_range[1])
if valid_range[0] is not None and valid_range[0] > valid_range[1]:
error_message = "Programmer error - In the following range, the" +\
" lower limit is greater than the upper" +\
" limit:\n" + gp.sprint_var(valid_range)
return error_message
if len_valid_range == 1:
if var_value < valid_range[0]:
error_message += "The following variable is not within the" +\
" expected range:\n" +\
gp.sprint_varx(get_var_name(var_name),
var_value) +\
gp.sprint_varx("valid_range",
str(valid_range[0]) + "..")
return error_message
return error_message
if valid_range[0] is None:
if var_value > valid_range[1]:
error_message += "The following variable is not within the" +\
" expected range:\n" +\
gp.sprint_varx(get_var_name(var_name),
var_value) +\
gp.sprint_varx("valid_range",
".." + str(valid_range[1]))
return error_message
if var_value < valid_range[0] or var_value > valid_range[1]:
error_message += "The following variable is not within the expected" +\
" range:\n" +\
gp.sprint_varx(get_var_name(var_name), var_value) +\
gp.sprint_varx("valid_range",
str(valid_range[0]) + ".."
+ str(valid_range[1]))
return error_message
return error_message
def valid_range(var_value,
valid_range=[],
var_name=""):
r"""
Return True if var_value is within range. Otherwise, print an error
message and either return False or exit(1) depending on the value of
exit_on_error.
Description of arguments:
(See description of arguments for svalid_range (above)).
"""
error_message = svalid_range(var_value, valid_range, var_name)
return process_error_message(error_message)
def svalid_list(var_value,
valid_values=[],
var_name=""):
r"""
Return an empty string if var_value is a valid list. Otherwise, return an
error string.
Description of arguments:
var_value The value (i.e. list) being validated.
valid_values A list of valid values. Each element in
the var_value list must be equal to one of
these values to be considered valid.
var_name The name of the variable whose value is
passed in var_value. This parameter is
normally unnecessary as this function can
figure out the var_name. This is provided
for Robot callers. In this scenario, we
are unable to get the variable name
ourselves.
"""
error_message = ""
if len(var_value) == 0:
error_message += "The \"" + get_var_name(var_name)
error_message += "\" list is empty and is therefore invalid:\n"
return error_message
found_error = 0
display_var_value = list(var_value)
for ix in range(0, len(var_value)):
if var_value[ix] not in valid_values:
found_error = 1
display_var_value[ix] = var_value[ix] + "*"
if found_error:
error_message += "The list entries marked with \"*\" are not valid:\n"
error_message += gp.sprint_varx(get_var_name(var_name),
display_var_value, gp.blank())
error_message += gp.sprint_var(valid_values)
return error_message
return ""
def valid_list(var_value,
valid_values=[],
var_name=""):
r"""
Return True if var_value is a valid list. Otherwise, print an error
message and either return False or exit(1) depending on the value of
exit_on_error.
Description of arguments:
(See description of arguments for svalid_list (above)).
"""
error_message = svalid_list(var_value, valid_values, var_name)
return process_error_message(error_message)
def svalid_dict(var_value,
required_keys=[],
var_name=""):
r"""
Return an empty string if var_value is a valid dictionary. Otherwise,
return an error string.
Description of arguments:
var_value The value (i.e. dictionary) being
validated.
required_keys A list of keys which must be found in the
dictionary for it to be considered valid.
var_name The name of the variable whose value is
passed in var_value. This parameter is
normally unnecessary as this function can
figure out the var_name. This is provided
for Robot callers. In this scenario, we
are unable to get the variable name
ourselves.
"""
error_message = ""
keys_missing = list(set(required_keys) - set(var_value.keys()))
if len(keys_missing) > 0:
var_name = get_var_name(var_name)
error_message = "The following key fields are missing from "
error_message += var_name + ":\n"
error_message += gp.sprint_var(keys_missing)
error_message += gp.sprint_varx(var_name, var_value, gp.blank())
return error_message
return ""
def valid_dict(var_value,
required_keys=[],
var_name=""):
r"""
Return True if var_value is a valid dictionary. Otherwise, print an error
message and either return False or exit(1) depending on the value of
exit_on_error.
Description of arguments:
(See description of arguments for svalid_list (above)).
"""
error_message = svalid_dict(var_value, required_keys, var_name)
return process_error_message(error_message)