#!/usr/bin/env python r""" This module provides validation functions like valid_value(), valid_integer(), etc. for robot programs. """ import re import gen_print as gp import gen_valid as gv import func_args as fa from robot.libraries.BuiltIn import BuiltIn def valid_var_name(var_name): r""" Validate the robot variable name and return its value. If the variable is undefined, this function will print an error message and call BuiltIn().fail(). Description of arguments(): var_name The name of the robot variable (e.g. "var1"). Do not include "${}" (e.g. "${var1}". Just provide the simple name of the variable. """ # Note: get_variable_value() seems to have no trouble with local variables. var_value = BuiltIn().get_variable_value("${" + var_name + "}") if var_value is None: var_value = "" error_message = gv.valid_value(var_value, invalid_values=[var_value], var_name=var_name) BuiltIn().fail(error_message) return var_value def valid_init(var_name, *args, **kwargs): r""" Do initialization for variable validation and return var_name, args and kwargs. This function is to be called by all of the various validation functions in this module. This function is designed solely for use by other functions in this file. Description of argument(s): var_name The name of the variable to be validated. args The positional arguments to be passed to a validation function. kwargs The keyword arguments to be passed to a validation function. """ var_value = valid_var_name(var_name) # Convert python string object definitions to objects (useful for robot # callers). args = fa.args_to_objects(args) kwargs = fa.args_to_objects(kwargs) return var_value, args, kwargs def process_error_message(error_message): r""" Process an error message. If error_message is non-blank, fail. Otherwise, do nothing. This function is designed solely for use by other functions in this file. Description of argument(s): error_message The error message to be processed. """ if error_message: error_message = gp.sprint_error_report(error_message) BuiltIn().fail(error_message) # The docstring header will be pre-pended to each validation function's # existing docstring. docstring_header = \ r""" Fail if the variable named by var_name is invalid. """ def customize_doc_string(doc_string): r""" Customize a gen_valid function docstring and return the result. This function is designed solely for use by other functions in this file. The caller should pass a docstring from a gen_valid.py validation function. This docstring will be changed to make a suitable docstring for this module's corresponding validation function. For example: Let's suppose that gen_valid.py has a function called "valid_value()". This module could make the following call to essentially copy gen_valid's "valid_value()" function, modify it and then assign it to the local version of the valid_value() function. valid.__doc__ = customize_doc_string(gv.valid.__doc__) Description of argument(s): doc_string The docstring to be customized. """ doc_string = docstring_header + doc_string doc_string = doc_string.split("\n") start_ix = 0 # Find the "var_value" line. start_ix = next((index for index, value in enumerate(doc_string[start_ix:], start_ix) if re.match("[ ]+var_value ", value)), None) # Replace the "var_value" line with our "var_name" line. doc_string[start_ix] = " var_name " \ + "The name of the variable to be validated." return "\n".join(doc_string) # All of the following functions are robot wrappers for the equivalent # functions defined in gen_valid.py. Note that the only difference between # any two of these locally defined functions is the function name and the # gv. which they call. Also, note that the docstring for each # is created by modifying the docstring from the supporting gen_valid.py # function. def valid_type(var_name, *args, **kwargs): var_value, args, kwargs = valid_init(var_name, *args, **kwargs) error_message = \ gv.valid_type(var_value, *args, var_name=var_name, **kwargs) process_error_message(error_message) def valid_value(var_name, *args, **kwargs): var_value, args, kwargs = valid_init(var_name, *args, **kwargs) error_message = \ gv.valid_value(var_value, *args, var_name=var_name, **kwargs) process_error_message(error_message) def valid_range(var_name, *args, **kwargs): var_value, args, kwargs = valid_init(var_name, *args, **kwargs) error_message = \ gv.valid_range(var_value, *args, var_name=var_name, **kwargs) process_error_message(error_message) def valid_integer(var_name, *args, **kwargs): var_value, args, kwargs = valid_init(var_name, *args, **kwargs) error_message = \ gv.valid_integer(var_value, *args, var_name=var_name, **kwargs) process_error_message(error_message) def valid_dir_path(var_name, *args, **kwargs): var_value, args, kwargs = valid_init(var_name, *args, **kwargs) error_message = \ gv.valid_dir_path(var_value, *args, var_name=var_name, **kwargs) process_error_message(error_message) def valid_file_path(var_name, *args, **kwargs): var_value, args, kwargs = valid_init(var_name, *args, **kwargs) error_message = \ gv.valid_file_path(var_value, *args, var_name=var_name, **kwargs) process_error_message(error_message) def valid_path(var_name, *args, **kwargs): var_value, args, kwargs = valid_init(var_name, *args, **kwargs) error_message = \ gv.valid_path(var_value, *args, var_name=var_name, **kwargs) process_error_message(error_message) def valid_list(var_name, *args, **kwargs): var_value, args, kwargs = valid_init(var_name, *args, **kwargs) error_message = \ gv.valid_list(var_value, *args, var_name=var_name, **kwargs) process_error_message(error_message) def valid_dict(var_name, *args, **kwargs): var_value, args, kwargs = valid_init(var_name, *args, **kwargs) error_message = \ gv.valid_dict(var_value, *args, var_name=var_name, **kwargs) process_error_message(error_message) # Modify the validation function docstrings by calling customize_doc_string # for each function in the func_names list. func_names = [ "valid_type", "valid_value", "valid_range", "valid_integer", "valid_dir_path", "valid_file_path", "valid_path", "valid_list", "valid_dict" ] for func_name in func_names: cmd_buf = func_name \ + ".__doc__ = customize_doc_string(gv.raw_doc_strings['" \ + func_name + "'])" exec(cmd_buf) # Define aliases for backward compatibility. rvalid_value = valid_value