corelp 1.0.28__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.
Files changed (48) hide show
  1. corelp/__init__.py +29 -0
  2. corelp/icon_pythonLP.ico +0 -0
  3. corelp/modules/Path_LP/Path.py +92 -0
  4. corelp/modules/Path_LP/__init__.py +0 -0
  5. corelp/modules/Path_LP/test_Path.py +37 -0
  6. corelp/modules/Section_LP/Section.py +176 -0
  7. corelp/modules/Section_LP/__init__.py +0 -0
  8. corelp/modules/Section_LP/test_Section.py +43 -0
  9. corelp/modules/__init__.py +0 -0
  10. corelp/modules/debug_LP/__init__.py +0 -0
  11. corelp/modules/debug_LP/debug.py +66 -0
  12. corelp/modules/debug_LP/test_debug.py +34 -0
  13. corelp/modules/folder_LP/__init__.py +0 -0
  14. corelp/modules/folder_LP/folder.py +96 -0
  15. corelp/modules/folder_LP/test_folder.py +43 -0
  16. corelp/modules/getmodule_LP/__init__.py +0 -0
  17. corelp/modules/getmodule_LP/getmodule.py +101 -0
  18. corelp/modules/kwargsself_LP/__init__.py +0 -0
  19. corelp/modules/kwargsself_LP/kwargsself.py +80 -0
  20. corelp/modules/kwargsself_LP/test_kwargsself.py +59 -0
  21. corelp/modules/main_LP/__init__.py +0 -0
  22. corelp/modules/main_LP/main.py +237 -0
  23. corelp/modules/main_LP/test_main.py +74 -0
  24. corelp/modules/print_LP/__init__.py +0 -0
  25. corelp/modules/print_LP/print.py +317 -0
  26. corelp/modules/print_LP/test_print.py +108 -0
  27. corelp/modules/prop_LP/__init__.py +0 -0
  28. corelp/modules/prop_LP/prop.py +134 -0
  29. corelp/modules/prop_LP/test_prop.py +104 -0
  30. corelp/modules/rfrom_LP/__init__.py +0 -0
  31. corelp/modules/rfrom_LP/rfrom.py +72 -0
  32. corelp/modules/rfrom_LP/test_rfrom.py +37 -0
  33. corelp/modules/selfkwargs_LP/__init__.py +0 -0
  34. corelp/modules/selfkwargs_LP/selfkwargs.py +51 -0
  35. corelp/modules/selfkwargs_LP/test_selfkwargs.py +41 -0
  36. corelp/modules/test_LP/__init__.py +0 -0
  37. corelp/modules/test_LP/test.py +61 -0
  38. corelp/modules/test_LP/test_test.py +33 -0
  39. corelp/modules/user_inputs_LP/__init__.py +0 -0
  40. corelp/modules/user_inputs_LP/test_user_inputs.py +45 -0
  41. corelp/modules/user_inputs_LP/user_inputs.py +81 -0
  42. corelp/modules.json +80 -0
  43. corelp/py.typed +0 -0
  44. corelp/scripts/__init__.py +0 -0
  45. corelp/scripts.json +1 -0
  46. corelp-1.0.28.dist-info/METADATA +41 -0
  47. corelp-1.0.28.dist-info/RECORD +48 -0
  48. corelp-1.0.28.dist-info/WHEEL +4 -0
@@ -0,0 +1,317 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2025-08-27
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : coreLP
7
+ # Module : print
8
+
9
+ """
10
+ This function overrides python built in print function to add functionnalities.
11
+ """
12
+
13
+
14
+
15
+ # %% Libraries
16
+
17
+
18
+
19
+ # %% Libraries
20
+ from corelp import prop
21
+ from dataclasses import dataclass, field
22
+ from datetime import datetime, timedelta
23
+ from rich import print as richprint
24
+ from rich.console import Console
25
+ from rich.theme import Theme
26
+ from rich.markdown import Markdown
27
+ from rich.traceback import Traceback
28
+ from rich.progress import (
29
+ Progress,
30
+ BarColumn,
31
+ TextColumn,
32
+ TaskProgressColumn,
33
+ TimeElapsedColumn,
34
+ TimeRemainingColumn,
35
+ ProgressColumn,
36
+ )
37
+ import traceback as tb_module
38
+ from time import perf_counter
39
+ from pathlib import Path
40
+ pyprint = print
41
+
42
+
43
+
44
+ # %% Class
45
+ @dataclass(slots=True, kw_only=True)
46
+ class Print() :
47
+ r"""
48
+ Enhanced replacement for the built-in :func:`print` function, adding muting,
49
+ logging, rich formatting, and progress utilities.
50
+
51
+ This class is callable and behaves like :func:`print`, with extra arguments.
52
+
53
+ Parameters
54
+ ----------
55
+ string : object
56
+ The object to print. Its :meth:`__str__` representation is used.
57
+ verbose : bool, optional
58
+ If ``True`` (default), printing is performed.
59
+ If ``False``, printing is skipped unless overridden.
60
+ return_string : bool, optional
61
+ If ``True``, return the processed string instead of ``None``.
62
+ file : str or pathlib.Path or None, optional
63
+ If provided, overrides the configured log file.
64
+ mode : {"w", "a"}, optional
65
+ File mode used when writing logs. Default is ``"a"``.
66
+ end : str, optional
67
+ End-of-line character(s). Defaults to ``"\n"``.
68
+ **kwargs :
69
+ Additional keyword arguments passed to :func:`print` or Rich's :func:`Console.print`.
70
+
71
+ Examples
72
+ --------
73
+ Basic usage::
74
+
75
+ >>> from corelp import print
76
+ >>> s = "Hello *world*!\nThis is a print **example**"
77
+ >>> print(s)
78
+
79
+ Muting::
80
+
81
+ >>> print.verbose = False
82
+ >>> print(s) # muted
83
+ >>> print(s, verbose=True) # forced printing
84
+ >>> print.verbose = True
85
+ >>> print(s) # prints again
86
+ >>> print(s, verbose=False) # forced mute
87
+
88
+ Access to underlying print functions::
89
+
90
+ >>> print.pyprint(s) # built-in print
91
+ >>> print.richprint(s) # rich.print
92
+ >>> print.print(s) # Console.print
93
+ >>> print.log(s) # Console.log
94
+
95
+ Logging::
96
+
97
+ >>> print.file = "log.txt"
98
+ >>> print("Hello") # also writes to file
99
+
100
+ Console styling::
101
+
102
+ >>> print.theme = {"success": "green"}
103
+ >>> print("Done!", style="success")
104
+ >>> try:
105
+ ... 1/0
106
+ ... except Exception:
107
+ ... print.error()
108
+ >>> print.export_html("log.html")
109
+
110
+ Progress / Clock::
111
+
112
+ >>> from time import sleep
113
+ >>> for i in print.clock(15, "Outer"):
114
+ ... for j in print.clock(10, "Inner"):
115
+ ... sleep(1)
116
+
117
+ Attributes
118
+ ----------
119
+ verbose : bool
120
+ Global muting switch.
121
+ pyprint : callable
122
+ Built-in Python :func:`print`.
123
+ richprint : callable
124
+ :mod:`rich` print function.
125
+ console : rich.console.Console
126
+ The Rich console instance used for styled printing.
127
+ file : pathlib.Path or None
128
+ Path to the log file.
129
+ progress : rich.progress.Progress
130
+ Active Rich progress manager.
131
+ bars : dict
132
+ Dictionary storing active progress bars.
133
+ theme : dict
134
+ Custom Rich style definitions.
135
+ """
136
+
137
+ # Main function
138
+ def __call__(self, string, verbose=None, *, return_string=False, file=None, mode='a', end='\n', **kwargs) :
139
+ # Muting
140
+ verbose = verbose if verbose is not None else self.verbose
141
+ if not verbose :
142
+ return None
143
+
144
+ # Printing markdown
145
+ string = str(string) + end
146
+ self.print(Markdown(string), **kwargs)
147
+
148
+ # Writting to file
149
+ file = file if file is not None else self.file
150
+ if file is not None :
151
+ with open(Path(file), mode) as file :
152
+ file.write(string)
153
+
154
+ # Return
155
+ if return_string :
156
+ return string
157
+
158
+
159
+ # MUTING
160
+ verbose : bool = True # True to print
161
+
162
+
163
+
164
+ # PRINT
165
+
166
+ @property
167
+ def print(self) :
168
+ return self.console.print
169
+ @property
170
+ def log(self) :
171
+ return self.console.log
172
+ pyprint = pyprint # python print
173
+ richprint = richprint # rich print
174
+
175
+
176
+
177
+ # LOGGING
178
+
179
+ _file : Path = None
180
+ @property
181
+ def file(self) :
182
+ return self._file
183
+ @file.setter
184
+ def file(self, value) :
185
+ self._file = Path(value)
186
+
187
+
188
+
189
+ # CONSOLE
190
+
191
+ _theme = {}
192
+ @property
193
+ def theme(self) :
194
+ return self._theme
195
+ @theme.setter
196
+ def theme(self, value) :
197
+ self._theme.update(value)
198
+ self._console = None
199
+
200
+ _console : Console = field(default=None, repr=False)
201
+ @prop(cache=True)
202
+ def console(self) :
203
+ theme = Theme(self.theme)
204
+ return Console(theme=theme, record=True)
205
+
206
+ def error(self) :
207
+ rich_tb = Traceback.from_exception(*tb_module.sys.exc_info())
208
+ self.console.print(rich_tb)
209
+
210
+ def print_locals(self) :
211
+ self.console.log(log_locals=True)
212
+
213
+ def export_html(self, path) :
214
+ if path is None :
215
+ return
216
+ path = Path(path)
217
+ html_content = self.console.export_html(inline_styles=True)
218
+ with open(path, "w", encoding="utf-8") as file:
219
+ file.write(html_content)
220
+
221
+
222
+
223
+ # CLOCK
224
+
225
+ def clock(self, iterable, title="Working...") :
226
+
227
+ # Get iterable
228
+ iterable = range(iterable) if isinstance(iterable, int) else iterable
229
+ iterable = list(iterable)
230
+
231
+ # Detect if progressbar already exists
232
+ first_bar = getattr(self, "_progress", None) is None
233
+ progress = self.progress
234
+ bars = self.bars
235
+
236
+ # Opens progress
237
+ if first_bar :
238
+ verbose = self.verbose
239
+ self.verbose = False
240
+
241
+ # Write to file
242
+ if self.file is not None :
243
+ with open(Path(self.file), "a") as file :
244
+ file.write(f'{title}...\n')
245
+ progress.start()
246
+
247
+ # Create new task
248
+ task = bars.get(title, None)
249
+ if task is None : # No bar with this name exists
250
+ task = progress.add_task(title, total=len(iterable), avg_time=0.0)
251
+ bars[title] = task # store it
252
+ else :
253
+ progress.reset(task)
254
+
255
+ # Loop
256
+ loop_counter = 0
257
+ start = perf_counter()
258
+ for item in iterable :
259
+ yield item
260
+ loop_counter += 1
261
+ elapsed = perf_counter() - start
262
+ avg_time = elapsed / loop_counter if loop_counter else 0
263
+ progress.update(task, advance=1, avg_time=avg_time)
264
+
265
+ # Clean up
266
+ if first_bar :
267
+ progress.stop()
268
+ del(self.bars)
269
+ del(self.progress)
270
+ self.verbose = verbose
271
+
272
+ _progress : Progress = field(default=None, repr=False)
273
+ @prop(cache=True)
274
+ def progress(self) :
275
+ return Progress(
276
+ TextColumn("{task.description}"),
277
+ BarColumn(),
278
+ TaskProgressColumn(),
279
+ TextColumn("[magenta]/{task.total}[/]"),
280
+ TimeElapsedColumn(),
281
+ AvgLoopTimeColumn(),
282
+ TimeRemainingColumn(),
283
+ EndTimeColumn(),
284
+ transient=False
285
+ )
286
+
287
+ _bars : dict = field(default=None, repr=False)
288
+ @prop(cache=True)
289
+ def bars(self) :
290
+ return {}
291
+
292
+
293
+
294
+ # Get instance
295
+ print = Print() # Instance to use everywhere
296
+
297
+ # Custom Progress bar columns
298
+ class AvgLoopTimeColumn(ProgressColumn):
299
+ def render(self, task):
300
+ avg_time = task.fields.get("avg_time", None)
301
+ if avg_time is not None and task.completed > 0:
302
+ string = f"[yellow]↻ {avg_time:.2f}s[/]" if avg_time > 1 else f"[yellow]↻ {avg_time*1000:.2f}ms[/]"
303
+ return string
304
+ return ""
305
+ class EndTimeColumn(ProgressColumn):
306
+ def render(self, task):
307
+ if task.time_remaining is not None:
308
+ end_time = datetime.now() + timedelta(seconds=task.time_remaining)
309
+ return f"[cyan]{end_time:%m-%d %H:%M:%S}[/] "
310
+ return ""
311
+
312
+
313
+
314
+ # %% Test function run
315
+ if __name__ == "__main__":
316
+ from corelp import test
317
+ test(__file__)
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2025-08-27
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : coreLP
7
+ # Module : print
8
+
9
+ """
10
+ This file allows to test print
11
+
12
+ print : This function overrides python built in print function to add functionnalities.
13
+ """
14
+
15
+
16
+
17
+ # %% Libraries
18
+ from corelp import print, debug
19
+ import pytest
20
+ from time import sleep
21
+ debug_folder = debug(__file__)
22
+
23
+
24
+ # %% test prints
25
+ def test_print() :
26
+ '''
27
+ Test print
28
+ '''
29
+ string = "# TEST\nHello *world*!\n\nThis is 1 print **example**"
30
+ print(string, style="magenta")
31
+ print.print(string, style="magenta")
32
+ print.log(string, style="magenta")
33
+ print.pyprint(string)
34
+ print.richprint(string)
35
+
36
+
37
+
38
+ # %% test verbose
39
+ def test_verbose() :
40
+ '''
41
+ Test verbose
42
+ '''
43
+ print.verbose = False # Muting
44
+ print("Should not print") # Does not print
45
+ print("Should print", verbose=True) # Does print
46
+ print("Should not print") # Does not print
47
+ print.verbose = True # Unmuting
48
+ print("Should print") # Does print
49
+ print("Should not print", verbose=False) # Does not print
50
+ print("Should print") # Does print
51
+
52
+
53
+
54
+ # %% test logging
55
+ def test_logging() :
56
+ '''
57
+ Test logging
58
+ '''
59
+ print.theme = {"success" : "green"}
60
+ string = "# TEST\nHello *world*!\n\nThis is 1 print **example**"
61
+ print(string, style="success")
62
+ print.print_locals()
63
+ try :
64
+ 1/0
65
+ except Exception :
66
+ print.error()
67
+ file = debug_folder / "log.html"
68
+ print.export_html(file)
69
+
70
+
71
+
72
+ # %% test console
73
+ def test_console() :
74
+ '''
75
+ Test console
76
+ '''
77
+ file = debug_folder / 'log.md'
78
+ print.file = file
79
+ string = "# TEST\nHello *world*!\n\nThis is 1 print **example**"
80
+ print(string, style="magenta")
81
+ assert file.exists()
82
+
83
+
84
+
85
+ # %% test clock
86
+ def test_clock() :
87
+ '''
88
+ Test clock
89
+ '''
90
+ for i in print.clock(5, "Outer loop") :
91
+ print("Should not print")
92
+ for j in print.clock(5, "Inner loop") :
93
+ sleep(1)
94
+ print("Should not print")
95
+
96
+ for i in print.clock(10, "Other loop") :
97
+ sleep(1)
98
+ print("Should not print")
99
+
100
+
101
+
102
+
103
+
104
+
105
+ # %% Test function run
106
+ if __name__ == "__main__":
107
+ from corelp import test
108
+ test(__file__)
File without changes
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2025-08-25
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : coreLP
7
+ # Module : prop
8
+
9
+ """
10
+ This function serves as an improved property decorator.
11
+ """
12
+
13
+
14
+
15
+ # %% Function
16
+ def prop(*, cache=False, variable=False, link=None) :
17
+ '''
18
+ This function serves as an improved property decorator.
19
+ By default, calls the function as a normal property.
20
+ However if the readonly attribute of same name (starting with "_") exists and is not None, it returns this value.
21
+ This function can also be used to link the property to another object attribute, then the return value should be this linked name.
22
+
23
+ Parameters
24
+ ----------
25
+ cache : bool
26
+ True to set readonly attribute at first call.
27
+ variable : bool
28
+ True to create a getter that will always use the _attr as a variable. [defines only setter, getter is normal]
29
+ link : bool
30
+ True to link property to another object attribute.
31
+
32
+ Returns
33
+ -------
34
+ decorator : property
35
+ This is the decorator to apply.
36
+
37
+ Examples
38
+ --------
39
+ >>> from corelp import prop
40
+ ...
41
+ >>> class MyClass :
42
+ ...
43
+ ... # Set default value
44
+ ... @prop()
45
+ ... def defaultattr(self) :
46
+ ... return "MyDefaultValue" # --> is overriden if "_defaultattr" exists
47
+ ...
48
+ ... # Set initialization value
49
+ ... @prop(cache=True)
50
+ ... def cachedattr(self) :
51
+ ... return "MyCachedValue" # --> called once and cached in "_cachedattr"
52
+ ...
53
+ ...
54
+ ...
55
+ >>> instance = MyClass() # Creates instance of MyClass
56
+ >>> class MyTwin :
57
+ ...
58
+ ... # The following properties do the same thing
59
+ ...
60
+ ... mytwin = instance
61
+ ... # Links on attribute name
62
+ ... @prop(link="mytwin") # --> links to self.mytwin
63
+ ... def attrlink(self) :
64
+ ... return "defaultattr" # --> calls the "defaultattr" attribute of the linked object
65
+ ...
66
+ ... # Links on object
67
+ ... @prop(link=instance) # --> links to an object
68
+ ... def objectlink(self) :
69
+ ... return "defaultattr" # --> calls the "defaultattr" attribute of the linked object
70
+ '''
71
+
72
+ if link is not None :
73
+ return linkproperty(link)
74
+ return defaultproperty(cache, variable)
75
+
76
+
77
+
78
+ def defaultproperty(cache, variable):
79
+ def decorator(func) :
80
+ attribut = func.__name__
81
+
82
+ def getter(self):
83
+ _attribut = getattr(self, f'_{attribut}',None)
84
+ if _attribut is not None and not variable :
85
+ return _attribut
86
+ result = func(self)
87
+ if cache :
88
+ setattr(self, f'_{attribut}', result)
89
+ return result
90
+
91
+ def setter(self, value):
92
+ setattr(self, f'_{attribut}', value)
93
+
94
+ def deleter(self):
95
+ setattr(self, f'_{attribut}', None)
96
+
97
+ prop = property(getter, setter, deleter)
98
+
99
+ return prop
100
+ return decorator
101
+
102
+
103
+
104
+ def linkproperty(link):
105
+ def decorator(func) :
106
+ attribut = func.__name__
107
+
108
+ def getter(self):
109
+ obj = getattr(self, link) if isinstance(link, str) else link
110
+ if obj is None : # If link failed, uses default _attribut
111
+ return getattr(self, attribut, None)
112
+ else :
113
+ obj_attribut = func(self)
114
+ return getattr(obj, f'{obj_attribut}')
115
+
116
+ def setter(self, value):
117
+ obj = getattr(self, link) if isinstance(link, str) else link
118
+ if obj is None : # If link failed, uses default _attribut
119
+ setattr(self, f'_{attribut}', value)
120
+ else :
121
+ obj_attribut = func(self)
122
+ setattr(obj, f'{obj_attribut}', value)
123
+
124
+ prop = property(getter, setter)
125
+
126
+ return prop
127
+ return decorator
128
+
129
+
130
+
131
+ # %% Test function run
132
+ if __name__ == "__main__":
133
+ from corelp import test
134
+ test(__file__)
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2025-08-25
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : coreLP
7
+ # Module : prop
8
+
9
+ """
10
+ This file allows to test prop
11
+
12
+ prop : This function serves as an improved property decorator.
13
+ """
14
+
15
+
16
+
17
+ # %% Libraries
18
+ from corelp import debug, prop
19
+ import pytest
20
+ debug_folder = debug(__file__)
21
+
22
+
23
+
24
+ # %% testclass
25
+ class MyClass :
26
+ # Set default value
27
+ @prop()
28
+ def defaultattr(self) :
29
+ return "MyDefaultValue" # --> is overriden if "_defaultattr" exists
30
+
31
+ # Set initialization value
32
+ @prop(cache=True)
33
+ def cachedattr(self) :
34
+ return "MyCachedValue" # --> called once and cached in "_cachedattr"
35
+
36
+
37
+
38
+ class MyTwin :
39
+ def __init__(self, twin) :
40
+ self.mytwin = twin
41
+
42
+ # Links on attribute name
43
+ @prop(link="mytwin") # --> links to self.mytwin
44
+ def attrlink(self) :
45
+ return "defaultattr" # --> calls the "defaultattr" attribute of the linked object
46
+
47
+
48
+
49
+ # %% Instance fixture
50
+ @pytest.fixture()
51
+ def instance() :
52
+ '''
53
+ Create a new instance at each test function
54
+ '''
55
+
56
+ instance = MyClass()
57
+ return instance, MyTwin(instance)
58
+
59
+
60
+
61
+ # %% Default values test
62
+ def test_default(instance) :
63
+ '''
64
+ Test default values
65
+ '''
66
+ person, twin = instance
67
+ assert person.defaultattr == "MyDefaultValue"
68
+ person.defaultattr = "NotMyDefaultValue"
69
+ assert person.defaultattr == "NotMyDefaultValue"
70
+ assert person._defaultattr == "NotMyDefaultValue"
71
+
72
+
73
+
74
+ # %% Default values cached
75
+ def test_cached(instance) :
76
+ '''
77
+ Test default values
78
+ '''
79
+ person, twin = instance
80
+ assert getattr(person, "_cachedattr", None) is None
81
+ assert person.cachedattr == "MyCachedValue"
82
+ assert person._cachedattr == "MyCachedValue"
83
+ assert person.cachedattr == "MyCachedValue"
84
+
85
+
86
+
87
+ # %% Link values test
88
+ def test_link(instance) :
89
+ '''
90
+ Test link values
91
+ '''
92
+ person, twin = instance
93
+ assert person.defaultattr == "MyDefaultValue"
94
+ assert twin.attrlink == "MyDefaultValue"
95
+ twin.attrlink = "MyLinkedValue"
96
+ assert person.defaultattr == "MyLinkedValue"
97
+ assert twin.attrlink == "MyLinkedValue"
98
+
99
+
100
+
101
+ # %% Test function run
102
+ if __name__ == "__main__":
103
+ from corelp import test
104
+ test(__file__)
File without changes