stouputils 1.9.1__tar.gz → 1.9.2__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 (139) hide show
  1. {stouputils-1.9.1 → stouputils-1.9.2}/PKG-INFO +1 -1
  2. {stouputils-1.9.1 → stouputils-1.9.2}/pyproject.toml +1 -1
  3. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/parallel.py +36 -13
  4. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/parallel.pyi +10 -5
  5. {stouputils-1.9.1 → stouputils-1.9.2}/.gitignore +0 -0
  6. {stouputils-1.9.1 → stouputils-1.9.2}/LICENSE +0 -0
  7. {stouputils-1.9.1 → stouputils-1.9.2}/README.md +0 -0
  8. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/__init__.py +0 -0
  9. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/__init__.pyi +0 -0
  10. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/__main__.py +0 -0
  11. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/_deprecated.py +0 -0
  12. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/_deprecated.pyi +0 -0
  13. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/all_doctests.py +0 -0
  14. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/all_doctests.pyi +0 -0
  15. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/__init__.py +0 -0
  16. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/__init__.pyi +0 -0
  17. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/automatic_docs.py +0 -0
  18. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/automatic_docs.pyi +0 -0
  19. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/upscaler/__init__.py +0 -0
  20. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/upscaler/__init__.pyi +0 -0
  21. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/upscaler/config.py +0 -0
  22. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/upscaler/config.pyi +0 -0
  23. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/upscaler/image.py +0 -0
  24. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/upscaler/image.pyi +0 -0
  25. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/upscaler/video.py +0 -0
  26. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/applications/upscaler/video.pyi +0 -0
  27. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/archive.py +0 -0
  28. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/archive.pyi +0 -0
  29. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/backup.py +0 -0
  30. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/backup.pyi +0 -0
  31. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/collections.py +0 -0
  32. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/collections.pyi +0 -0
  33. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/__init__.py +0 -0
  34. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/__init__.pyi +0 -0
  35. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/cd_utils.py +0 -0
  36. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/cd_utils.pyi +0 -0
  37. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/github.py +0 -0
  38. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/github.pyi +0 -0
  39. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/pypi.py +0 -0
  40. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/pypi.pyi +0 -0
  41. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/pyproject.py +0 -0
  42. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/pyproject.pyi +0 -0
  43. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/stubs.py +0 -0
  44. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/continuous_delivery/stubs.pyi +0 -0
  45. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/ctx.py +0 -0
  46. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/ctx.pyi +0 -0
  47. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/config/get.py +0 -0
  48. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/config/set.py +0 -0
  49. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/__init__.py +0 -0
  50. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/auto_contrast.py +0 -0
  51. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/axis_flip.py +0 -0
  52. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/bias_field_correction.py +0 -0
  53. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/binary_threshold.py +0 -0
  54. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/blur.py +0 -0
  55. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/brightness.py +0 -0
  56. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/canny.py +0 -0
  57. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/clahe.py +0 -0
  58. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/common.py +0 -0
  59. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/contrast.py +0 -0
  60. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/curvature_flow_filter.py +0 -0
  61. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/denoise.py +0 -0
  62. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/histogram_equalization.py +0 -0
  63. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/invert.py +0 -0
  64. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/laplacian.py +0 -0
  65. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/median_blur.py +0 -0
  66. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/noise.py +0 -0
  67. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/normalize.py +0 -0
  68. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/random_erase.py +0 -0
  69. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/resize.py +0 -0
  70. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/rotation.py +0 -0
  71. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/salt_pepper.py +0 -0
  72. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/sharpening.py +0 -0
  73. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/shearing.py +0 -0
  74. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/threshold.py +0 -0
  75. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/translation.py +0 -0
  76. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image/zoom.py +0 -0
  77. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image_augmentation.py +0 -0
  78. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/image_preprocess.py +0 -0
  79. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/prosthesis_detection.py +0 -0
  80. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/data_processing/technique.py +0 -0
  81. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/dataset/__init__.py +0 -0
  82. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/dataset/dataset.py +0 -0
  83. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/dataset/dataset_loader.py +0 -0
  84. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/dataset/grouping_strategy.py +0 -0
  85. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/dataset/image_loader.py +0 -0
  86. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/dataset/xy_tuple.py +0 -0
  87. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/metric_dictionnary.py +0 -0
  88. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/metric_utils.py +0 -0
  89. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/mlflow_utils.py +0 -0
  90. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/abstract_model.py +0 -0
  91. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/all.py +0 -0
  92. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/base_keras.py +0 -0
  93. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras/all.py +0 -0
  94. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras/convnext.py +0 -0
  95. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras/densenet.py +0 -0
  96. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras/efficientnet.py +0 -0
  97. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras/mobilenet.py +0 -0
  98. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras/resnet.py +0 -0
  99. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras/squeezenet.py +0 -0
  100. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras/vgg.py +0 -0
  101. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras/xception.py +0 -0
  102. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras_utils/callbacks/__init__.py +0 -0
  103. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras_utils/callbacks/colored_progress_bar.py +0 -0
  104. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras_utils/callbacks/learning_rate_finder.py +0 -0
  105. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras_utils/callbacks/model_checkpoint_v2.py +0 -0
  106. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras_utils/callbacks/progressive_unfreezing.py +0 -0
  107. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras_utils/callbacks/warmup_scheduler.py +0 -0
  108. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras_utils/losses/__init__.py +0 -0
  109. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras_utils/losses/next_generation_loss.py +0 -0
  110. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/keras_utils/visualizations.py +0 -0
  111. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/model_interface.py +0 -0
  112. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/models/sandbox.py +0 -0
  113. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/range_tuple.py +0 -0
  114. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/scripts/augment_dataset.py +0 -0
  115. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/scripts/exhaustive_process.py +0 -0
  116. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/scripts/preprocess_dataset.py +0 -0
  117. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/scripts/routine.py +0 -0
  118. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/data_science/utils.py +0 -0
  119. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/decorators.py +0 -0
  120. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/decorators.pyi +0 -0
  121. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/image.py +0 -0
  122. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/image.pyi +0 -0
  123. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/__init__.py +0 -0
  124. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/__init__.pyi +0 -0
  125. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/common.py +0 -0
  126. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/common.pyi +0 -0
  127. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/downloader.py +0 -0
  128. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/downloader.pyi +0 -0
  129. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/linux.py +0 -0
  130. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/linux.pyi +0 -0
  131. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/main.py +0 -0
  132. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/main.pyi +0 -0
  133. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/windows.py +0 -0
  134. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/installer/windows.pyi +0 -0
  135. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/io.py +0 -0
  136. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/io.pyi +0 -0
  137. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/print.py +0 -0
  138. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/print.pyi +0 -0
  139. {stouputils-1.9.1 → stouputils-1.9.2}/stouputils/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stouputils
3
- Version: 1.9.1
3
+ Version: 1.9.2
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
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
 
6
6
  [project]
7
7
  name = "stouputils"
8
- version = "1.9.1"
8
+ version = "1.9.2"
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"
@@ -17,7 +17,6 @@ import time
17
17
  from collections.abc import Callable
18
18
  from typing import Any, TypeVar, cast
19
19
 
20
- from .decorators import LogLevels, handle_error
21
20
  from .print import BAR_FORMAT, MAGENTA
22
21
 
23
22
 
@@ -34,9 +33,8 @@ T = TypeVar("T")
34
33
  R = TypeVar("R")
35
34
 
36
35
  # Functions
37
- @handle_error(error_log=LogLevels.ERROR_TRACEBACK)
38
36
  def multiprocessing(
39
- func: Callable[[T], R] | list[Callable[[T], R]],
37
+ func: Callable[..., R] | list[Callable[..., R]],
40
38
  args: list[T],
41
39
  use_starmap: bool = False,
42
40
  chunksize: int = 1,
@@ -150,9 +148,8 @@ def multiprocessing(
150
148
  return [func(arg) for arg in args]
151
149
 
152
150
 
153
- @handle_error(error_log=LogLevels.ERROR_TRACEBACK)
154
151
  def multithreading(
155
- func: Callable[[T], R] | list[Callable[[T], R]],
152
+ func: Callable[..., R] | list[Callable[..., R]],
156
153
  args: list[T],
157
154
  use_starmap: bool = False,
158
155
  desc: str = "",
@@ -243,10 +240,10 @@ def multithreading(
243
240
  return [func(arg) for arg in args]
244
241
 
245
242
 
246
- @handle_error(error_log=LogLevels.ERROR_TRACEBACK)
247
243
  def run_in_subprocess(
248
244
  func: Callable[..., R],
249
245
  *args: Any,
246
+ timeout: float | None = None,
250
247
  **kwargs: Any
251
248
  ) -> R:
252
249
  """ Execute a function in a subprocess with positional and keyword arguments.
@@ -259,13 +256,16 @@ def run_in_subprocess(
259
256
  func (Callable): The function to execute in a subprocess.
260
257
  (SHOULD BE A TOP-LEVEL FUNCTION TO BE PICKLABLE)
261
258
  *args (Any): Positional arguments to pass to the function.
259
+ timeout (float | None): Maximum time in seconds to wait for the subprocess.
260
+ If None, wait indefinitely. If the subprocess exceeds this time, it will be terminated.
262
261
  **kwargs (Any): Keyword arguments to pass to the function.
263
262
 
264
263
  Returns:
265
264
  R: The return value of the function.
266
265
 
267
266
  Raises:
268
- RuntimeError: If the subprocess exits with a non-zero exit code.
267
+ RuntimeError: If the subprocess exits with a non-zero exit code or times out.
268
+ TimeoutError: If the subprocess exceeds the specified timeout.
269
269
 
270
270
  Examples:
271
271
  .. code-block:: python
@@ -285,6 +285,9 @@ def run_in_subprocess(
285
285
  . return f"{greeting}, {name}!"
286
286
  > run_in_subprocess(greet, "World", greeting="Hi")
287
287
  'Hi, World!'
288
+
289
+ > # With timeout to prevent hanging
290
+ > run_in_subprocess(some_gpu_func, data, timeout=300.0)
288
291
  """
289
292
  import multiprocessing as mp
290
293
  from multiprocessing import Queue
@@ -298,20 +301,40 @@ def run_in_subprocess(
298
301
  args=(result_queue, func, args, kwargs)
299
302
  )
300
303
  process.start()
301
- process.join()
304
+
305
+ # Join with timeout to prevent indefinite hanging
306
+ process.join(timeout=timeout)
307
+
308
+ # Check if process is still alive (timed out)
309
+ if process.is_alive():
310
+ process.terminate()
311
+ time.sleep(0.5) # Give it a moment to terminate gracefully
312
+ if process.is_alive():
313
+ process.kill()
314
+ process.join()
315
+ raise TimeoutError(f"Subprocess exceeded timeout of {timeout} seconds and was terminated")
302
316
 
303
317
  # Check exit code
304
318
  if process.exitcode != 0:
305
- raise RuntimeError(f"Subprocess failed with exit code {process.exitcode}")
319
+ # Try to get any exception from the queue (non-blocking)
320
+ error_msg = f"Subprocess failed with exit code {process.exitcode}"
321
+ try:
322
+ if not result_queue.empty():
323
+ result_or_exception = result_queue.get_nowait()
324
+ if isinstance(result_or_exception, Exception):
325
+ raise result_or_exception
326
+ except Exception:
327
+ pass
328
+ raise RuntimeError(error_msg)
306
329
 
307
330
  # Retrieve the result
308
- if not result_queue.empty():
309
- result_or_exception = result_queue.get()
331
+ try:
332
+ result_or_exception = result_queue.get_nowait()
310
333
  if isinstance(result_or_exception, Exception):
311
334
  raise result_or_exception
312
335
  return result_or_exception
313
- else:
314
- raise RuntimeError("Subprocess did not return any result")
336
+ except Exception as e:
337
+ raise RuntimeError("Subprocess did not return any result") from e
315
338
 
316
339
 
317
340
  # "Private" function for subprocess wrapper (must be at module level for pickling on Windows)
@@ -1,4 +1,3 @@
1
- from .decorators import LogLevels as LogLevels, handle_error as handle_error
2
1
  from .print import BAR_FORMAT as BAR_FORMAT, MAGENTA as MAGENTA
3
2
  from collections.abc import Callable
4
3
  from typing import Any, TypeVar
@@ -10,7 +9,7 @@ CPU_COUNT: int
10
9
  T = TypeVar('T')
11
10
  R = TypeVar('R')
12
11
 
13
- def multiprocessing(func: Callable[[T], R] | list[Callable[[T], R]], args: list[T], use_starmap: bool = False, chunksize: int = 1, desc: str = '', max_workers: int = ..., delay_first_calls: float = 0, color: str = ..., bar_format: str = ..., ascii: bool = False) -> list[R]:
12
+ def multiprocessing(func: Callable[..., R] | list[Callable[..., R]], args: list[T], use_starmap: bool = False, chunksize: int = 1, desc: str = '', max_workers: int = ..., delay_first_calls: float = 0, color: str = ..., bar_format: str = ..., ascii: bool = False) -> list[R]:
14
13
  ''' Method to execute a function in parallel using multiprocessing
15
14
 
16
15
  \t- For CPU-bound operations where the GIL (Global Interpreter Lock) is a bottleneck.
@@ -64,7 +63,7 @@ def multiprocessing(func: Callable[[T], R] | list[Callable[[T], R]], args: list[
64
63
  \t\t\t. )
65
64
  \t\t\t[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
66
65
  \t'''
67
- def multithreading(func: Callable[[T], R] | list[Callable[[T], R]], args: list[T], use_starmap: bool = False, desc: str = '', max_workers: int = ..., delay_first_calls: float = 0, color: str = ..., bar_format: str = ..., ascii: bool = False) -> list[R]:
66
+ def multithreading(func: Callable[..., R] | list[Callable[..., R]], args: list[T], use_starmap: bool = False, desc: str = '', max_workers: int = ..., delay_first_calls: float = 0, color: str = ..., bar_format: str = ..., ascii: bool = False) -> list[R]:
68
67
  ''' Method to execute a function in parallel using multithreading, you should use it:
69
68
 
70
69
  \t- For I/O-bound operations where the GIL is not a bottleneck, such as network requests or disk operations.
@@ -116,7 +115,7 @@ def multithreading(func: Callable[[T], R] | list[Callable[[T], R]], args: list[T
116
115
  \t\t\t. )
117
116
  \t\t\t[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
118
117
  \t'''
119
- def run_in_subprocess(func: Callable[..., R], *args: Any, **kwargs: Any) -> R:
118
+ def run_in_subprocess(func: Callable[..., R], *args: Any, timeout: float | None = None, **kwargs: Any) -> R:
120
119
  ''' Execute a function in a subprocess with positional and keyword arguments.
121
120
 
122
121
  \tThis is useful when you need to run a function in isolation to avoid memory leaks,
@@ -127,13 +126,16 @@ def run_in_subprocess(func: Callable[..., R], *args: Any, **kwargs: Any) -> R:
127
126
  \t\tfunc (Callable): The function to execute in a subprocess.
128
127
  \t\t\t(SHOULD BE A TOP-LEVEL FUNCTION TO BE PICKLABLE)
129
128
  \t\t*args (Any): Positional arguments to pass to the function.
129
+ \t\ttimeout (float | None): Maximum time in seconds to wait for the subprocess.
130
+ \t\t\tIf None, wait indefinitely. If the subprocess exceeds this time, it will be terminated.
130
131
  \t\t**kwargs (Any): Keyword arguments to pass to the function.
131
132
 
132
133
  \tReturns:
133
134
  \t\tR: The return value of the function.
134
135
 
135
136
  \tRaises:
136
- \t\tRuntimeError: If the subprocess exits with a non-zero exit code.
137
+ \t\tRuntimeError: If the subprocess exits with a non-zero exit code or times out.
138
+ \t\tTimeoutError: If the subprocess exceeds the specified timeout.
137
139
 
138
140
  \tExamples:
139
141
  \t\t.. code-block:: python
@@ -153,6 +155,9 @@ def run_in_subprocess(func: Callable[..., R], *args: Any, **kwargs: Any) -> R:
153
155
  \t\t\t. return f"{greeting}, {name}!"
154
156
  \t\t\t> run_in_subprocess(greet, "World", greeting="Hi")
155
157
  \t\t\t\'Hi, World!\'
158
+
159
+ \t\t\t> # With timeout to prevent hanging
160
+ \t\t\t> run_in_subprocess(some_gpu_func, data, timeout=300.0)
156
161
  \t'''
157
162
  def _subprocess_wrapper(result_queue: Any, func: Callable[..., R], args: tuple[Any, ...], kwargs: dict[str, Any]) -> None:
158
163
  """ Wrapper function to execute the target function and store the result in the queue.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes