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