1#!/usr/bin/env python 2 3r""" 4This module provides validation functions like valid_value(), valid_integer(), 5etc. for robot programs. 6""" 7 8import re 9import gen_print as gp 10import gen_valid as gv 11import func_args as fa 12 13from robot.libraries.BuiltIn import BuiltIn 14 15 16def valid_var_name(var_name): 17 r""" 18 Validate the robot variable name and return its value. 19 20 If the variable is undefined, this function will print an error message 21 and call BuiltIn().fail(). 22 23 Description of arguments(): 24 var_name The name of the robot variable (e.g. 25 "var1"). Do not include "${}" (e.g. 26 "${var1}". Just provide the simple name 27 of the variable. 28 """ 29 30 # Note: get_variable_value() seems to have no trouble with local variables. 31 var_value = BuiltIn().get_variable_value("${" + var_name + "}") 32 if var_value is None: 33 var_value = "<undefined>" 34 error_message = gv.valid_value(var_value, invalid_values=[var_value], 35 var_name=var_name) 36 BuiltIn().fail(error_message) 37 38 return var_value 39 40 41def valid_init(var_name, *args, **kwargs): 42 r""" 43 Do initialization for variable validation and return var_name, args and 44 kwargs. 45 46 This function is to be called by all of the various validation functions 47 in this module. 48 49 This function is designed solely for use by other functions in this file. 50 51 Description of argument(s): 52 var_name The name of the variable to be validated. 53 args The positional arguments to be passed to a 54 validation function. 55 kwargs The keyword arguments to be passed to a 56 validation function. 57 """ 58 59 var_value = valid_var_name(var_name) 60 # Convert python string object definitions to objects (useful for robot 61 # callers). 62 args = fa.args_to_objects(args) 63 kwargs = fa.args_to_objects(kwargs) 64 return var_value, args, kwargs 65 66 67def process_error_message(error_message): 68 r""" 69 Process an error message. 70 71 If error_message is non-blank, fail. Otherwise, do nothing. 72 73 This function is designed solely for use by other functions in this file. 74 75 Description of argument(s): 76 error_message The error message to be processed. 77 """ 78 79 if error_message: 80 error_message = gp.sprint_error_report(error_message) 81 BuiltIn().fail(error_message) 82 83 84# The docstring header will be pre-pended to each validation function's 85# existing docstring. 86docstring_header = \ 87 r""" 88 Fail if the variable named by var_name is invalid. 89 """ 90 91 92def customize_doc_string(doc_string): 93 r""" 94 Customize a gen_valid function docstring and return the result. 95 96 This function is designed solely for use by other functions in this file. 97 98 The caller should pass a docstring from a gen_valid.py validation 99 function. This docstring will be changed to make a suitable docstring for 100 this module's corresponding validation function. 101 102 For example: 103 104 Let's suppose that gen_valid.py has a function called "valid_value()". 105 This module could make the following call to essentially copy gen_valid's 106 "valid_value()" function, modify it and then assign it to the local 107 version of the valid_value() function. 108 109 valid.__doc__ = customize_doc_string(gv.valid.__doc__) 110 111 Description of argument(s): 112 doc_string The docstring to be customized. 113 """ 114 115 doc_string = docstring_header + doc_string 116 doc_string = doc_string.split("\n") 117 118 start_ix = 0 119 # Find the "var_value" line. 120 start_ix = next((index for index, value in 121 enumerate(doc_string[start_ix:], start_ix) 122 if re.match("[ ]+var_value ", value)), None) 123 # Replace the "var_value" line with our "var_name" line. 124 doc_string[start_ix] = " var_name " \ 125 + "The name of the variable to be validated." 126 127 return "\n".join(doc_string) 128 129 130# All of the following functions are robot wrappers for the equivalent 131# functions defined in gen_valid.py. Note that the only difference between 132# any two of these locally defined functions is the function name and the 133# gv.<function name> which they call. Also, note that the docstring for each 134# is created by modifying the docstring from the supporting gen_valid.py 135# function. 136 137def valid_type(var_name, *args, **kwargs): 138 139 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 140 error_message = \ 141 gv.valid_type(var_value, *args, var_name=var_name, **kwargs) 142 process_error_message(error_message) 143 144 145def valid_value(var_name, *args, **kwargs): 146 147 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 148 error_message = \ 149 gv.valid_value(var_value, *args, var_name=var_name, **kwargs) 150 process_error_message(error_message) 151 152 153def valid_range(var_name, *args, **kwargs): 154 155 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 156 error_message = \ 157 gv.valid_range(var_value, *args, var_name=var_name, **kwargs) 158 process_error_message(error_message) 159 160 161def valid_integer(var_name, *args, **kwargs): 162 163 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 164 error_message = \ 165 gv.valid_integer(var_value, *args, var_name=var_name, **kwargs) 166 process_error_message(error_message) 167 168 169def valid_dir_path(var_name, *args, **kwargs): 170 171 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 172 error_message = \ 173 gv.valid_dir_path(var_value, *args, var_name=var_name, **kwargs) 174 process_error_message(error_message) 175 176 177def valid_file_path(var_name, *args, **kwargs): 178 179 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 180 error_message = \ 181 gv.valid_file_path(var_value, *args, var_name=var_name, **kwargs) 182 process_error_message(error_message) 183 184 185def valid_path(var_name, *args, **kwargs): 186 187 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 188 error_message = \ 189 gv.valid_path(var_value, *args, var_name=var_name, **kwargs) 190 process_error_message(error_message) 191 192 193def valid_list(var_name, *args, **kwargs): 194 195 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 196 error_message = \ 197 gv.valid_list(var_value, *args, var_name=var_name, **kwargs) 198 process_error_message(error_message) 199 200 201def valid_dict(var_name, *args, **kwargs): 202 203 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 204 error_message = \ 205 gv.valid_dict(var_value, *args, var_name=var_name, **kwargs) 206 process_error_message(error_message) 207 208 209def valid_program(var_name, *args, **kwargs): 210 211 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 212 error_message = \ 213 gv.valid_program(var_value, *args, var_name=var_name, **kwargs) 214 process_error_message(error_message) 215 216 217def valid_length(var_name, *args, **kwargs): 218 219 var_value, args, kwargs = valid_init(var_name, *args, **kwargs) 220 error_message = \ 221 gv.valid_length(var_value, *args, var_name=var_name, **kwargs) 222 process_error_message(error_message) 223 224 225# Modify the validation function docstrings by calling customize_doc_string 226# for each function in the func_names list. 227func_names = [ 228 "valid_type", "valid_value", "valid_range", "valid_integer", 229 "valid_dir_path", "valid_file_path", "valid_path", "valid_list", 230 "valid_dict", "valid_program", "valid_length" 231] 232 233for func_name in func_names: 234 cmd_buf = func_name \ 235 + ".__doc__ = customize_doc_string(gv.raw_doc_strings['" \ 236 + func_name + "'])" 237 exec(cmd_buf) 238