stouputils 1.9.5__tar.gz → 1.9.7__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.
- {stouputils-1.9.5 → stouputils-1.9.7}/PKG-INFO +1 -1
- {stouputils-1.9.5 → stouputils-1.9.7}/pyproject.toml +1 -1
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/ctx.py +94 -21
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/ctx.pyi +50 -11
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/parallel.py +22 -4
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/parallel.pyi +8 -4
- {stouputils-1.9.5 → stouputils-1.9.7}/.gitignore +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/LICENSE +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/README.md +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/__init__.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/__init__.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/__main__.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/_deprecated.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/_deprecated.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/all_doctests.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/all_doctests.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/__init__.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/__init__.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/automatic_docs.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/automatic_docs.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/upscaler/__init__.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/upscaler/__init__.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/upscaler/config.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/upscaler/config.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/upscaler/image.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/upscaler/image.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/upscaler/video.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/applications/upscaler/video.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/archive.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/archive.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/backup.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/backup.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/collections.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/collections.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/__init__.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/__init__.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/cd_utils.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/cd_utils.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/github.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/github.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/pypi.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/pypi.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/pyproject.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/pyproject.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/stubs.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/continuous_delivery/stubs.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/config/get.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/config/set.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/__init__.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/auto_contrast.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/axis_flip.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/bias_field_correction.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/binary_threshold.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/blur.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/brightness.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/canny.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/clahe.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/common.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/contrast.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/curvature_flow_filter.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/denoise.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/histogram_equalization.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/invert.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/laplacian.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/median_blur.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/noise.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/normalize.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/random_erase.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/resize.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/rotation.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/salt_pepper.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/sharpening.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/shearing.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/threshold.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/translation.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/zoom.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image_augmentation.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image_preprocess.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/prosthesis_detection.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/technique.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/dataset/__init__.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/dataset/dataset.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/dataset/dataset_loader.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/dataset/grouping_strategy.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/dataset/image_loader.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/dataset/xy_tuple.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/metric_dictionnary.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/metric_utils.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/mlflow_utils.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/abstract_model.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/all.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/base_keras.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras/all.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras/convnext.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras/densenet.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras/efficientnet.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras/mobilenet.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras/resnet.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras/squeezenet.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras/vgg.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras/xception.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/callbacks/__init__.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/callbacks/colored_progress_bar.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/callbacks/learning_rate_finder.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/callbacks/model_checkpoint_v2.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/callbacks/progressive_unfreezing.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/callbacks/warmup_scheduler.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/losses/__init__.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/losses/next_generation_loss.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/visualizations.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/model_interface.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/sandbox.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/range_tuple.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/scripts/augment_dataset.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/scripts/exhaustive_process.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/scripts/preprocess_dataset.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/scripts/routine.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/utils.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/decorators.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/decorators.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/image.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/image.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/__init__.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/__init__.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/common.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/common.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/downloader.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/downloader.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/linux.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/linux.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/main.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/main.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/windows.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/installer/windows.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/io.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/io.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/print.py +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/print.pyi +0 -0
- {stouputils-1.9.5 → stouputils-1.9.7}/stouputils/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stouputils
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.7
|
|
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.
|
|
8
|
+
version = "1.9.7"
|
|
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"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""
|
|
2
|
-
This module provides context managers for
|
|
2
|
+
This module provides context managers for various utilities such as logging to a file,
|
|
3
|
+
measuring execution time, silencing output, and setting multiprocessing start methods.
|
|
3
4
|
|
|
4
5
|
- LogToFile: Context manager to log to a file every print call (with LINE_UP handling)
|
|
5
6
|
- MeasureTime: Context manager to measure execution time of a code block
|
|
@@ -18,14 +19,22 @@ import os
|
|
|
18
19
|
import sys
|
|
19
20
|
import time
|
|
20
21
|
from collections.abc import Callable
|
|
21
|
-
from
|
|
22
|
+
from contextlib import AbstractAsyncContextManager, AbstractContextManager
|
|
23
|
+
from typing import IO, Any, TextIO, TypeVar
|
|
22
24
|
|
|
23
25
|
from .io import super_open
|
|
24
26
|
from .print import TeeMultiOutput, debug
|
|
25
27
|
|
|
28
|
+
# Type variable for context managers
|
|
29
|
+
T = TypeVar("T")
|
|
30
|
+
|
|
31
|
+
# Abstract base class for context managers supporting both sync and async usage
|
|
32
|
+
class AbstractBothContextManager(AbstractContextManager[T], AbstractAsyncContextManager[T]):
|
|
33
|
+
""" Abstract base class for context managers that support both synchronous and asynchronous usage. """
|
|
34
|
+
pass
|
|
26
35
|
|
|
27
36
|
# Context manager to log to a file
|
|
28
|
-
class LogToFile:
|
|
37
|
+
class LogToFile(AbstractBothContextManager["LogToFile"]):
|
|
29
38
|
""" Context manager to log to a file.
|
|
30
39
|
|
|
31
40
|
This context manager allows you to temporarily log output to a file while still printing normally.
|
|
@@ -38,6 +47,8 @@ class LogToFile:
|
|
|
38
47
|
tee_stdout (bool): Whether to redirect stdout to the file (default: True)
|
|
39
48
|
tee_stderr (bool): Whether to redirect stderr to the file (default: True)
|
|
40
49
|
ignore_lineup (bool): Whether to ignore lines containing LINE_UP escape sequence in files (default: False)
|
|
50
|
+
restore_on_exit (bool): Whether to restore original stdout/stderr on exit (default: False)
|
|
51
|
+
This ctx uses TeeMultiOutput which handles closed files gracefully, so restoring is not mandatory.
|
|
41
52
|
|
|
42
53
|
Examples:
|
|
43
54
|
.. code-block:: python
|
|
@@ -46,6 +57,11 @@ class LogToFile:
|
|
|
46
57
|
> with stp.LogToFile("output.log"):
|
|
47
58
|
> stp.info("This will be logged to output.log and printed normally")
|
|
48
59
|
> print("This will also be logged")
|
|
60
|
+
|
|
61
|
+
> with stp.LogToFile("output.log") as log_ctx:
|
|
62
|
+
> stp.warning("This will be logged to output.log and printed normally")
|
|
63
|
+
> log_ctx.change_file("new_file.log")
|
|
64
|
+
> print("This will be logged to new_file.log")
|
|
49
65
|
"""
|
|
50
66
|
def __init__(
|
|
51
67
|
self,
|
|
@@ -54,7 +70,8 @@ class LogToFile:
|
|
|
54
70
|
encoding: str = "utf-8",
|
|
55
71
|
tee_stdout: bool = True,
|
|
56
72
|
tee_stderr: bool = True,
|
|
57
|
-
ignore_lineup: bool = True
|
|
73
|
+
ignore_lineup: bool = True,
|
|
74
|
+
restore_on_exit: bool = False
|
|
58
75
|
) -> None:
|
|
59
76
|
self.path: str = path
|
|
60
77
|
""" Attribute remembering path to the log file """
|
|
@@ -68,19 +85,27 @@ class LogToFile:
|
|
|
68
85
|
""" Whether to redirect stderr to the file """
|
|
69
86
|
self.ignore_lineup: bool = ignore_lineup
|
|
70
87
|
""" Whether to ignore lines containing LINE_UP escape sequence in files """
|
|
71
|
-
self.
|
|
88
|
+
self.restore_on_exit: bool = restore_on_exit
|
|
89
|
+
""" Whether to restore original stdout/stderr on exit.
|
|
90
|
+
This ctx uses TeeMultiOutput which handles closed files gracefully, so restoring is not mandatory. """
|
|
91
|
+
self.file: IO[Any]
|
|
72
92
|
""" Attribute remembering opened file """
|
|
73
|
-
self.original_stdout: TextIO
|
|
93
|
+
self.original_stdout: TextIO
|
|
74
94
|
""" Original stdout before redirection """
|
|
75
|
-
self.original_stderr: TextIO
|
|
95
|
+
self.original_stderr: TextIO
|
|
76
96
|
""" Original stderr before redirection """
|
|
77
97
|
|
|
78
98
|
def __enter__(self) -> LogToFile:
|
|
79
99
|
""" Enter context manager which opens the log file and redirects stdout/stderr """
|
|
100
|
+
# Open file
|
|
101
|
+
self.file = super_open(self.path, mode=self.mode, encoding=self.encoding)
|
|
102
|
+
|
|
80
103
|
# Redirect stdout and stderr if requested
|
|
81
104
|
if self.tee_stdout:
|
|
105
|
+
self.original_stdout = sys.stdout
|
|
82
106
|
sys.stdout = TeeMultiOutput(self.original_stdout, self.file, ignore_lineup=self.ignore_lineup)
|
|
83
107
|
if self.tee_stderr:
|
|
108
|
+
self.original_stderr = sys.stderr
|
|
84
109
|
sys.stderr = TeeMultiOutput(self.original_stderr, self.file, ignore_lineup=self.ignore_lineup)
|
|
85
110
|
|
|
86
111
|
# Return self
|
|
@@ -88,16 +113,35 @@ class LogToFile:
|
|
|
88
113
|
|
|
89
114
|
def __exit__(self, exc_type: type[BaseException]|None, exc_val: BaseException|None, exc_tb: Any|None) -> None:
|
|
90
115
|
""" Exit context manager which closes the log file and restores stdout/stderr """
|
|
91
|
-
# Restore original stdout and stderr
|
|
92
|
-
if self.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
116
|
+
# Restore original stdout and stderr (if requested)
|
|
117
|
+
if self.restore_on_exit:
|
|
118
|
+
if self.tee_stdout:
|
|
119
|
+
sys.stdout = self.original_stdout
|
|
120
|
+
if self.tee_stderr:
|
|
121
|
+
sys.stderr = self.original_stderr
|
|
97
122
|
|
|
98
123
|
# Close file
|
|
99
124
|
self.file.close()
|
|
100
125
|
|
|
126
|
+
async def __aenter__(self) -> LogToFile:
|
|
127
|
+
""" Enter async context manager which opens the log file and redirects stdout/stderr """
|
|
128
|
+
return self.__enter__()
|
|
129
|
+
|
|
130
|
+
async def __aexit__(self, exc_type: type[BaseException]|None, exc_val: BaseException|None, exc_tb: Any|None) -> None:
|
|
131
|
+
""" Exit async context manager which closes the log file and restores stdout/stderr """
|
|
132
|
+
self.__exit__(exc_type, exc_val, exc_tb)
|
|
133
|
+
|
|
134
|
+
def change_file(self, new_path: str) -> None:
|
|
135
|
+
""" Change the log file to a new path.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
new_path (str): New path to the log file
|
|
139
|
+
"""
|
|
140
|
+
# Close current file, open new file and redirect outputs
|
|
141
|
+
self.file.close()
|
|
142
|
+
self.path = new_path
|
|
143
|
+
self.__enter__()
|
|
144
|
+
|
|
101
145
|
@staticmethod
|
|
102
146
|
def common(logs_folder: str, filepath: str, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
|
|
103
147
|
""" Common code used at the beginning of a program to launch main function
|
|
@@ -129,7 +173,7 @@ class LogToFile:
|
|
|
129
173
|
return func(*args, **kwargs)
|
|
130
174
|
|
|
131
175
|
# Context manager to measure execution time
|
|
132
|
-
class MeasureTime:
|
|
176
|
+
class MeasureTime(AbstractBothContextManager["MeasureTime"]):
|
|
133
177
|
""" Context manager to measure execution time.
|
|
134
178
|
|
|
135
179
|
This context manager measures the execution time of the code block it wraps
|
|
@@ -202,9 +246,18 @@ class MeasureTime:
|
|
|
202
246
|
hours: int = hours % 24
|
|
203
247
|
self.print_func(f"{self.message}: {days}d {hours}h {minutes}m {seconds}s")
|
|
204
248
|
|
|
249
|
+
async def __aenter__(self) -> MeasureTime:
|
|
250
|
+
""" Enter async context manager, record start time """
|
|
251
|
+
return self.__enter__()
|
|
252
|
+
|
|
253
|
+
async def __aexit__(self, exc_type: type[BaseException]|None, exc_val: BaseException|None, exc_tb: Any|None) -> None:
|
|
254
|
+
""" Exit async context manager, calculate duration and print """
|
|
255
|
+
self.__exit__(exc_type, exc_val, exc_tb)
|
|
256
|
+
|
|
205
257
|
# Context manager to temporarily silence output
|
|
206
|
-
class Muffle:
|
|
258
|
+
class Muffle(AbstractBothContextManager["Muffle"]):
|
|
207
259
|
""" Context manager that temporarily silences output.
|
|
260
|
+
(No thread-safety guaranteed)
|
|
208
261
|
|
|
209
262
|
Alternative to stouputils.decorators.silent()
|
|
210
263
|
|
|
@@ -215,18 +268,20 @@ class Muffle:
|
|
|
215
268
|
def __init__(self, mute_stderr: bool = False) -> None:
|
|
216
269
|
self.mute_stderr: bool = mute_stderr
|
|
217
270
|
""" Attribute remembering if stderr should be muted """
|
|
218
|
-
self.original_stdout:
|
|
271
|
+
self.original_stdout: IO[Any]
|
|
219
272
|
""" Attribute remembering original stdout """
|
|
220
|
-
self.original_stderr:
|
|
273
|
+
self.original_stderr: IO[Any]
|
|
221
274
|
""" Attribute remembering original stderr """
|
|
222
275
|
|
|
223
276
|
def __enter__(self) -> Muffle:
|
|
224
277
|
""" Enter context manager which redirects stdout and stderr to devnull """
|
|
225
278
|
# Redirect stdout to devnull
|
|
279
|
+
self.original_stdout = sys.stdout
|
|
226
280
|
sys.stdout = open(os.devnull, "w", encoding="utf-8")
|
|
227
281
|
|
|
228
282
|
# Redirect stderr to devnull if needed
|
|
229
283
|
if self.mute_stderr:
|
|
284
|
+
self.original_stderr = sys.stderr
|
|
230
285
|
sys.stderr = open(os.devnull, "w", encoding="utf-8")
|
|
231
286
|
|
|
232
287
|
# Return self
|
|
@@ -243,8 +298,16 @@ class Muffle:
|
|
|
243
298
|
sys.stderr.close()
|
|
244
299
|
sys.stderr = self.original_stderr
|
|
245
300
|
|
|
301
|
+
async def __aenter__(self) -> Muffle:
|
|
302
|
+
""" Enter async context manager which redirects stdout and stderr to devnull """
|
|
303
|
+
return self.__enter__()
|
|
304
|
+
|
|
305
|
+
async def __aexit__(self, exc_type: type[BaseException]|None, exc_val: BaseException|None, exc_tb: Any|None) -> None:
|
|
306
|
+
""" Exit async context manager which restores original stdout and stderr """
|
|
307
|
+
self.__exit__(exc_type, exc_val, exc_tb)
|
|
308
|
+
|
|
246
309
|
# Context manager that does nothing
|
|
247
|
-
class DoNothing:
|
|
310
|
+
class DoNothing(AbstractBothContextManager["DoNothing"]):
|
|
248
311
|
""" Context manager that does nothing.
|
|
249
312
|
|
|
250
313
|
This is a no-op context manager that can be used as a placeholder
|
|
@@ -269,7 +332,7 @@ class DoNothing:
|
|
|
269
332
|
""" No initialization needed, this is a no-op context manager """
|
|
270
333
|
pass
|
|
271
334
|
|
|
272
|
-
def __enter__(self) ->
|
|
335
|
+
def __enter__(self) -> DoNothing:
|
|
273
336
|
""" Enter context manager (does nothing) """
|
|
274
337
|
return self
|
|
275
338
|
|
|
@@ -277,16 +340,18 @@ class DoNothing:
|
|
|
277
340
|
""" Exit context manager (does nothing) """
|
|
278
341
|
pass
|
|
279
342
|
|
|
280
|
-
async def __aenter__(self) ->
|
|
343
|
+
async def __aenter__(self) -> DoNothing:
|
|
281
344
|
""" Enter async context manager (does nothing) """
|
|
282
345
|
return self
|
|
283
346
|
|
|
284
347
|
async def __aexit__(self, *excinfo: Any) -> None:
|
|
285
348
|
""" Exit async context manager (does nothing) """
|
|
286
349
|
pass
|
|
350
|
+
NullContextManager = DoNothing
|
|
351
|
+
""" Alias for DoNothing context manager """
|
|
287
352
|
|
|
288
353
|
# Context manager to temporarily set multiprocessing start method
|
|
289
|
-
class SetMPStartMethod:
|
|
354
|
+
class SetMPStartMethod(AbstractBothContextManager["SetMPStartMethod"]):
|
|
290
355
|
""" Context manager to temporarily set multiprocessing start method.
|
|
291
356
|
|
|
292
357
|
This context manager allows you to temporarily change the multiprocessing start method
|
|
@@ -333,3 +398,11 @@ class SetMPStartMethod:
|
|
|
333
398
|
if self.old_method != self.start_method:
|
|
334
399
|
mp.set_start_method(self.old_method, force=True)
|
|
335
400
|
|
|
401
|
+
async def __aenter__(self) -> SetMPStartMethod:
|
|
402
|
+
""" Enter async context manager which sets the start method """
|
|
403
|
+
return self.__enter__()
|
|
404
|
+
|
|
405
|
+
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
406
|
+
""" Exit async context manager which restores the original start method """
|
|
407
|
+
self.__exit__(exc_type, exc_val, exc_tb)
|
|
408
|
+
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import abc
|
|
1
2
|
from .io import super_open as super_open
|
|
2
3
|
from .print import TeeMultiOutput as TeeMultiOutput, debug as debug
|
|
3
4
|
from collections.abc import Callable as Callable
|
|
4
|
-
from
|
|
5
|
+
from contextlib import AbstractAsyncContextManager, AbstractContextManager
|
|
6
|
+
from typing import Any, IO, TextIO, TypeVar
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
T = TypeVar('T')
|
|
9
|
+
|
|
10
|
+
class AbstractBothContextManager(AbstractContextManager[T], AbstractAsyncContextManager[T], metaclass=abc.ABCMeta):
|
|
11
|
+
""" Abstract base class for context managers that support both synchronous and asynchronous usage. """
|
|
12
|
+
|
|
13
|
+
class LogToFile(AbstractBothContextManager['LogToFile']):
|
|
7
14
|
''' Context manager to log to a file.
|
|
8
15
|
|
|
9
16
|
\tThis context manager allows you to temporarily log output to a file while still printing normally.
|
|
@@ -16,6 +23,8 @@ class LogToFile:
|
|
|
16
23
|
\t\ttee_stdout (bool): Whether to redirect stdout to the file (default: True)
|
|
17
24
|
\t\ttee_stderr (bool): Whether to redirect stderr to the file (default: True)
|
|
18
25
|
\t\tignore_lineup (bool): Whether to ignore lines containing LINE_UP escape sequence in files (default: False)
|
|
26
|
+
\t\trestore_on_exit (bool): Whether to restore original stdout/stderr on exit (default: False)
|
|
27
|
+
\t\t\tThis ctx uses TeeMultiOutput which handles closed files gracefully, so restoring is not mandatory.
|
|
19
28
|
|
|
20
29
|
\tExamples:
|
|
21
30
|
\t\t.. code-block:: python
|
|
@@ -24,6 +33,11 @@ class LogToFile:
|
|
|
24
33
|
\t\t\t> with stp.LogToFile("output.log"):
|
|
25
34
|
\t\t\t> stp.info("This will be logged to output.log and printed normally")
|
|
26
35
|
\t\t\t> print("This will also be logged")
|
|
36
|
+
|
|
37
|
+
\t\t\t> with stp.LogToFile("output.log") as log_ctx:
|
|
38
|
+
\t\t\t> stp.warning("This will be logged to output.log and printed normally")
|
|
39
|
+
\t\t\t> log_ctx.change_file("new_file.log")
|
|
40
|
+
\t\t\t> print("This will be logged to new_file.log")
|
|
27
41
|
\t'''
|
|
28
42
|
path: str
|
|
29
43
|
mode: str
|
|
@@ -31,14 +45,25 @@ class LogToFile:
|
|
|
31
45
|
tee_stdout: bool
|
|
32
46
|
tee_stderr: bool
|
|
33
47
|
ignore_lineup: bool
|
|
48
|
+
restore_on_exit: bool
|
|
34
49
|
file: IO[Any]
|
|
35
50
|
original_stdout: TextIO
|
|
36
51
|
original_stderr: TextIO
|
|
37
|
-
def __init__(self, path: str, mode: str = 'w', encoding: str = 'utf-8', tee_stdout: bool = True, tee_stderr: bool = True, ignore_lineup: bool = True) -> None: ...
|
|
52
|
+
def __init__(self, path: str, mode: str = 'w', encoding: str = 'utf-8', tee_stdout: bool = True, tee_stderr: bool = True, ignore_lineup: bool = True, restore_on_exit: bool = False) -> None: ...
|
|
38
53
|
def __enter__(self) -> LogToFile:
|
|
39
54
|
""" Enter context manager which opens the log file and redirects stdout/stderr """
|
|
40
55
|
def __exit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: Any | None) -> None:
|
|
41
56
|
""" Exit context manager which closes the log file and restores stdout/stderr """
|
|
57
|
+
async def __aenter__(self) -> LogToFile:
|
|
58
|
+
""" Enter async context manager which opens the log file and redirects stdout/stderr """
|
|
59
|
+
async def __aexit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: Any | None) -> None:
|
|
60
|
+
""" Exit async context manager which closes the log file and restores stdout/stderr """
|
|
61
|
+
def change_file(self, new_path: str) -> None:
|
|
62
|
+
""" Change the log file to a new path.
|
|
63
|
+
|
|
64
|
+
\t\tArgs:
|
|
65
|
+
\t\t\tnew_path (str): New path to the log file
|
|
66
|
+
\t\t"""
|
|
42
67
|
@staticmethod
|
|
43
68
|
def common(logs_folder: str, filepath: str, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
|
|
44
69
|
''' Common code used at the beginning of a program to launch main function
|
|
@@ -57,7 +82,7 @@ class LogToFile:
|
|
|
57
82
|
\t\t\t... LogToFile.common(f"{ROOT}/logs", __file__, main)
|
|
58
83
|
\t\t'''
|
|
59
84
|
|
|
60
|
-
class MeasureTime:
|
|
85
|
+
class MeasureTime(AbstractBothContextManager['MeasureTime']):
|
|
61
86
|
''' Context manager to measure execution time.
|
|
62
87
|
|
|
63
88
|
\tThis context manager measures the execution time of the code block it wraps
|
|
@@ -91,9 +116,14 @@ class MeasureTime:
|
|
|
91
116
|
""" Enter context manager, record start time """
|
|
92
117
|
def __exit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: Any | None) -> None:
|
|
93
118
|
""" Exit context manager, calculate duration and print """
|
|
119
|
+
async def __aenter__(self) -> MeasureTime:
|
|
120
|
+
""" Enter async context manager, record start time """
|
|
121
|
+
async def __aexit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: Any | None) -> None:
|
|
122
|
+
""" Exit async context manager, calculate duration and print """
|
|
94
123
|
|
|
95
|
-
class Muffle:
|
|
124
|
+
class Muffle(AbstractBothContextManager['Muffle']):
|
|
96
125
|
''' Context manager that temporarily silences output.
|
|
126
|
+
\t(No thread-safety guaranteed)
|
|
97
127
|
|
|
98
128
|
\tAlternative to stouputils.decorators.silent()
|
|
99
129
|
|
|
@@ -102,15 +132,19 @@ class Muffle:
|
|
|
102
132
|
\t\t... print("This will not be printed")
|
|
103
133
|
\t'''
|
|
104
134
|
mute_stderr: bool
|
|
105
|
-
original_stdout:
|
|
106
|
-
original_stderr:
|
|
135
|
+
original_stdout: IO[Any]
|
|
136
|
+
original_stderr: IO[Any]
|
|
107
137
|
def __init__(self, mute_stderr: bool = False) -> None: ...
|
|
108
138
|
def __enter__(self) -> Muffle:
|
|
109
139
|
""" Enter context manager which redirects stdout and stderr to devnull """
|
|
110
140
|
def __exit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: Any | None) -> None:
|
|
111
141
|
""" Exit context manager which restores original stdout and stderr """
|
|
142
|
+
async def __aenter__(self) -> Muffle:
|
|
143
|
+
""" Enter async context manager which redirects stdout and stderr to devnull """
|
|
144
|
+
async def __aexit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: Any | None) -> None:
|
|
145
|
+
""" Exit async context manager which restores original stdout and stderr """
|
|
112
146
|
|
|
113
|
-
class DoNothing:
|
|
147
|
+
class DoNothing(AbstractBothContextManager['DoNothing']):
|
|
114
148
|
''' Context manager that does nothing.
|
|
115
149
|
|
|
116
150
|
\tThis is a no-op context manager that can be used as a placeholder
|
|
@@ -133,16 +167,17 @@ class DoNothing:
|
|
|
133
167
|
\t'''
|
|
134
168
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
135
169
|
""" No initialization needed, this is a no-op context manager """
|
|
136
|
-
def __enter__(self) ->
|
|
170
|
+
def __enter__(self) -> DoNothing:
|
|
137
171
|
""" Enter context manager (does nothing) """
|
|
138
172
|
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
139
173
|
""" Exit context manager (does nothing) """
|
|
140
|
-
async def __aenter__(self) ->
|
|
174
|
+
async def __aenter__(self) -> DoNothing:
|
|
141
175
|
""" Enter async context manager (does nothing) """
|
|
142
176
|
async def __aexit__(self, *excinfo: Any) -> None:
|
|
143
177
|
""" Exit async context manager (does nothing) """
|
|
178
|
+
NullContextManager = DoNothing
|
|
144
179
|
|
|
145
|
-
class SetMPStartMethod:
|
|
180
|
+
class SetMPStartMethod(AbstractBothContextManager['SetMPStartMethod']):
|
|
146
181
|
''' Context manager to temporarily set multiprocessing start method.
|
|
147
182
|
|
|
148
183
|
\tThis context manager allows you to temporarily change the multiprocessing start method
|
|
@@ -170,3 +205,7 @@ class SetMPStartMethod:
|
|
|
170
205
|
""" Enter context manager which sets the start method """
|
|
171
206
|
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
172
207
|
""" Exit context manager which restores the original start method """
|
|
208
|
+
async def __aenter__(self) -> SetMPStartMethod:
|
|
209
|
+
""" Enter async context manager which sets the start method """
|
|
210
|
+
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
211
|
+
""" Exit async context manager which restores the original start method """
|
|
@@ -40,7 +40,7 @@ def multiprocessing(
|
|
|
40
40
|
use_starmap: bool = False,
|
|
41
41
|
chunksize: int = 1,
|
|
42
42
|
desc: str = "",
|
|
43
|
-
max_workers: int = CPU_COUNT,
|
|
43
|
+
max_workers: int | float = CPU_COUNT,
|
|
44
44
|
delay_first_calls: float = 0,
|
|
45
45
|
color: str = MAGENTA,
|
|
46
46
|
bar_format: str = BAR_FORMAT,
|
|
@@ -61,7 +61,9 @@ def multiprocessing(
|
|
|
61
61
|
(Defaults to 1 for proper progress bar display)
|
|
62
62
|
desc (str): Description displayed in the progress bar
|
|
63
63
|
(if not provided no progress bar will be displayed)
|
|
64
|
-
max_workers (int):
|
|
64
|
+
max_workers (int | float): Number of workers to use (Defaults to CPU_COUNT), -1 means CPU_COUNT.
|
|
65
|
+
If float between 0 and 1, it's treated as a percentage of CPU_COUNT.
|
|
66
|
+
If negative float between -1 and 0, it's treated as a percentage of len(args).
|
|
65
67
|
delay_first_calls (float): Apply i*delay_first_calls seconds delay to the first "max_workers" calls.
|
|
66
68
|
For instance, the first process will be delayed by 0 seconds, the second by 1 second, etc.
|
|
67
69
|
(Defaults to 0): This can be useful to avoid functions being called in the same second.
|
|
@@ -109,6 +111,13 @@ def multiprocessing(
|
|
|
109
111
|
# Handle parameters
|
|
110
112
|
if max_workers == -1:
|
|
111
113
|
max_workers = CPU_COUNT
|
|
114
|
+
if isinstance(max_workers, float):
|
|
115
|
+
if max_workers > 0:
|
|
116
|
+
assert max_workers <= 1, "max_workers as positive float must be between 0 and 1 (percentage of CPU_COUNT)"
|
|
117
|
+
max_workers = int(max_workers * CPU_COUNT)
|
|
118
|
+
else:
|
|
119
|
+
assert -1 <= max_workers < 0, "max_workers as negative float must be between -1 and 0 (percentage of len(args))"
|
|
120
|
+
max_workers = int(-max_workers * len(args))
|
|
112
121
|
verbose: bool = desc != ""
|
|
113
122
|
desc, func, args = _handle_parameters(func, args, use_starmap, delay_first_calls, max_workers, desc, color)
|
|
114
123
|
if bar_format == BAR_FORMAT:
|
|
@@ -148,7 +157,7 @@ def multithreading(
|
|
|
148
157
|
args: list[T],
|
|
149
158
|
use_starmap: bool = False,
|
|
150
159
|
desc: str = "",
|
|
151
|
-
max_workers: int = CPU_COUNT,
|
|
160
|
+
max_workers: int | float = CPU_COUNT,
|
|
152
161
|
delay_first_calls: float = 0,
|
|
153
162
|
color: str = MAGENTA,
|
|
154
163
|
bar_format: str = BAR_FORMAT,
|
|
@@ -167,7 +176,9 @@ def multithreading(
|
|
|
167
176
|
True means the function will be called like func(\*args[i]) instead of func(args[i])
|
|
168
177
|
desc (str): Description displayed in the progress bar
|
|
169
178
|
(if not provided no progress bar will be displayed)
|
|
170
|
-
max_workers (int):
|
|
179
|
+
max_workers (int | float): Number of workers to use (Defaults to CPU_COUNT), -1 means CPU_COUNT.
|
|
180
|
+
If float between 0 and 1, it's treated as a percentage of CPU_COUNT.
|
|
181
|
+
If negative float between -1 and 0, it's treated as a percentage of len(args).
|
|
171
182
|
delay_first_calls (float): Apply i*delay_first_calls seconds delay to the first "max_workers" calls.
|
|
172
183
|
For instance with value to 1, the first thread will be delayed by 0 seconds, the second by 1 second, etc.
|
|
173
184
|
(Defaults to 0): This can be useful to avoid functions being called in the same second.
|
|
@@ -213,6 +224,13 @@ def multithreading(
|
|
|
213
224
|
# Handle parameters
|
|
214
225
|
if max_workers == -1:
|
|
215
226
|
max_workers = CPU_COUNT
|
|
227
|
+
if isinstance(max_workers, float):
|
|
228
|
+
if max_workers > 0:
|
|
229
|
+
assert max_workers <= 1, "max_workers as positive float must be between 0 and 1 (percentage of CPU_COUNT)"
|
|
230
|
+
max_workers = int(max_workers * CPU_COUNT)
|
|
231
|
+
else:
|
|
232
|
+
assert -1 <= max_workers < 0, "max_workers as negative float must be between -1 and 0 (percentage of len(args))"
|
|
233
|
+
max_workers = int(-max_workers * len(args))
|
|
216
234
|
verbose: bool = desc != ""
|
|
217
235
|
desc, func, args = _handle_parameters(func, args, use_starmap, delay_first_calls, max_workers, desc, color)
|
|
218
236
|
if bar_format == BAR_FORMAT:
|
|
@@ -10,7 +10,7 @@ CPU_COUNT: int
|
|
|
10
10
|
T = TypeVar('T')
|
|
11
11
|
R = TypeVar('R')
|
|
12
12
|
|
|
13
|
-
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]:
|
|
13
|
+
def multiprocessing(func: Callable[..., R] | list[Callable[..., R]], args: list[T], use_starmap: bool = False, chunksize: int = 1, desc: str = '', max_workers: int | float = ..., delay_first_calls: float = 0, color: str = ..., bar_format: str = ..., ascii: bool = False) -> list[R]:
|
|
14
14
|
''' Method to execute a function in parallel using multiprocessing
|
|
15
15
|
|
|
16
16
|
\t- For CPU-bound operations where the GIL (Global Interpreter Lock) is a bottleneck.
|
|
@@ -26,7 +26,9 @@ def multiprocessing(func: Callable[..., R] | list[Callable[..., R]], args: list[
|
|
|
26
26
|
\t\t\t(Defaults to 1 for proper progress bar display)
|
|
27
27
|
\t\tdesc\t\t\t\t(str):\t\t\t\tDescription displayed in the progress bar
|
|
28
28
|
\t\t\t(if not provided no progress bar will be displayed)
|
|
29
|
-
\t\tmax_workers\t\t\t(int):\t\
|
|
29
|
+
\t\tmax_workers\t\t\t(int | float):\t\tNumber of workers to use (Defaults to CPU_COUNT), -1 means CPU_COUNT.
|
|
30
|
+
\t\t\tIf float between 0 and 1, it\'s treated as a percentage of CPU_COUNT.
|
|
31
|
+
\t\t\tIf negative float between -1 and 0, it\'s treated as a percentage of len(args).
|
|
30
32
|
\t\tdelay_first_calls\t(float):\t\t\tApply i*delay_first_calls seconds delay to the first "max_workers" calls.
|
|
31
33
|
\t\t\tFor instance, the first process will be delayed by 0 seconds, the second by 1 second, etc.
|
|
32
34
|
\t\t\t(Defaults to 0): This can be useful to avoid functions being called in the same second.
|
|
@@ -64,7 +66,7 @@ def multiprocessing(func: Callable[..., R] | list[Callable[..., R]], args: list[
|
|
|
64
66
|
\t\t\t. )
|
|
65
67
|
\t\t\t[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
66
68
|
\t'''
|
|
67
|
-
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]:
|
|
69
|
+
def multithreading(func: Callable[..., R] | list[Callable[..., R]], args: list[T], use_starmap: bool = False, desc: str = '', max_workers: int | float = ..., delay_first_calls: float = 0, color: str = ..., bar_format: str = ..., ascii: bool = False) -> list[R]:
|
|
68
70
|
''' Method to execute a function in parallel using multithreading, you should use it:
|
|
69
71
|
|
|
70
72
|
\t- For I/O-bound operations where the GIL is not a bottleneck, such as network requests or disk operations.
|
|
@@ -78,7 +80,9 @@ def multithreading(func: Callable[..., R] | list[Callable[..., R]], args: list[T
|
|
|
78
80
|
\t\t\tTrue means the function will be called like func(\\*args[i]) instead of func(args[i])
|
|
79
81
|
\t\tdesc\t\t\t\t(str):\t\t\t\tDescription displayed in the progress bar
|
|
80
82
|
\t\t\t(if not provided no progress bar will be displayed)
|
|
81
|
-
\t\tmax_workers\t\t\t(int):\t\
|
|
83
|
+
\t\tmax_workers\t\t\t(int | float):\t\tNumber of workers to use (Defaults to CPU_COUNT), -1 means CPU_COUNT.
|
|
84
|
+
\t\t\tIf float between 0 and 1, it\'s treated as a percentage of CPU_COUNT.
|
|
85
|
+
\t\t\tIf negative float between -1 and 0, it\'s treated as a percentage of len(args).
|
|
82
86
|
\t\tdelay_first_calls\t(float):\t\t\tApply i*delay_first_calls seconds delay to the first "max_workers" calls.
|
|
83
87
|
\t\t\tFor instance with value to 1, the first thread will be delayed by 0 seconds, the second by 1 second, etc.
|
|
84
88
|
\t\t\t(Defaults to 0): This can be useful to avoid functions being called in the same second.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/__init__.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/auto_contrast.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/axis_flip.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/brightness.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/canny.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/clahe.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/common.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/contrast.py
RENAMED
|
File without changes
|
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/denoise.py
RENAMED
|
File without changes
|
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/invert.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/laplacian.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/median_blur.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/noise.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/normalize.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/random_erase.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/resize.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/rotation.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/salt_pepper.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/sharpening.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/shearing.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/threshold.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image/translation.py
RENAMED
|
File without changes
|
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image_augmentation.py
RENAMED
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/data_processing/image_preprocess.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/losses/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{stouputils-1.9.5 → stouputils-1.9.7}/stouputils/data_science/models/keras_utils/visualizations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|