gsplot 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gsplot/__init__.py +98 -0
- gsplot/base/base.py +518 -0
- gsplot/base/base_alias_validator.py +155 -0
- gsplot/color/colormap.py +218 -0
- gsplot/config/config.py +422 -0
- gsplot/data/load_file.py +188 -0
- gsplot/figure/axes.py +361 -0
- gsplot/figure/axes_base.py +952 -0
- gsplot/figure/figure_tools.py +66 -0
- gsplot/figure/show.py +205 -0
- gsplot/figure/store.py +119 -0
- gsplot/hello_world/hello_world.py +23 -0
- gsplot/logger.py +155 -0
- gsplot/path/path.py +227 -0
- gsplot/plot/line.py +328 -0
- gsplot/plot/line_base.py +272 -0
- gsplot/plot/line_colormap_base.py +120 -0
- gsplot/plot/line_colormap_dashed.py +540 -0
- gsplot/plot/line_colormap_solid.py +289 -0
- gsplot/plot/scatter.py +228 -0
- gsplot/plot/scatter_colormap.py +296 -0
- gsplot/style/graph.py +466 -0
- gsplot/style/label.py +866 -0
- gsplot/style/legend.py +469 -0
- gsplot/style/legend_colormap.py +381 -0
- gsplot/style/ticks.py +167 -0
- gsplot/version.py +2 -0
- gsplot-0.0.1.dist-info/LICENSE +21 -0
- gsplot-0.0.1.dist-info/METADATA +82 -0
- gsplot-0.0.1.dist-info/RECORD +31 -0
- gsplot-0.0.1.dist-info/WHEEL +4 -0
gsplot/__init__.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from .color.colormap import get_cmap
|
|
2
|
+
from .config.config import (Config, config_dict, config_entry_option,
|
|
3
|
+
config_load)
|
|
4
|
+
from .data.load_file import load_file
|
|
5
|
+
from .figure.axes import axes
|
|
6
|
+
from .figure.figure_tools import get_figure_size
|
|
7
|
+
from .figure.show import show
|
|
8
|
+
from .hello_world.hello_world import hello_world
|
|
9
|
+
from .logger import logger
|
|
10
|
+
from .path.path import home, pwd, pwd_main, pwd_move
|
|
11
|
+
from .plot.line import line
|
|
12
|
+
from .plot.line_colormap_dashed import line_colormap_dashed
|
|
13
|
+
from .plot.line_colormap_solid import line_colormap_solid
|
|
14
|
+
from .plot.scatter import scatter
|
|
15
|
+
from .plot.scatter_colormap import scatter_colormap
|
|
16
|
+
from .style.graph import (graph_facecolor, graph_square, graph_square_axes,
|
|
17
|
+
graph_transparent, graph_transparent_axes,
|
|
18
|
+
graph_white, graph_white_axes)
|
|
19
|
+
from .style.label import label, label_add_index
|
|
20
|
+
from .style.legend import (legend, legend_axes, legend_get_handlers,
|
|
21
|
+
legend_handlers, legend_reverse)
|
|
22
|
+
from .style.legend_colormap import legend_colormap
|
|
23
|
+
from .style.ticks import ticks_off, ticks_on, ticks_on_axes
|
|
24
|
+
from .version import __commit__, __version__
|
|
25
|
+
|
|
26
|
+
# ╭──────────────────────────────────────────────────────────╮
|
|
27
|
+
# │ Load the configuration file │
|
|
28
|
+
# ╰──────────────────────────────────────────────────────────╯
|
|
29
|
+
Config()
|
|
30
|
+
|
|
31
|
+
# ╭──────────────────────────────────────────────────────────╮
|
|
32
|
+
# │ Logging setup │
|
|
33
|
+
# ╰──────────────────────────────────────────────────────────╯
|
|
34
|
+
logger()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
__version__ = __version__
|
|
38
|
+
__commit__ = __commit__
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
__all__ = [
|
|
42
|
+
# color/colormap.py
|
|
43
|
+
"get_cmap",
|
|
44
|
+
# data/load_file.py
|
|
45
|
+
"load_file",
|
|
46
|
+
# figure/axes.py
|
|
47
|
+
"axes",
|
|
48
|
+
# figure/figure_tools.py
|
|
49
|
+
"get_figure_size",
|
|
50
|
+
# figure/show.py
|
|
51
|
+
"show",
|
|
52
|
+
# hello_world.py
|
|
53
|
+
"hello_world",
|
|
54
|
+
# config/config.py
|
|
55
|
+
"config_load",
|
|
56
|
+
"config_dict",
|
|
57
|
+
"config_entry_option",
|
|
58
|
+
# path/path.py
|
|
59
|
+
"home",
|
|
60
|
+
"pwd",
|
|
61
|
+
"pwd_move",
|
|
62
|
+
"pwd_main",
|
|
63
|
+
# plot/line.py
|
|
64
|
+
"line",
|
|
65
|
+
# plot/line_colormap.py
|
|
66
|
+
"line_colormap",
|
|
67
|
+
# plot/line_colormap_solid.py
|
|
68
|
+
"line_colormap_solid",
|
|
69
|
+
# plot/line_colormap_dashed.py
|
|
70
|
+
"line_colormap_dashed",
|
|
71
|
+
# plot/scatter.py
|
|
72
|
+
"scatter",
|
|
73
|
+
# plot/scatter_colormap.py
|
|
74
|
+
"scatter_colormap",
|
|
75
|
+
# style/graph.py
|
|
76
|
+
"graph_square",
|
|
77
|
+
"graph_square_axes",
|
|
78
|
+
"graph_white",
|
|
79
|
+
"graph_white_axes",
|
|
80
|
+
"graph_transparent",
|
|
81
|
+
"graph_transparent_axes",
|
|
82
|
+
"graph_facecolor",
|
|
83
|
+
# style/label.py
|
|
84
|
+
"label",
|
|
85
|
+
"label_add_index",
|
|
86
|
+
# style/legend.py
|
|
87
|
+
"legend",
|
|
88
|
+
"legend_axes",
|
|
89
|
+
"legend_handlers",
|
|
90
|
+
"legend_reverse",
|
|
91
|
+
"legend_get_handlers",
|
|
92
|
+
# style/legend_colormap.py
|
|
93
|
+
"legend_colormap",
|
|
94
|
+
# style/ticks.py
|
|
95
|
+
"ticks_off",
|
|
96
|
+
"ticks_on",
|
|
97
|
+
"ticks_on_axes",
|
|
98
|
+
]
|
gsplot/base/base.py
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from functools import wraps
|
|
3
|
+
from typing import Any, Callable
|
|
4
|
+
|
|
5
|
+
from ..config.config import Config
|
|
6
|
+
|
|
7
|
+
__all__: list[str] = []
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GetPassedParams:
|
|
11
|
+
"""
|
|
12
|
+
A utility class to capture and process the arguments passed to a function.
|
|
13
|
+
|
|
14
|
+
This class binds the provided arguments and keyword arguments to the
|
|
15
|
+
signature of the target function, identifies explicitly passed arguments,
|
|
16
|
+
and separates them from default values.
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
--------------------
|
|
20
|
+
func : Callable
|
|
21
|
+
The target function whose parameters are to be captured and processed.
|
|
22
|
+
*args : tuple
|
|
23
|
+
Positional arguments passed to the target function.
|
|
24
|
+
**kwargs : dict
|
|
25
|
+
Keyword arguments passed to the target function.
|
|
26
|
+
|
|
27
|
+
Attributes
|
|
28
|
+
--------------------
|
|
29
|
+
func : Callable
|
|
30
|
+
The target function whose parameters are being analyzed.
|
|
31
|
+
passed_params : dict of str, Any
|
|
32
|
+
A dictionary containing explicitly passed arguments and keyword arguments.
|
|
33
|
+
args : Any
|
|
34
|
+
Positional arguments passed to the target function.
|
|
35
|
+
kwargs : Any
|
|
36
|
+
Keyword arguments passed to the target function.
|
|
37
|
+
sig : inspect.Signature
|
|
38
|
+
The signature of the target function.
|
|
39
|
+
|
|
40
|
+
Methods
|
|
41
|
+
--------------------
|
|
42
|
+
count_default_params(bound_arguments)
|
|
43
|
+
Counts the number of arguments that have default values.
|
|
44
|
+
create_passed_args(bound_arguments)
|
|
45
|
+
Creates a dictionary of explicitly passed positional arguments.
|
|
46
|
+
crete_passed_kwargs(bound_arguments)
|
|
47
|
+
Creates a dictionary of explicitly passed keyword arguments.
|
|
48
|
+
get_passed_params()
|
|
49
|
+
Binds the arguments to the function's signature and retrieves explicitly passed parameters.
|
|
50
|
+
|
|
51
|
+
Examples
|
|
52
|
+
--------------------
|
|
53
|
+
>>> def example_function(a, b=2, *args, **kwargs):
|
|
54
|
+
... pass
|
|
55
|
+
>>> obj = GetPassedParams(example_function, 1, 3, c=4)
|
|
56
|
+
>>> params = obj.get_passed_params()
|
|
57
|
+
>>> print(params)
|
|
58
|
+
{'a': 1, 'args': [3], 'kwargs': {'c': 4}}
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
def __init__(self, func: Callable, *args: Any, **kwargs: Any) -> None:
|
|
62
|
+
self.func: Callable = func
|
|
63
|
+
self.passed_params: dict[str, Any] = {}
|
|
64
|
+
self.args: Any = args
|
|
65
|
+
self.kwargs: Any = kwargs
|
|
66
|
+
|
|
67
|
+
def count_default_params(self, bound_arguments: dict[str, Any]) -> int:
|
|
68
|
+
"""
|
|
69
|
+
Counts the number of arguments with default values in the bound arguments.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
--------------------
|
|
73
|
+
bound_arguments : dict of str, Any
|
|
74
|
+
The arguments bound to the function's signature.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
--------------------
|
|
78
|
+
int
|
|
79
|
+
The count of arguments with default values.
|
|
80
|
+
"""
|
|
81
|
+
filtered_bound_arguments = {
|
|
82
|
+
k: v for k, v in bound_arguments.items() if k not in ["args", "kwargs"]
|
|
83
|
+
}
|
|
84
|
+
return len(filtered_bound_arguments)
|
|
85
|
+
|
|
86
|
+
def create_passed_args(self, bound_arguments: dict[str, Any]) -> dict[str, Any]:
|
|
87
|
+
"""
|
|
88
|
+
Creates a dictionary of explicitly passed positional arguments.
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
--------------------
|
|
92
|
+
bound_arguments : dict of str, Any
|
|
93
|
+
The arguments bound to the function's signature.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
--------------------
|
|
97
|
+
dict of str, Any
|
|
98
|
+
A dictionary containing the explicitly passed positional arguments.
|
|
99
|
+
"""
|
|
100
|
+
args_len = len(self.args)
|
|
101
|
+
default_params_len = self.count_default_params(bound_arguments)
|
|
102
|
+
# directly iterate over dictionary items without kwargs key
|
|
103
|
+
passed_args = {
|
|
104
|
+
k: v
|
|
105
|
+
for i, (k, v) in enumerate(bound_arguments.items())
|
|
106
|
+
if i < args_len and i < default_params_len
|
|
107
|
+
}
|
|
108
|
+
passed_args["args"] = bound_arguments.get("args", [])
|
|
109
|
+
return passed_args
|
|
110
|
+
|
|
111
|
+
def crete_passed_kwargs(self, bound_arguments: dict[str, Any]) -> dict[str, Any]:
|
|
112
|
+
"""
|
|
113
|
+
Creates a dictionary of explicitly passed keyword arguments.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
--------------------
|
|
117
|
+
bound_arguments : dict of str, Any
|
|
118
|
+
The arguments bound to the function's signature.
|
|
119
|
+
|
|
120
|
+
Returns
|
|
121
|
+
--------------------
|
|
122
|
+
dict of str, Any
|
|
123
|
+
A dictionary containing the explicitly passed keyword arguments.
|
|
124
|
+
"""
|
|
125
|
+
passed_kwargs = {k: v for k, v in bound_arguments.items() if k in self.kwargs}
|
|
126
|
+
|
|
127
|
+
passed_kwargs["kwargs"] = bound_arguments.get("kwargs", {})
|
|
128
|
+
return passed_kwargs
|
|
129
|
+
|
|
130
|
+
def get_passed_params(self) -> dict[str, Any]:
|
|
131
|
+
"""
|
|
132
|
+
Retrieves the explicitly passed parameters after binding them to the function's signature.
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
--------------------
|
|
136
|
+
dict of str, Any
|
|
137
|
+
A dictionary containing the explicitly passed arguments and keyword arguments.
|
|
138
|
+
|
|
139
|
+
Examples
|
|
140
|
+
--------------------
|
|
141
|
+
>>> def example_function(a, b=2, *args, **kwargs):
|
|
142
|
+
... pass
|
|
143
|
+
>>> obj = GetPassedParams(example_function, 1, 3, c=4)
|
|
144
|
+
>>> params = obj.get_passed_params()
|
|
145
|
+
>>> print(params)
|
|
146
|
+
{'a': 1, 'args': [3], 'kwargs': {'c': 4}}
|
|
147
|
+
"""
|
|
148
|
+
sig = inspect.signature(self.func)
|
|
149
|
+
self.sig = sig
|
|
150
|
+
bound_args = sig.bind_partial(*self.args, **self.kwargs)
|
|
151
|
+
bound_args.apply_defaults()
|
|
152
|
+
|
|
153
|
+
bound_arguments = bound_args.arguments
|
|
154
|
+
|
|
155
|
+
passe_args = self.create_passed_args(bound_arguments)
|
|
156
|
+
passed_kwargs = self.crete_passed_kwargs(bound_arguments)
|
|
157
|
+
|
|
158
|
+
passed_params = {**passe_args, **passed_kwargs}
|
|
159
|
+
|
|
160
|
+
self.passed_params = passed_params
|
|
161
|
+
return self.passed_params
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class CreateClassParams:
|
|
165
|
+
"""
|
|
166
|
+
A utility class to construct parameters for a class by combining default parameters,
|
|
167
|
+
configuration entries, and explicitly passed parameters.
|
|
168
|
+
|
|
169
|
+
Parameters
|
|
170
|
+
--------------------
|
|
171
|
+
passed_params : dict of str, Any
|
|
172
|
+
The explicitly passed parameters.
|
|
173
|
+
|
|
174
|
+
Attributes
|
|
175
|
+
--------------------
|
|
176
|
+
passed_params : dict of str, Any
|
|
177
|
+
The explicitly passed parameters.
|
|
178
|
+
wrapped_func_frame : frame
|
|
179
|
+
The frame of the wrapped function.
|
|
180
|
+
wrapped_func_name : str
|
|
181
|
+
The name of the wrapped function.
|
|
182
|
+
wrapped_func : Callable
|
|
183
|
+
The wrapped function itself.
|
|
184
|
+
default_params : dict of str, Any
|
|
185
|
+
Default parameters extracted from the wrapped function's signature.
|
|
186
|
+
config_entry_params : dict of str, Any
|
|
187
|
+
Parameters from the configuration entry for the wrapped function.
|
|
188
|
+
|
|
189
|
+
Methods
|
|
190
|
+
--------------------
|
|
191
|
+
get_wrapped_func_frame()
|
|
192
|
+
Retrieves the frame of the wrapped function.
|
|
193
|
+
get_wrapped_func_name()
|
|
194
|
+
Retrieves the name of the wrapped function.
|
|
195
|
+
get_wrapped_func()
|
|
196
|
+
Retrieves the wrapped function.
|
|
197
|
+
get_default_params()
|
|
198
|
+
Extracts default parameters from the wrapped function's signature.
|
|
199
|
+
get_config_entry_params()
|
|
200
|
+
Retrieves parameters from the configuration entry corresponding to the wrapped function.
|
|
201
|
+
get_class_params()
|
|
202
|
+
Constructs the final parameters for the class by merging default, configuration, and passed parameters.
|
|
203
|
+
|
|
204
|
+
Examples
|
|
205
|
+
--------------------
|
|
206
|
+
>>> @bind_passed_params()
|
|
207
|
+
>>> def example_func(p1, p2, p3):
|
|
208
|
+
>>> passed_params: dict[str, Any] = ParamsGetter(
|
|
209
|
+
>>> "passed_params"
|
|
210
|
+
>>> ).get_bound_params()
|
|
211
|
+
>>> AliasValidator(alias_map, passed_params).validate()
|
|
212
|
+
>>> class_params: dict[str, Any] = CreateClassParams(passed_params).get_class_params()
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
def __init__(self, passed_params: dict[str, Any]) -> None:
|
|
216
|
+
self.passed_params: dict[str, Any] = passed_params
|
|
217
|
+
|
|
218
|
+
self.wrapped_func_frame = self.get_wrapped_func_frame()
|
|
219
|
+
self.wrapped_func_name: str = self.get_wrapped_func_name()
|
|
220
|
+
self.wrapped_func: Callable = self.get_wrapped_func()
|
|
221
|
+
|
|
222
|
+
self.default_params: dict[str, Any] = self.get_default_params()
|
|
223
|
+
self.config_entry_params: dict[str, Any] = self.get_config_entry_params()
|
|
224
|
+
|
|
225
|
+
def get_wrapped_func_frame(self):
|
|
226
|
+
"""
|
|
227
|
+
Retrieves the frame of the wrapped function.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
--------------------
|
|
231
|
+
frame
|
|
232
|
+
The frame of the wrapped function.
|
|
233
|
+
|
|
234
|
+
Raises
|
|
235
|
+
--------------------
|
|
236
|
+
Exception
|
|
237
|
+
If the current frame or its ancestors cannot be retrieved.
|
|
238
|
+
"""
|
|
239
|
+
current_frame = inspect.currentframe()
|
|
240
|
+
|
|
241
|
+
if (
|
|
242
|
+
not current_frame
|
|
243
|
+
or not current_frame.f_back
|
|
244
|
+
or not current_frame.f_back.f_back
|
|
245
|
+
):
|
|
246
|
+
raise Exception("Cannot get current frame")
|
|
247
|
+
|
|
248
|
+
wrapped_func_frame = current_frame.f_back.f_back
|
|
249
|
+
return wrapped_func_frame
|
|
250
|
+
|
|
251
|
+
def get_wrapped_func_name(self) -> Any:
|
|
252
|
+
"""
|
|
253
|
+
Retrieves the name of the wrapped function.
|
|
254
|
+
|
|
255
|
+
Returns
|
|
256
|
+
--------------------
|
|
257
|
+
str
|
|
258
|
+
The name of the wrapped function.
|
|
259
|
+
"""
|
|
260
|
+
wrapped_func_name = self.wrapped_func_frame.f_code.co_name
|
|
261
|
+
return wrapped_func_name
|
|
262
|
+
|
|
263
|
+
def get_wrapped_func(self) -> Any:
|
|
264
|
+
"""
|
|
265
|
+
Retrieves the wrapped function.
|
|
266
|
+
|
|
267
|
+
Returns
|
|
268
|
+
--------------------
|
|
269
|
+
Callable
|
|
270
|
+
The wrapped function.
|
|
271
|
+
"""
|
|
272
|
+
wrapped_func = self.wrapped_func_frame.f_globals[self.wrapped_func_name]
|
|
273
|
+
return wrapped_func
|
|
274
|
+
|
|
275
|
+
def get_default_params(self) -> dict[str, Any]:
|
|
276
|
+
"""
|
|
277
|
+
Extracts default parameters from the wrapped function's signature.
|
|
278
|
+
|
|
279
|
+
Returns
|
|
280
|
+
--------------------
|
|
281
|
+
dict of str, Any
|
|
282
|
+
A dictionary of default parameters.
|
|
283
|
+
"""
|
|
284
|
+
sig = inspect.signature(self.wrapped_func)
|
|
285
|
+
default_params = {
|
|
286
|
+
name: param.default
|
|
287
|
+
for name, param in sig.parameters.items()
|
|
288
|
+
if param.default is not inspect.Parameter.empty
|
|
289
|
+
}
|
|
290
|
+
return default_params
|
|
291
|
+
|
|
292
|
+
def get_config_entry_params(self) -> dict[str, Any]:
|
|
293
|
+
"""
|
|
294
|
+
Retrieves parameters from the configuration entry for the wrapped function.
|
|
295
|
+
|
|
296
|
+
Returns
|
|
297
|
+
--------------------
|
|
298
|
+
dict of str, Any
|
|
299
|
+
A dictionary of configuration entry parameters, with non-default
|
|
300
|
+
parameters grouped under a "kwargs" key.
|
|
301
|
+
"""
|
|
302
|
+
config_entry_option: dict[str, Any] = Config().get_config_entry_option(
|
|
303
|
+
self.wrapped_func_name
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
# decompose the config_entry_option following the structure of defaults_params
|
|
307
|
+
config_entry_params = {
|
|
308
|
+
key: config_entry_option[key]
|
|
309
|
+
for key in config_entry_option
|
|
310
|
+
if key in self.default_params
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
config_entry_params["kwargs"] = {
|
|
314
|
+
key: value
|
|
315
|
+
for key, value in config_entry_option.items()
|
|
316
|
+
if key not in self.default_params
|
|
317
|
+
}
|
|
318
|
+
return config_entry_params
|
|
319
|
+
|
|
320
|
+
def get_class_params(self) -> dict[str, Any]:
|
|
321
|
+
"""
|
|
322
|
+
Constructs the final parameters for the class by merging default parameters,
|
|
323
|
+
configuration entry parameters, and explicitly passed parameters.
|
|
324
|
+
|
|
325
|
+
Returns
|
|
326
|
+
--------------------
|
|
327
|
+
dict of str, Any
|
|
328
|
+
A dictionary of the final class parameters.
|
|
329
|
+
"""
|
|
330
|
+
defaults_params = self.default_params
|
|
331
|
+
config_entry_params = self.config_entry_params
|
|
332
|
+
passed_params = self.passed_params
|
|
333
|
+
|
|
334
|
+
class_params = {
|
|
335
|
+
**defaults_params,
|
|
336
|
+
**config_entry_params,
|
|
337
|
+
**passed_params,
|
|
338
|
+
}
|
|
339
|
+
class_params["kwargs"] = {
|
|
340
|
+
**config_entry_params.get("kwargs", {}),
|
|
341
|
+
**passed_params.get("kwargs", {}),
|
|
342
|
+
}
|
|
343
|
+
return class_params
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def bind_passed_params() -> Callable:
|
|
347
|
+
"""
|
|
348
|
+
A decorator to bind and store the parameters passed to a function call.
|
|
349
|
+
|
|
350
|
+
This decorator captures the parameters passed to the decorated function
|
|
351
|
+
(including positional arguments, keyword arguments, and their default values)
|
|
352
|
+
and attaches them to the decorated function as an attribute named `passed_params`.
|
|
353
|
+
|
|
354
|
+
Returns
|
|
355
|
+
--------------------
|
|
356
|
+
Callable
|
|
357
|
+
A decorator that wraps a function to capture its passed parameters.
|
|
358
|
+
|
|
359
|
+
Examples
|
|
360
|
+
--------------------
|
|
361
|
+
>>> @bind_passed_params()
|
|
362
|
+
>>> def example_func(p1, p2, p3):
|
|
363
|
+
>>> passed_params: dict[str, Any] = ParamsGetter(
|
|
364
|
+
>>> "passed_params"
|
|
365
|
+
>>> ).get_params_from_wrapper()
|
|
366
|
+
"""
|
|
367
|
+
|
|
368
|
+
def wrapped(func: Callable) -> Callable:
|
|
369
|
+
"""
|
|
370
|
+
Wraps the target function to capture passed parameters.
|
|
371
|
+
|
|
372
|
+
Parameters
|
|
373
|
+
--------------------
|
|
374
|
+
func : Callable
|
|
375
|
+
The function to be wrapped.
|
|
376
|
+
|
|
377
|
+
Returns
|
|
378
|
+
--------------------
|
|
379
|
+
Callable
|
|
380
|
+
The wrapped function with an attached `passed_params` attribute.
|
|
381
|
+
"""
|
|
382
|
+
|
|
383
|
+
@wraps(func)
|
|
384
|
+
def wrapper(*args, **kwargs) -> Any:
|
|
385
|
+
"""
|
|
386
|
+
Captures passed parameters and executes the original function.
|
|
387
|
+
|
|
388
|
+
Parameters
|
|
389
|
+
--------------------
|
|
390
|
+
*args : tuple
|
|
391
|
+
Positional arguments passed to the function.
|
|
392
|
+
**kwargs : dict
|
|
393
|
+
Keyword arguments passed to the function.
|
|
394
|
+
|
|
395
|
+
Returns
|
|
396
|
+
--------------------
|
|
397
|
+
Any
|
|
398
|
+
The result of the original function call.
|
|
399
|
+
"""
|
|
400
|
+
|
|
401
|
+
# get passed parameters from the function call wrapped by the decorator
|
|
402
|
+
passed_params = GetPassedParams(func, *args, **kwargs).get_passed_params()
|
|
403
|
+
setattr(wrapper, "passed_params", passed_params)
|
|
404
|
+
return func(*args, **kwargs)
|
|
405
|
+
|
|
406
|
+
return wrapper
|
|
407
|
+
|
|
408
|
+
return wrapped
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
class ParamsGetter:
|
|
412
|
+
"""
|
|
413
|
+
A utility class to retrieve bound parameters from a wrapped function.
|
|
414
|
+
|
|
415
|
+
This class accesses a specified attribute of a wrapped function and verifies
|
|
416
|
+
the parameters, ensuring they are not `None`.
|
|
417
|
+
|
|
418
|
+
Parameters
|
|
419
|
+
--------------------
|
|
420
|
+
var : str
|
|
421
|
+
The name of the attribute containing the parameters to retrieve.
|
|
422
|
+
|
|
423
|
+
Attributes
|
|
424
|
+
--------------------
|
|
425
|
+
var : str
|
|
426
|
+
The name of the target attribute in the wrapped function.
|
|
427
|
+
|
|
428
|
+
Methods
|
|
429
|
+
--------------------
|
|
430
|
+
get_wrapped_frame()
|
|
431
|
+
Retrieves the frame of the wrapped function.
|
|
432
|
+
verify(params)
|
|
433
|
+
Verifies that the provided parameters are not `None`.
|
|
434
|
+
get_bound_params()
|
|
435
|
+
Retrieves and verifies the bound parameters from the wrapped function.
|
|
436
|
+
|
|
437
|
+
Examples
|
|
438
|
+
--------------------
|
|
439
|
+
>>> @bind_passed_params()
|
|
440
|
+
>>> def example_func(p1, p2, p3):
|
|
441
|
+
>>> passed_params: dict[str, Any] = ParamsGetter(
|
|
442
|
+
>>> "passed_params"
|
|
443
|
+
>>> ).get_bound_params()
|
|
444
|
+
"""
|
|
445
|
+
|
|
446
|
+
def __init__(self, var: str) -> None:
|
|
447
|
+
self.var: str = var
|
|
448
|
+
|
|
449
|
+
def get_wrapped_frame(self):
|
|
450
|
+
"""
|
|
451
|
+
Retrieves the frame of the wrapped function.
|
|
452
|
+
|
|
453
|
+
Returns
|
|
454
|
+
--------------------
|
|
455
|
+
frame
|
|
456
|
+
The frame of the wrapped function.
|
|
457
|
+
|
|
458
|
+
Raises
|
|
459
|
+
--------------------
|
|
460
|
+
Exception
|
|
461
|
+
If the current frame or its ancestors cannot be retrieved.
|
|
462
|
+
"""
|
|
463
|
+
current_frame = inspect.currentframe()
|
|
464
|
+
if (
|
|
465
|
+
not current_frame
|
|
466
|
+
or not current_frame.f_back
|
|
467
|
+
or not current_frame.f_back.f_back
|
|
468
|
+
):
|
|
469
|
+
raise Exception("Cannot get current frame")
|
|
470
|
+
wrapped_frame = current_frame.f_back.f_back
|
|
471
|
+
return wrapped_frame
|
|
472
|
+
|
|
473
|
+
def verify(self, params: dict[str, Any] | None) -> dict[str, Any]:
|
|
474
|
+
"""
|
|
475
|
+
Verifies that the provided parameters are not `None`.
|
|
476
|
+
|
|
477
|
+
Parameters
|
|
478
|
+
--------------------
|
|
479
|
+
params : dict[str, Any] or None
|
|
480
|
+
The parameters to verify.
|
|
481
|
+
|
|
482
|
+
Returns
|
|
483
|
+
--------------------
|
|
484
|
+
dict[str, Any]
|
|
485
|
+
The verified parameters.
|
|
486
|
+
|
|
487
|
+
Raises
|
|
488
|
+
--------------------
|
|
489
|
+
ValueError
|
|
490
|
+
If the provided parameters are `None`.
|
|
491
|
+
"""
|
|
492
|
+
if params is None:
|
|
493
|
+
raise ValueError("Params is None")
|
|
494
|
+
return params
|
|
495
|
+
|
|
496
|
+
def get_bound_params(self) -> dict[str, Any]:
|
|
497
|
+
"""
|
|
498
|
+
Retrieves and verifies the bound parameters from the wrapped function.
|
|
499
|
+
|
|
500
|
+
Returns
|
|
501
|
+
--------------------
|
|
502
|
+
dict[str, Any]
|
|
503
|
+
The bound parameters retrieved from the wrapped function.
|
|
504
|
+
|
|
505
|
+
Raises
|
|
506
|
+
--------------------
|
|
507
|
+
ValueError
|
|
508
|
+
If the parameters are `None`.
|
|
509
|
+
Exception
|
|
510
|
+
If the wrapped function frame cannot be retrieved.
|
|
511
|
+
"""
|
|
512
|
+
wrapped_frame = self.get_wrapped_frame()
|
|
513
|
+
wrapped_func_name = wrapped_frame.f_code.co_name
|
|
514
|
+
func = wrapped_frame.f_globals[wrapped_func_name]
|
|
515
|
+
|
|
516
|
+
params: dict[str, Any] | None = getattr(func, self.var, None)
|
|
517
|
+
params = self.verify(params)
|
|
518
|
+
return params
|