stouputils 1.2.27__tar.gz → 1.2.29__tar.gz

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 (25) hide show
  1. {stouputils-1.2.27 → stouputils-1.2.29}/PKG-INFO +3 -2
  2. {stouputils-1.2.27 → stouputils-1.2.29}/README.md +2 -1
  3. {stouputils-1.2.27 → stouputils-1.2.29}/pyproject.toml +1 -1
  4. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/decorators.py +11 -6
  5. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/parallel.py +55 -16
  6. {stouputils-1.2.27 → stouputils-1.2.29}/.gitignore +0 -0
  7. {stouputils-1.2.27 → stouputils-1.2.29}/LICENSE +0 -0
  8. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/__init__.py +0 -0
  9. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/all_doctests.py +0 -0
  10. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/applications/__init__.py +0 -0
  11. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/applications/automatic_docs.py +0 -0
  12. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/archive.py +0 -0
  13. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/backup.py +0 -0
  14. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/collections.py +0 -0
  15. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/continuous_delivery/__init__.py +0 -0
  16. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/continuous_delivery/cd_utils.py +0 -0
  17. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/continuous_delivery/github.py +0 -0
  18. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/continuous_delivery/pypi.py +0 -0
  19. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/continuous_delivery/pyproject.py +0 -0
  20. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/ctx.py +0 -0
  21. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/dont_look/zip_file_override.py +0 -0
  22. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/image.py +0 -0
  23. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/io.py +0 -0
  24. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/print.py +0 -0
  25. {stouputils-1.2.27 → stouputils-1.2.29}/stouputils/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stouputils
3
- Version: 1.2.27
3
+ Version: 1.2.29
4
4
  Summary: Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more.
5
5
  Project-URL: Homepage, https://github.com/Stoupy51/stouputils
6
6
  Project-URL: Issues, https://github.com/Stoupy51/stouputils/issues
@@ -38,7 +38,7 @@ It includes a range of tools for tasks such as execution of doctests, display ut
38
38
 
39
39
 
40
40
  # 🚀 Project File Tree
41
-
41
+ <html>
42
42
  <style>
43
43
  .code-tree {
44
44
  border-radius: 6px;
@@ -86,6 +86,7 @@ It includes a range of tools for tasks such as execution of doctests, display ut
86
86
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.print.html">print.py</a> <span class="comment"># 🖨️ Display utilities (info, debug, warning, error)</span>
87
87
  └── ...
88
88
  </pre>
89
+ </html>
89
90
 
90
91
  ## ⭐ Star History
91
92
 
@@ -11,7 +11,7 @@ It includes a range of tools for tasks such as execution of doctests, display ut
11
11
 
12
12
 
13
13
  # 🚀 Project File Tree
14
-
14
+ <html>
15
15
  <style>
16
16
  .code-tree {
17
17
  border-radius: 6px;
@@ -59,6 +59,7 @@ It includes a range of tools for tasks such as execution of doctests, display ut
59
59
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.print.html">print.py</a> <span class="comment"># 🖨️ Display utilities (info, debug, warning, error)</span>
60
60
  └── ...
61
61
  </pre>
62
+ </html>
62
63
 
63
64
  ## ⭐ Star History
64
65
 
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
 
6
6
  [project]
7
7
  name = "stouputils"
8
- version = "1.2.27"
8
+ version = "1.2.29"
9
9
  description = "Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more."
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -25,6 +25,11 @@ from typing import Callable, Literal, Any
25
25
  from functools import wraps
26
26
  from .print import debug, warning, error
27
27
 
28
+ def get_func_name(func: Callable[..., Any]) -> str:
29
+ try:
30
+ return func.__name__
31
+ except:
32
+ return "<unknown>"
28
33
 
29
34
  # Decorator that make a function silent (disable stdout)
30
35
  def silent(
@@ -113,7 +118,7 @@ def measure_time(
113
118
  # Set the message if not specified
114
119
  nonlocal message
115
120
  if not message:
116
- message = f"Execution time of {func.__name__}"
121
+ message = f"Execution time of {get_func_name(func)}"
117
122
 
118
123
  @wraps(func)
119
124
  def wrapper(*args: tuple[Any, ...], **kwargs: dict[str, Any]) -> Any:
@@ -213,11 +218,11 @@ def handle_error(
213
218
  return func(*args, **kwargs)
214
219
  except exceptions as e:
215
220
  if error_log == LogLevels.WARNING:
216
- warning(f"{msg}Error during {func.__name__}: ({type(e).__name__}) {e}")
221
+ warning(f"{msg}Error during {get_func_name(func)}: ({type(e).__name__}) {e}")
217
222
  elif error_log == LogLevels.WARNING_TRACEBACK:
218
- warning(f"{msg}Error during {func.__name__}:\n{format_exc()}")
223
+ warning(f"{msg}Error during {get_func_name(func)}:\n{format_exc()}")
219
224
  elif error_log == LogLevels.ERROR_TRACEBACK:
220
- error(f"{msg}Error during {func.__name__}:\n{format_exc()}", exit=True)
225
+ error(f"{msg}Error during {get_func_name(func)}:\n{format_exc()}", exit=True)
221
226
  elif error_log == LogLevels.RAISE_EXCEPTION:
222
227
  raise e
223
228
  return wrapper
@@ -327,7 +332,7 @@ def deprecated(
327
332
  @wraps(func)
328
333
  def wrapper(*args: tuple[Any, ...], **kwargs: dict[str, Any]) -> Any:
329
334
  # Build deprecation message
330
- msg: str = f"Function '{func.__name__}()' is deprecated"
335
+ msg: str = f"Function '{get_func_name(func)}()' is deprecated"
331
336
  if message:
332
337
  msg += f". {message}"
333
338
 
@@ -385,7 +390,7 @@ def abstract(
385
390
  NotImplementedError: Function 'method' is abstract and must be implemented by a subclass
386
391
  """
387
392
  def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
388
- message: str = f"Function '{func.__name__}' is abstract and must be implemented by a subclass"
393
+ message: str = f"Function '{get_func_name(func)}' is abstract and must be implemented by a subclass"
389
394
  if not func.__doc__:
390
395
  func.__doc__ = message
391
396
 
@@ -12,7 +12,7 @@ I highly encourage you to read the function docstrings to understand when to use
12
12
 
13
13
  # Imports
14
14
  from .print import MAGENTA, RESET
15
- from .decorators import handle_error, LogLevels
15
+ from .decorators import handle_error, LogLevels, get_func_name
16
16
  from multiprocessing import Pool, cpu_count
17
17
  from typing import Callable, TypeVar
18
18
  from tqdm.auto import tqdm
@@ -50,7 +50,8 @@ def __handle_parameters(
50
50
  use_starmap: bool,
51
51
  delay_first_calls: float,
52
52
  max_workers: int,
53
- desc: str
53
+ desc: str,
54
+ color: str
54
55
  ) -> tuple[str, Callable[[T], R], list[T]]:
55
56
  r""" Private function to handle the parameters for multiprocessing or multithreading functions
56
57
 
@@ -61,12 +62,13 @@ def __handle_parameters(
61
62
  delay_first_calls (int): Apply i*delay_first_calls seconds delay to the first "max_workers" calls. For instance, the first process will be delayed by 0 seconds, the second by 1 second, etc. (Defaults to 0): This can be useful to avoid functions being called in the same second.
62
63
  max_workers (int): Number of workers to use (Defaults to CPU_COUNT)
63
64
  desc (str): Description of the function execution displayed in the progress bar
65
+ color (str): Color of the progress bar
64
66
  Returns:
65
67
  tuple[str, Callable[[T], R], list[T]]: Tuple containing the description, function, and arguments
66
68
  """
67
69
  if not desc:
68
- desc = func.__name__
69
- desc = MAGENTA + desc
70
+ desc = get_func_name(func)
71
+ desc = color + desc
70
72
 
71
73
  # If use_starmap is True, we use the __starmap function
72
74
  if use_starmap:
@@ -84,7 +86,19 @@ def __handle_parameters(
84
86
  return desc, func, args
85
87
 
86
88
  @handle_error(error_log=LogLevels.ERROR_TRACEBACK)
87
- def multiprocessing(func: Callable[[T], R], args: list[T], use_starmap: bool = False, chunksize: int = 1, desc: str = "", max_workers: int = CPU_COUNT, delay_first_calls: float = 0, verbose: int = 0) -> list[R]:
89
+ def multiprocessing(
90
+ func: Callable[[T], R],
91
+ args: list[T],
92
+ use_starmap: bool = False,
93
+ chunksize: int = 1,
94
+ desc: str = "",
95
+ max_workers: int = CPU_COUNT,
96
+ delay_first_calls: float = 0,
97
+ color: str = MAGENTA,
98
+ bar_format: str = BAR_FORMAT,
99
+ ascii: bool = False,
100
+ verbose: int = 0
101
+ ) -> list[R]:
88
102
  r""" Method to execute a function in parallel using multiprocessing, you should use it:
89
103
 
90
104
  - For CPU-bound operations where the GIL (Global Interpreter Lock) is a bottleneck.
@@ -98,8 +112,13 @@ def multiprocessing(func: Callable[[T], R], args: list[T], use_starmap: bool = F
98
112
  chunksize (int): Number of arguments to process at a time (Defaults to 1 for proper progress bar display)
99
113
  desc (str): Description of the function execution displayed in the progress bar
100
114
  max_workers (int): Number of workers to use (Defaults to CPU_COUNT)
101
- delay_first_calls (float): Apply i*delay_first_calls seconds delay to the first "max_workers" calls. For instance, the first process will be delayed by 0 seconds, the second by 1 second, etc. (Defaults to 0): This can be useful to avoid functions being called in the same second.
102
- verbose (int): Level of verbosity, decrease by 1 for each depth
115
+ delay_first_calls (float): Apply i*delay_first_calls seconds delay to the first "max_workers" calls.
116
+ For instance, the first process will be delayed by 0 seconds, the second by 1 second, etc.
117
+ (Defaults to 0): This can be useful to avoid functions being called in the same second.
118
+ color (str): Color of the progress bar (Defaults to MAGENTA)
119
+ bar_format (str): Format of the progress bar (Defaults to BAR_FORMAT)
120
+ ascii (bool): Whether to use ASCII or Unicode characters for the progress bar (Defaults to False)
121
+ verbose (int): Level of verbosity, decrease by 1 for each depth (Defaults to 0)
103
122
  Returns:
104
123
  list[object]: Results of the function execution
105
124
  Examples:
@@ -118,12 +137,14 @@ def multiprocessing(func: Callable[[T], R], args: list[T], use_starmap: bool = F
118
137
  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
119
138
  """
120
139
  # Handle parameters
121
- desc, func, args = __handle_parameters(func, args, use_starmap, delay_first_calls, max_workers, desc)
140
+ desc, func, args = __handle_parameters(func, args, use_starmap, delay_first_calls, max_workers, desc, color)
141
+ if bar_format == BAR_FORMAT:
142
+ bar_format = bar_format.replace(MAGENTA, color)
122
143
 
123
144
  # Do multiprocessing only if there is more than 1 argument and more than 1 CPU
124
145
  if max_workers > 1 and len(args) > 1:
125
146
  if verbose > 0:
126
- return list(process_map(func, args, max_workers=max_workers, chunksize=chunksize, desc=desc, bar_format=BAR_FORMAT, ascii=False)) # type: ignore
147
+ return list(process_map(func, args, max_workers=max_workers, chunksize=chunksize, desc=desc, bar_format=bar_format, ascii=ascii)) # type: ignore
127
148
  else:
128
149
  with Pool(max_workers) as pool:
129
150
  return list(pool.map(func, args, chunksize=chunksize)) # type: ignore
@@ -131,13 +152,24 @@ def multiprocessing(func: Callable[[T], R], args: list[T], use_starmap: bool = F
131
152
  # Single process execution
132
153
  else:
133
154
  if verbose > 0:
134
- return [func(arg) for arg in tqdm(args, total=len(args), desc=desc, bar_format=BAR_FORMAT, ascii=False)]
155
+ return [func(arg) for arg in tqdm(args, total=len(args), desc=desc, bar_format=bar_format, ascii=ascii)]
135
156
  else:
136
157
  return [func(arg) for arg in args]
137
158
 
138
159
 
139
160
  @handle_error(error_log=LogLevels.ERROR_TRACEBACK)
140
- def multithreading(func: Callable[[T], R], args: list[T], use_starmap: bool = False, desc: str = "", max_workers: int = CPU_COUNT, delay_first_calls: float = 0, verbose: int = 0) -> list[R]:
161
+ def multithreading(
162
+ func: Callable[[T], R],
163
+ args: list[T],
164
+ use_starmap: bool = False,
165
+ desc: str = "",
166
+ max_workers: int = CPU_COUNT,
167
+ delay_first_calls: float = 0,
168
+ color: str = MAGENTA,
169
+ bar_format: str = BAR_FORMAT,
170
+ ascii: bool = False,
171
+ verbose: int = 0
172
+ ) -> list[R]:
141
173
  r""" Method to execute a function in parallel using multithreading, you should use it:
142
174
 
143
175
  - For I/O-bound operations where the GIL is not a bottleneck, such as network requests or disk operations.
@@ -150,8 +182,13 @@ def multithreading(func: Callable[[T], R], args: list[T], use_starmap: bool = Fa
150
182
  use_starmap (bool): Whether to use starmap or not (Defaults to False): True means the function will be called like func(\*args[i]) instead of func(args[i])
151
183
  desc (str): Description of the function execution displayed in the progress bar
152
184
  max_workers (int): Number of workers to use (Defaults to CPU_COUNT)
153
- delay_first_calls (float): Apply i*delay_first_calls seconds delay to the first "max_workers" calls. For instance with value to 1, the first thread will be delayed by 0 seconds, the second by 1 second, etc. (Defaults to 0): This can be useful to avoid functions being called in the same second.
154
- verbose (int): Level of verbosity, decrease by 1 for each depth
185
+ delay_first_calls (float): Apply i*delay_first_calls seconds delay to the first "max_workers" calls.
186
+ For instance with value to 1, the first thread will be delayed by 0 seconds, the second by 1 second, etc.
187
+ (Defaults to 0): This can be useful to avoid functions being called in the same second.
188
+ color (str): Color of the progress bar (Defaults to MAGENTA)
189
+ bar_format (str): Format of the progress bar (Defaults to BAR_FORMAT)
190
+ ascii (bool): Whether to use ASCII or Unicode characters for the progress bar (Defaults to False)
191
+ verbose (int): Level of verbosity, decrease by 1 for each depth (Defaults to 0)
155
192
  Returns:
156
193
  list[object]: Results of the function execution
157
194
  Examples:
@@ -170,13 +207,15 @@ def multithreading(func: Callable[[T], R], args: list[T], use_starmap: bool = Fa
170
207
  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
171
208
  """
172
209
  # Handle parameters
173
- desc, func, args = __handle_parameters(func, args, use_starmap, delay_first_calls, max_workers, desc)
210
+ desc, func, args = __handle_parameters(func, args, use_starmap, delay_first_calls, max_workers, desc, color)
211
+ if bar_format == BAR_FORMAT:
212
+ bar_format = bar_format.replace(MAGENTA, color)
174
213
 
175
214
  # Do multithreading only if there is more than 1 argument and more than 1 CPU
176
215
  if max_workers > 1 and len(args) > 1:
177
216
  if verbose > 0:
178
217
  with ThreadPoolExecutor(max_workers) as executor:
179
- return list(tqdm(executor.map(func, args), total=len(args), desc=desc, bar_format=BAR_FORMAT, ascii=False))
218
+ return list(tqdm(executor.map(func, args), total=len(args), desc=desc, bar_format=bar_format, ascii=ascii))
180
219
  else:
181
220
  with ThreadPoolExecutor(max_workers) as executor:
182
221
  return list(executor.map(func, args))
@@ -184,7 +223,7 @@ def multithreading(func: Callable[[T], R], args: list[T], use_starmap: bool = Fa
184
223
  # Single process execution
185
224
  else:
186
225
  if verbose > 0:
187
- return [func(arg) for arg in tqdm(args, total=len(args), desc=desc, bar_format=BAR_FORMAT, ascii=False)]
226
+ return [func(arg) for arg in tqdm(args, total=len(args), desc=desc, bar_format=bar_format, ascii=ascii)]
188
227
  else:
189
228
  return [func(arg) for arg in args]
190
229
 
File without changes
File without changes