| #!/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() | gp.verbose()) +\ |
| "\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() | gp.verbose()) +\ |
| "\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) |