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