1#!/usr/bin/env python3 2 3r""" 4This module provides functions which are useful for writing python wrapper functions (i.e. in this context, a 5wrapper function is one whose aim is to call some other function on the caller's behalf but to provide some 6additional functionality over and above what the base function provides). 7""" 8 9 10def create_func_def_string( 11 base_func_name, wrap_func_name, func_body_template, replace_dict 12): 13 r""" 14 Create and return a complete function definition as a string. The caller may run "exec" on the resulting 15 string to create the desired function. 16 17 Description of argument(s): 18 base_func_name The name of the base function around which a wrapper is being created. 19 wrap_func_name The name of the wrapper function being created. 20 func_body_template A function body in the form of a list. Each list element represents one 21 line of a function This is a template in so far as text substitutions 22 will be done on it to arrive at a valid function definition. This 23 template should NOT contain the function definition line (e.g. "def 24 func1():"). create_func_def_string will pre-pend the definition line. 25 The template should also contain the text "<call_line>" which is to be 26 replaced by text which will call the base function with appropriate 27 arguments. 28 replace_dict A dictionary indicating additional text replacements to be done. For 29 example, if the template contains a "<sub1>" (be sure to include the 30 angle brackets), and the dictionary contains a key/value pair of 31 'sub1'/'replace1', then all instances of "<sub1>" will be replaced by 32 "replace1". 33 """ 34 35 # Create the initial function definition list as a copy of the template. 36 func_def = list(func_body_template) 37 func_def_line = "def " + wrap_func_name + "(*args, **kwargs):" 38 call_line = base_func_name + "(*args, **kwargs)" 39 # Insert the func_def_line composed by create_wrapper_def_and_call is the first list entry. 40 func_def.insert(0, func_def_line) 41 # Make sure the replace_dict has a 'call_line'/call_line pair so that any '<call_line>' text gets 42 # replaced as intended. 43 replace_dict["call_line"] = call_line 44 45 # Do the replacements. 46 for key, value in replace_dict.items(): 47 func_def = [w.replace("<" + key + ">", value) for w in func_def] 48 49 return "\n".join(func_def) + "\n" 50