New exit_on_error mode for gen_valid.py
In 'exit_on_error' mode, the validation functions will exit the program
on error instead of returning False.
- Also general cleanup and improvements including:
- New functions:
- get_var_name
- process_error_message
- svalid_path
- valid_path
Change-Id: If69243f794cf880b3677336d3b5bedd2539a5de9
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/lib/gen_valid.py b/lib/gen_valid.py
index 9db81e6..e18e847 100755
--- a/lib/gen_valid.py
+++ b/lib/gen_valid.py
@@ -5,11 +5,110 @@
gen_get_options and sprint_args.
"""
-import sys
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 arguement 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(0)
+ return False
+
def svalid_value(var_value,
invalid_values=[],
@@ -25,7 +124,10 @@
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.
+ 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 invalid values. var_value must
be equal to one of these values to be
considered valid.
@@ -40,8 +142,8 @@
success_message = ""
error_message = ""
- stack_frame_ix = 3
+ # 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:
@@ -57,11 +159,10 @@
# Processing the valid_values list.
if var_value in valid_values:
return success_message
- if var_name == "":
- var_name = gp.get_arg_name(0, 1, stack_frame_ix)
error_message += "The following variable has an invalid" +\
" value:\n" +\
- gp.sprint_varx(var_name, var_value, show_blanks) +\
+ gp.sprint_varx(get_var_name(var_name), var_value,
+ show_blanks) +\
"\nIt must be one of the following values:\n" +\
gp.sprint_varx("valid_values", valid_values,
show_blanks)
@@ -75,10 +176,9 @@
if var_value not in invalid_values:
return success_message
- if var_name == "":
- var_name = gp.get_arg_name(0, 1, stack_frame_ix)
error_message += "The following variable has an invalid value:\n" +\
- gp.sprint_varx(var_name, var_value, show_blanks) +\
+ gp.sprint_varx(get_var_name(var_name), var_value,
+ show_blanks) +\
"\nIt must NOT be one of the following values:\n" +\
gp.sprint_varx("invalid_values", invalid_values,
show_blanks)
@@ -90,8 +190,8 @@
valid_values=[],
var_name=""):
r"""
- Return True if var_value is a valid value. Otherwise, return False and
- print an error message to stderr.
+ 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)).
@@ -99,11 +199,7 @@
error_message = svalid_value(var_value, invalid_values, valid_values,
var_name)
-
- if not error_message == "":
- gp.print_error_report(error_message)
- return False
- return True
+ return process_error_message(error_message)
def svalid_integer(var_value,
@@ -132,13 +228,10 @@
pass
# If we get to this point, the validation has failed.
- if var_name is "":
- stack_index = 3
- var_name = gp.get_arg_name(0, 1, stack_index)
-
show_blanks = 1
- error_message += "Invalid integer value:\n" +\
- gp.sprint_varx(var_name, var_value, show_blanks)
+ error_message +=\
+ "Invalid integer value:\n" +\
+ gp.sprint_varx(get_var_name(var_name), var_value, show_blanks)
return error_message
@@ -146,19 +239,16 @@
def valid_integer(var_value,
var_name=""):
r"""
- Return True if var_value is a valid integer. Otherwise, return False and
- print an error message to stderr.
+ 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_value (above)).
+ (See description of arguments for svalid_integer (above)).
"""
error_message = svalid_integer(var_value, var_name)
-
- if not error_message == "":
- gp.print_error_report(error_message)
- return False
- return True
+ return process_error_message(error_message)
def svalid_dir_path(var_value,
@@ -180,11 +270,8 @@
error_message = ""
if not os.path.isdir(str(var_value)):
- if var_name is "":
- stack_index = 3
- var_name = gp.get_arg_name(0, 1, stack_index)
error_message += "The following directory does not exist:\n" +\
- gp.sprint_varx(var_name, var_value)
+ gp.sprint_varx(get_var_name(var_name), var_value)
return error_message
@@ -192,20 +279,18 @@
def valid_dir_path(var_value,
var_name=""):
r"""
- Return True if var_value is a valid integer. Otherwise, return False and
- print an error message to stderr.
+ 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_value (above)).
+ (See description of arguments for svalid_dir_path (above)).
"""
error_message = svalid_dir_path(var_value, var_name)
-
- if not error_message == "":
- gp.print_error_report(error_message)
- return False
-
- return True
+ return process_error_message(error_message)
def svalid_file_path(var_value,
@@ -227,11 +312,8 @@
error_message = ""
if not os.path.isfile(str(var_value)):
- if var_name is "":
- stack_index = 3
- var_name = gp.get_arg_name(0, 1, stack_index)
error_message += "Invalid file (does not exist):\n" +\
- gp.sprint_varx(var_name, var_value)
+ gp.sprint_varx(get_var_name(var_name), var_value)
return error_message
@@ -239,24 +321,64 @@
def valid_file_path(var_value,
var_name=""):
r"""
- Return True if var_value is a valid integer. Otherwise, return False and
- print an error message to stderr.
+ 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_value (above)).
+ (See description of arguments for svalid_file_path (above)).
"""
error_message = svalid_file_path(var_value, var_name)
+ return process_error_message(error_message)
- if not error_message == "":
- gp.print_error_report(error_message)
- return False
- return True
+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,
- range=[],
+ valid_range=[],
var_name=""):
r"""
Return an empty string if var_value is within the range. Otherwise,
@@ -265,7 +387,7 @@
Description of arguments:
var_value The value being validated. This value
must be an integer.
- range A list comprised of one or two elements
+ 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
@@ -281,8 +403,6 @@
"""
error_message = ""
- if var_name == "":
- var_name = gp.get_arg_name(0, 1, stack_frame_ix=3)
# Validate this function's parms:
# First, ensure that the value is an integer.
@@ -291,75 +411,80 @@
return error_message
var_value = int(var_value)
- len_range = len(range)
- if len_range > 2:
- error_message += "Programmer error - For the range parameter, you" +\
- " must provide a list consisting of one or two" +\
+ 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(range)
+ gp.sprint_var(valid_range)
return error_message
- if len_range == 1 or range[0] is not None:
- # Make sure lower range value is an integer.
- error_message = svalid_integer(range[0], "range[0]")
+ 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 range[0] is not None:
- range[0] = int(range[0])
- if len_range == 2:
- # Make sure upper range value is an integer.
- error_message = svalid_integer(range[1], "range[1]")
+ 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
- range[1] = int(range[1])
-
- if len_range == 1:
- if var_value < range[0]:
- error_message += "The following variable is not within the" +\
- " expected range:\n" +\
- gp.sprint_varx(var_name, var_value) +\
- gp.sprint_varx("valid_range",
- str(range[0]) + "..")
+ 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_varx("valid_range",
+ valid_range)
return error_message
- if range[0] is None:
- if var_value > range[1]:
+ 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(var_name, var_value) +\
+ gp.sprint_varx(get_var_name(var_name),
+ var_value) +\
gp.sprint_varx("valid_range",
- ".." + str(range[1]))
+ 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 < range[0] or var_value > range[1]:
+ 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(var_name, var_value) +\
+ gp.sprint_varx(get_var_name(var_name), var_value) +\
gp.sprint_varx("valid_range",
- str(range[0]) + ".." +
- str(range[1]))
+ str(valid_range[0]) + ".." +
+ str(valid_range[1]))
return error_message
return error_message
def valid_range(var_value,
- range=[],
+ valid_range=[],
var_name=""):
r"""
- Return True if var_value is within the range. Otherwise, return False and
- print an error message to stderr.
+ 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, range, var_name)
-
- if not error_message == "":
- gp.print_error_report(error_message)
- return False
-
- return True
+ error_message = svalid_range(var_value, valid_range, var_name)
+ return process_error_message(error_message)