Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2"""
3@file
4@brief Various function needed when using the windows used to ask for parameters
5"""
6import sys
7import re
8import inspect
9import datetime
10from pyquickhelper.loghelper.flog import guess_machine_parameter
13def get_function_list(module):
14 """
15 Extracts all functions in a module.
17 @param module a object module
18 @return the list of function included in a module, dictionary { name, object }
19 """
20 res = {}
21 d = module.__dict__
22 for k, v in d.items():
23 if isinstance(v, get_function_list.__class__):
24 res[k] = v
25 return res
28def has_unknown_parameters(func):
29 """
30 Returns True if the function contains a parameter like ``**params``.
32 @param func function
33 @return True if the function contains something like ``**params``
34 """
35 # de = func.__defaults__
36 # na = func.__code__.co_varnames
37 keys = inspect.signature(func)
38 return "**" in str(keys)
41def extract_function_information(function):
42 """
43 Extracts information about a function.
44 The function assumes all parameters receive a default value.
46 @param function function object
47 @return dictionary { info : value }
49 The returned dictionary will be composed as follows:
50 - name: name of the function
51 - nbpar: number of parameters
52 - param: list of parameters (dictionary) and their default value
53 - types: type of parameters (dictionary), if the default value does not exist,
54 the function will look in the help looking for the following:
55 @code
56 param name (type)
57 @endcode
58 - help: documentation of the function
59 - helpparam: help associated to each parameters (dictionary),
60 assuming they are described in the documentation using
61 the same format as this docstring
62 - module: module which defines the function
63 """
64 if function.__doc__ is None:
65 raise Exception("the function given to FrameFunction should be documented: help is displayed,"
66 " if you want parameter to be described, use javadoc format to do so: "
67 "@<tag> param_name param_meaning with tag=param")
69 res = dict()
70 res["name"] = function.__name__
71 nbp = function.__code__.co_argcount
72 par = function.__code__.co_varnames[:nbp]
73 res["nbpar"] = len(par)
74 defd = function.__defaults__ if function.__defaults__ is not None else []
75 dec = len(par) - len(defd)
77 typ = {}
78 p = {}
79 for pos, a in enumerate(par):
80 if a == 'fLOG':
81 continue
82 p2 = pos - dec
83 if p2 >= 0:
84 b = defd[p2]
85 typ[a] = b.__class__
86 else:
87 b = ""
88 typ[a] = None
89 if not a.startswith("_"):
90 p[a] = b
92 res["types"] = typ
93 res["param"] = p
94 res["help"] = function.__doc__
96 mod = function.__module__
97 mod = sys.modules.get(mod, None)
98 res["module"] = mod
100 regex = re.compile("@" + "param +([a-zA-Z0-9_]+) +(.+)")
101 alls = regex.findall(res["help"])
102 p = {}
103 for a, b in alls:
104 a = a.strip()
105 if a == "fLOG":
106 continue
107 p[a] = b.strip()
108 res["helpparam"] = p
110 reg = re.compile(
111 "@" + "param +([a-zA-Z_][a-zA-Z_0-9]*?) +[(]([a-zA-Z]+?)[)]")
112 alls = reg.findall(res["help"])
113 typ = {k: v for k, v in alls} # pylint: disable=R1721
114 keys = list(res["types"])
115 for a in keys:
116 b = res["types"][a]
117 if b is None or isinstance(None, b):
118 b = typ.get(a, None)
119 if b is not None:
120 if "|" in b:
121 e, ee = b.split("|")
122 e = eval(e)
123 ee = eval(ee)
124 res["types"][a] = lambda v, e=e, ee=ee: ee if (
125 len(v) == 0 or v == str(ee)) else e(v)
126 elif b == "datetime":
127 res["types"][a] = datetime.datetime
128 else:
129 res["types"][a] = eval(b)
131 # If no default value, we assume the type is str.
132 keys = list(res["types"])
133 for a in keys:
134 b = res["types"][a]
135 if b is None:
136 res[b] = str
138 return res
141def private_adjust_parameters(param):
142 """
143 Change the value of some parameters when they are NULL:
144 *user*. Changes the parameters inplace.
146 @param param list of parameters
147 """
148 res = guess_machine_parameter()
149 for k in param:
150 if param[k] is None and k.lower() in ["user", "username"]:
151 res[k] = res.get("USERNAME", res["USER"])
154def private_get_function(function_name):
155 """
156 Returns the function object from its name, the name
157 must contains a dot "." otherwise the function will assume
158 it is defined in module @see md default_functions.
160 @param function_name name of the function
161 @return object
162 """
163 if "." in function_name:
164 module = function_name.split(".")
165 name = module[-1]
166 fname = ".".join(module[:-1])
168 if fname in sys.modules:
169 mod = sys.modules[fname]
170 else:
171 mod = __import__(fname, globals(), locals(), [], 0)
173 if name not in mod.__dict__:
174 raise KeyError("module %s, function %s not in %s (path %s)" %
175 (module, name, str(mod.__dict__.keys()), mod.__file__))
176 return mod.__dict__[name]
177 else:
178 from .default_functions import file_grep, file_list, file_split, file_head, test_regular_expression
179 if function_name == "file_grep":
180 return file_grep
181 elif function_name == "file_list":
182 return file_list
183 elif function_name == "file_split":
184 return file_split
185 elif function_name == "file_head":
186 return file_head
187 elif function_name == "test_regular_expression":
188 return test_regular_expression
189 else:
190 raise NameError("unknown exception " + function_name)