blob: ebf4f611ed0b6aee3c62d649395f9460b1df3e85 [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
Michael Walsh264bc142017-11-13 11:18:12 -06002
3r"""
Michael Walsh410b1782019-10-22 15:56:18 -05004This 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).
Michael Walsh264bc142017-11-13 11:18:12 -06007"""
8
Michael Walsh264bc142017-11-13 11:18:12 -06009
Patrick Williams20f38712022-12-08 06:18:26 -060010def create_func_def_string(
11 base_func_name, wrap_func_name, func_body_template, replace_dict
12):
Michael Walsh264bc142017-11-13 11:18:12 -060013 r"""
Michael Walsh410b1782019-10-22 15:56:18 -050014 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.
Michael Walsh264bc142017-11-13 11:18:12 -060016
17 Description of argument(s):
Michael Walsh410b1782019-10-22 15:56:18 -050018 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".
Michael Walsh264bc142017-11-13 11:18:12 -060033 """
34
35 # Create the initial function definition list as a copy of the template.
36 func_def = list(func_body_template)
Michael Walsh0f8b6032020-02-14 15:24:21 -060037 func_def_line = "def " + wrap_func_name + "(*args, **kwargs):"
38 call_line = base_func_name + "(*args, **kwargs)"
Michael Walsh410b1782019-10-22 15:56:18 -050039 # Insert the func_def_line composed by create_wrapper_def_and_call is the first list entry.
Michael Walsh264bc142017-11-13 11:18:12 -060040 func_def.insert(0, func_def_line)
Michael Walsh410b1782019-10-22 15:56:18 -050041 # Make sure the replace_dict has a 'call_line'/call_line pair so that any '<call_line>' text gets
42 # replaced as intended.
Patrick Williams20f38712022-12-08 06:18:26 -060043 replace_dict["call_line"] = call_line
Michael Walsh264bc142017-11-13 11:18:12 -060044
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
Patrick Williams20f38712022-12-08 06:18:26 -060049 return "\n".join(func_def) + "\n"