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 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