Changes to gen_print.py.
- Cleaned up the code that generates print, qprint and dprint
functions.
- Added support for printing to stdout in robot environment.
Change-Id: Ic9561b6fa77ad3b255685623a68947b1b1844d56
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/lib/gen_print.py b/lib/gen_print.py
index 643a3be..e5e74d8 100755
--- a/lib/gen_print.py
+++ b/lib/gen_print.py
@@ -18,10 +18,12 @@
import collections
try:
+ robot_env = 1
from robot.utils import DotDict
from robot.utils import NormalizedDict
+ from robot.libraries.BuiltIn import BuiltIn
except ImportError:
- pass
+ robot_env = 0
import gen_arg as ga
@@ -67,12 +69,9 @@
start_time = time.time()
sprint_time_last_seconds = start_time
-try:
- # The user can set environment variable "GEN_PRINT_DEBUG" to get debug
- # output from this module.
- gen_print_debug = int(os.environ['GEN_PRINT_DEBUG'])
-except KeyError:
- gen_print_debug = 0
+# The user can set environment variable "GEN_PRINT_DEBUG" to get debug output
+# from this module.
+gen_print_debug = int(os.environ.get('GEN_PRINT_DEBUG', 0))
###############################################################################
@@ -84,7 +83,7 @@
Description of arguments:
stack_frame_ix The index of the stack frame whose
function name should be returned. If the
- caller does not specifiy a value, this
+ caller does not specify a value, this
function will set the value to 1 which is
the index of the caller's stack frame. If
the caller is the wrapper function
@@ -120,7 +119,7 @@
Return the "name" of an argument passed to a function. This could be a
literal or a variable name.
- Description of arguements:
+ Description of arguments:
var The variable whose name you want returned.
arg_num The arg number (1 through n) whose name
you wish to have returned. This value
@@ -827,7 +826,7 @@
r"""
Return a string of dashes to the caller.
- Description of arguements:
+ Description of arguments:
indent The number of characters to indent the
output.
width The width of the string of dashes.
@@ -968,7 +967,7 @@
Description of arguments:
stack_frame_ix The index of the stack frame whose
function info should be returned. If the
- caller does not specifiy a value, this
+ caller does not specify a value, this
function will set the value to 1 which is
the index of the caller's stack frame. If
the caller is the wrapper function
@@ -1214,24 +1213,77 @@
###############################################################################
+def gp_debug_print(buffer):
+
+ r"""
+ Print buffer to stdout only if gen_print_debug is set.
+
+ This function is intended for use only by other functions in this module.
+
+ Description of arguments:
+ buffer The string to be printed.
+ """
+
+ if not gen_print_debug:
+ return
+
+ if robot_env:
+ BuiltIn().log_to_console(buffer)
+ else:
+ print(buffer)
+
+###############################################################################
+
+
+###############################################################################
+def gp_get_var_value(var_name,
+ default=1):
+
+ r"""
+ Get the value of the named variable and return it. If the variable is not
+ defined, the default value is returned.
+
+ If we are in a robot environment, get_variable_value will be used.
+ Otherwise, the __builtin__ version of the variable is returned.
+
+ This function is intended for use only by other functions in this module.
+
+ Description of arguments:
+ var_name The name of the variable whose value is to
+ be returned.
+ default The value that is returned if var_name is
+ not defined.
+ """
+
+ if robot_env:
+ var_value = int(BuiltIn().get_variable_value("${" + var_name + "}",
+ default))
+ else:
+ var_value = getattr(__builtin__, var_name, default)
+
+ return var_value
+
+###############################################################################
+
+
+###############################################################################
# In the following section of code, we will dynamically create print versions
# for each of the sprint functions defined above. So, for example, where we
# have an sprint_time() function defined above that returns the time to the
# caller in a string, we will create a corresponding print_time() function
# that will print that string directly to stdout.
-# It can be complicated to follow what's being creaed by the exec statement
+# It can be complicated to follow what's being created by the exec statements
# below. Here is an example of the print_time() function that will be created:
# def print_time(*args):
-# s_funcname = "s" + sys._getframe().f_code.co_name
-# s_func = getattr(sys.modules[__name__], s_funcname)
-# sys.stdout.write(s_func(*args))
+# s_func = getattr(sys.modules[__name__], "sprint_time")
+# sys.stdout.write(s_func(*args))
+# sys.stdout.flush()
# Here are comments describing the 3 lines in the body of the created function.
-# Calculate the "s" version of this function name (e.g. if this function name
-# is print_time, we want s_funcname to be "sprint_time".
-# Put a reference to the "s" version of this function in s_func.
+# Create a reference to the "s" version of the given function in s_func (e.g.
+# if this function name is print_time, we want s_funcname to be "sprint_time").
# Call the "s" version of this function passing it all of our arguments.
# Write the result to stdout.
@@ -1243,111 +1295,88 @@
'print_pgm_header', 'print_issuing', 'print_pgm_footer',
'print_error_report', 'print', 'printn']
-for func_name in func_names:
- if func_name == "print":
- continue
- # Create abbreviated aliases (e.g. spvar is an alias for sprint_var).
- alias = re.sub("print_", "p", func_name)
- pgm_definition_string = "s" + alias + " = s" + func_name
- if gen_print_debug:
- print(pgm_definition_string)
- exec(pgm_definition_string)
+# stderr_func_names is a list of functions whose output should go to stderr
+# rather than stdout.
+stderr_func_names = ['print_error', 'print_error_report']
+gp_debug_print("robot_env: " + str(robot_env))
for func_name in func_names:
- if func_name == "print_error" or func_name == "print_error_report":
+ gp_debug_print("func_name: " + func_name)
+ if func_name in stderr_func_names:
output_stream = "stderr"
else:
output_stream = "stdout"
- func_def = \
- [
- "def " + func_name + "(*args):",
- " s_func_name = \"s\" + sys._getframe().f_code.co_name",
- " s_func = getattr(sys.modules[__name__], s_func_name)",
- " sys." + output_stream + ".write(s_func(*args))",
- " sys." + output_stream + ".flush()"
- ]
+
+ func_def_line = "def " + func_name + "(*args):"
+ s_func_line = " s_func = getattr(sys.modules[__name__], \"s" +\
+ func_name + "\")"
+ # Generate the code to do the printing.
+ if robot_env:
+ func_print_lines = \
+ [
+ " BuiltIn().log_to_console(s_func(*args),"
+ " stream='" + output_stream + "',"
+ " no_newline=True)"
+ ]
+ else:
+ func_print_lines = \
+ [
+ " sys." + output_stream + ".write(s_func(*args))",
+ " sys." + output_stream + ".flush()"
+ ]
+
+ # Create an array containing the lines of the function we wish to create.
+ func_def = [func_def_line, s_func_line] + func_print_lines
+ # We don't want to try to redefine the "print" function, thus the if
+ # statement.
if func_name != "print":
pgm_definition_string = '\n'.join(func_def)
- if gen_print_debug:
- print(pgm_definition_string)
+ gp_debug_print(pgm_definition_string)
exec(pgm_definition_string)
- # Now define "q" versions of each print function.
- func_def = \
- [
- "def q" + func_name + "(*args):",
- " if __builtin__.quiet: return",
- " s_func_name = \"s" + func_name + "\"",
- " s_func = getattr(sys.modules[__name__], s_func_name)",
- " sys." + output_stream + ".write(s_func(*args))",
- " sys." + output_stream + ".flush()"
- ]
+ # Insert a blank line which will be overwritten by the next several
+ # definitions.
+ func_def.insert(1, "")
+ # Define the "q" (i.e. quiet) version of the given print function.
+ func_def[0] = "def q" + func_name + "(*args):"
+ func_def[1] = " if gp_get_var_value(\"quiet\", 0): return"
pgm_definition_string = '\n'.join(func_def)
- if gen_print_debug:
- print(pgm_definition_string)
+ gp_debug_print(pgm_definition_string)
exec(pgm_definition_string)
- # Now define "d" versions of each print function.
- func_def = \
- [
- "def d" + func_name + "(*args):",
- " if not __builtin__.debug: return",
- " s_func_name = \"s" + func_name + "\"",
- " s_func = getattr(sys.modules[__name__], s_func_name)",
- " sys." + output_stream + ".write(s_func(*args))",
- " sys." + output_stream + ".flush()"
- ]
-
+ # Define the "d" (i.e. debug) version of the given print function.
+ func_def[0] = "def d" + func_name + "(*args):"
+ func_def[1] = " if not gp_get_var_value(\"debug\", 0): return"
pgm_definition_string = '\n'.join(func_def)
- if gen_print_debug:
- print(pgm_definition_string)
+ gp_debug_print(pgm_definition_string)
exec(pgm_definition_string)
- # Now define "l" versions of each print function.
- func_def = \
+ # Define the "l" (i.e. log) version of the given print function.
+ func_def_line = "def l" + func_name + "(*args):"
+ func_print_lines = \
[
- "def l" + func_name + "(*args):",
- " s_func_name = \"s" + func_name + "\"",
- " s_func = getattr(sys.modules[__name__], s_func_name)",
- " logging.log(getattr(logging, 'INFO'), s_func(*args))",
+ " logging.log(getattr(logging, 'INFO'), s_func(*args))"
]
+ func_def = [func_def_line, s_func_line] + func_print_lines
if func_name != "print_varx" and func_name != "print_var":
pgm_definition_string = '\n'.join(func_def)
- if gen_print_debug:
- print(pgm_definition_string)
+ gp_debug_print(pgm_definition_string)
exec(pgm_definition_string)
- if func_name == "print":
+ if func_name == "print" or func_name == "printn":
+ gp_debug_print("")
continue
- # Create abbreviated aliases (e.g. pvar is an alias for print_var).
+ # Create abbreviated aliases (e.g. spvar is an alias for sprint_var).
alias = re.sub("print_", "p", func_name)
- pgm_definition_string = alias + " = " + func_name
- if gen_print_debug:
- print(pgm_definition_string)
- exec(pgm_definition_string)
+ prefixes = ["", "s", "q", "d", "l"]
+ for prefix in prefixes:
+ pgm_definition_string = prefix + alias + " = " + prefix + func_name
+ gp_debug_print(pgm_definition_string)
+ exec(pgm_definition_string)
- # Create abbreviated aliases (e.g. qpvar is an alias for qprint_var).
- alias = re.sub("print_", "p", func_name)
- pgm_definition_string = "q" + alias + " = q" + func_name
- if gen_print_debug:
- print(pgm_definition_string)
- exec(pgm_definition_string)
-
- # Create abbreviated aliases (e.g. dpvar is an alias for dprint_var).
- alias = re.sub("print_", "p", func_name)
- pgm_definition_string = "d" + alias + " = d" + func_name
- if gen_print_debug:
- print(pgm_definition_string)
- exec(pgm_definition_string)
-
- # Create abbreviated aliases (e.g. lpvar is an alias for lprint_var).
- alias = re.sub("print_", "p", func_name)
- pgm_definition_string = "l" + alias + " = l" + func_name
- if gen_print_debug:
- print(pgm_definition_string)
- exec(pgm_definition_string)
+ gp_debug_print("")
###############################################################################