stouputils 1.16.1__py3-none-any.whl → 1.16.3__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.
- stouputils/all_doctests.py +2 -2
- stouputils/applications/automatic_docs.py +0 -4
- stouputils/collections.py +34 -1
- stouputils/collections.pyi +21 -1
- stouputils/image.py +6 -6
- {stouputils-1.16.1.dist-info → stouputils-1.16.3.dist-info}/METADATA +2 -2
- {stouputils-1.16.1.dist-info → stouputils-1.16.3.dist-info}/RECORD +9 -9
- {stouputils-1.16.1.dist-info → stouputils-1.16.3.dist-info}/WHEEL +0 -0
- {stouputils-1.16.1.dist-info → stouputils-1.16.3.dist-info}/entry_points.txt +0 -0
stouputils/all_doctests.py
CHANGED
|
@@ -154,7 +154,7 @@ def launch_tests(root_dir: str, strict: bool = True, pattern: str = "*") -> int:
|
|
|
154
154
|
return total_failed
|
|
155
155
|
|
|
156
156
|
|
|
157
|
-
def test_module_with_progress(module: ModuleType, separator: str) -> TestResults:
|
|
157
|
+
def test_module_with_progress(module: "ModuleType", separator: str) -> "TestResults":
|
|
158
158
|
""" Test a module with testmod and measure the time taken with progress printing.
|
|
159
159
|
|
|
160
160
|
Args:
|
|
@@ -165,7 +165,7 @@ def test_module_with_progress(module: ModuleType, separator: str) -> TestResults
|
|
|
165
165
|
"""
|
|
166
166
|
from doctest import testmod
|
|
167
167
|
@measure_time(message=f"Testing module '{module.__name__}' {separator}took")
|
|
168
|
-
def internal() -> TestResults:
|
|
168
|
+
def internal() -> "TestResults":
|
|
169
169
|
return testmod(m=module)
|
|
170
170
|
return internal()
|
|
171
171
|
|
|
@@ -141,10 +141,6 @@ def get_sphinx_conf_content(
|
|
|
141
141
|
# Imports
|
|
142
142
|
import sys
|
|
143
143
|
from typing import Any
|
|
144
|
-
import typing
|
|
145
|
-
|
|
146
|
-
# Set TYPE_CHECKING to avoid import issues during documentation generation
|
|
147
|
-
typing.TYPE_CHECKING = True
|
|
148
144
|
|
|
149
145
|
# Add project_dir directory to Python path for module discovery
|
|
150
146
|
sys.path.insert(0, "{parent_of_project_dir}")
|
stouputils/collections.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
This module provides utilities for collection manipulation:
|
|
3
3
|
|
|
4
4
|
- unique_list: Remove duplicates from a list while preserving order using object id, hash or str
|
|
5
|
+
- at_least_n: Check if at least n elements in an iterable satisfy a given predicate
|
|
5
6
|
- sort_dict_keys: Sort dictionary keys using a given order list (ascending or descending)
|
|
6
7
|
- upsert_in_dataframe: Insert or update a row in a Polars DataFrame based on primary keys
|
|
7
8
|
- array_to_disk: Easily handle large numpy arrays on disk using zarr for efficient storage and access.
|
|
@@ -15,7 +16,7 @@ import atexit
|
|
|
15
16
|
import os
|
|
16
17
|
import shutil
|
|
17
18
|
import tempfile
|
|
18
|
-
from collections.abc import Iterable
|
|
19
|
+
from collections.abc import Callable, Iterable
|
|
19
20
|
from typing import TYPE_CHECKING, Any, Literal, TypeVar
|
|
20
21
|
|
|
21
22
|
# Lazy imports for typing
|
|
@@ -77,6 +78,38 @@ def unique_list[T](list_to_clean: Iterable[T], method: Literal["id", "hash", "st
|
|
|
77
78
|
# Return the cleaned list
|
|
78
79
|
return result
|
|
79
80
|
|
|
81
|
+
|
|
82
|
+
def at_least_n(iterable: Iterable[T], predicate: Callable[[T], bool], n: int) -> bool:
|
|
83
|
+
""" Return True if at least n elements in iterable satisfy predicate.
|
|
84
|
+
It's like the built-in any() but for at least n matches.
|
|
85
|
+
|
|
86
|
+
Stops iterating as soon as n matches are found (short-circuit evaluation).
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
iterable (Iterable[T]): The iterable to check.
|
|
90
|
+
predicate (Callable[[T], bool]): The predicate to apply to items.
|
|
91
|
+
n (int): Minimum number of matches required.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
bool: True if at least n elements satisfy predicate, otherwise False.
|
|
95
|
+
|
|
96
|
+
Examples:
|
|
97
|
+
>>> at_least_n([1, 2, 3, 4, *[i for i in range(5, int(1e5))]], lambda x: x % 2 == 0, 2)
|
|
98
|
+
True
|
|
99
|
+
>>> at_least_n([1, 3, 5, 7], lambda x: x % 2 == 0, 1)
|
|
100
|
+
False
|
|
101
|
+
"""
|
|
102
|
+
if n <= 0:
|
|
103
|
+
return True
|
|
104
|
+
count: int = 0
|
|
105
|
+
for item in iterable:
|
|
106
|
+
if predicate(item):
|
|
107
|
+
count += 1
|
|
108
|
+
if count >= n:
|
|
109
|
+
return True
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
|
|
80
113
|
def sort_dict_keys[T](dictionary: dict[T, Any], order: list[T], reverse: bool = False) -> dict[T, Any]:
|
|
81
114
|
""" Sort dictionary keys using a given order list (reverse optional)
|
|
82
115
|
|
stouputils/collections.pyi
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import polars as pl
|
|
2
2
|
import zarr
|
|
3
|
-
from collections.abc import Iterable
|
|
3
|
+
from collections.abc import Callable as Callable, Iterable
|
|
4
4
|
from numpy.typing import NDArray as NDArray
|
|
5
5
|
from typing import Any, Literal, TypeVar
|
|
6
6
|
|
|
@@ -31,6 +31,26 @@ def unique_list[T](list_to_clean: Iterable[T], method: Literal['id', 'hash', 'st
|
|
|
31
31
|
\t\t>>> unique_list([s1, s2, s1, s1, s3, s2, s3], method="str")
|
|
32
32
|
\t\t[{1, 2, 3}, {2, 3, 4}]
|
|
33
33
|
\t'''
|
|
34
|
+
def at_least_n(iterable: Iterable[T], predicate: Callable[[T], bool], n: int) -> bool:
|
|
35
|
+
""" Return True if at least n elements in iterable satisfy predicate.
|
|
36
|
+
\tIt's like the built-in any() but for at least n matches.
|
|
37
|
+
|
|
38
|
+
\tStops iterating as soon as n matches are found (short-circuit evaluation).
|
|
39
|
+
|
|
40
|
+
\tArgs:
|
|
41
|
+
\t\titerable\t(Iterable[T]):\t\t\tThe iterable to check.
|
|
42
|
+
\t\tpredicate\t(Callable[[T], bool]):\tThe predicate to apply to items.
|
|
43
|
+
\t\tn\t\t\t(int):\t\t\t\t\tMinimum number of matches required.
|
|
44
|
+
|
|
45
|
+
\tReturns:
|
|
46
|
+
\t\tbool: True if at least n elements satisfy predicate, otherwise False.
|
|
47
|
+
|
|
48
|
+
\tExamples:
|
|
49
|
+
\t\t>>> at_least_n([1, 2, 3, 4, *[i for i in range(5, int(1e5))]], lambda x: x % 2 == 0, 2)
|
|
50
|
+
\t\tTrue
|
|
51
|
+
\t\t>>> at_least_n([1, 3, 5, 7], lambda x: x % 2 == 0, 1)
|
|
52
|
+
\t\tFalse
|
|
53
|
+
\t"""
|
|
34
54
|
def sort_dict_keys[T](dictionary: dict[T, Any], order: list[T], reverse: bool = False) -> dict[T, Any]:
|
|
35
55
|
''' Sort dictionary keys using a given order list (reverse optional)
|
|
36
56
|
|
stouputils/image.py
CHANGED
|
@@ -28,7 +28,7 @@ PIL_Image_or_NDArray = TypeVar("PIL_Image_or_NDArray", bound="Image.Image | NDAr
|
|
|
28
28
|
def image_resize[PIL_Image_or_NDArray](
|
|
29
29
|
image: PIL_Image_or_NDArray,
|
|
30
30
|
max_result_size: int,
|
|
31
|
-
resampling: Image.Resampling | None = None,
|
|
31
|
+
resampling: "Image.Resampling | None" = None,
|
|
32
32
|
min_or_max: Callable[[int, int], int] = max,
|
|
33
33
|
return_type: type[PIL_Image_or_NDArray] | str = "same",
|
|
34
34
|
keep_aspect_ratio: bool = True,
|
|
@@ -123,8 +123,8 @@ def image_resize[PIL_Image_or_NDArray](
|
|
|
123
123
|
|
|
124
124
|
def auto_crop[PIL_Image_or_NDArray](
|
|
125
125
|
image: PIL_Image_or_NDArray,
|
|
126
|
-
mask: NDArray[np.bool_] | None = None,
|
|
127
|
-
threshold: int | float | Callable[[NDArray[np.number]], int | float] | None = None,
|
|
126
|
+
mask: "NDArray[np.bool_] | None" = None,
|
|
127
|
+
threshold: int | float | Callable[["NDArray[np.number]"], int | float] | None = None,
|
|
128
128
|
return_type: type[PIL_Image_or_NDArray] | str = "same",
|
|
129
129
|
contiguous: bool = True,
|
|
130
130
|
) -> Any:
|
|
@@ -207,7 +207,7 @@ def auto_crop[PIL_Image_or_NDArray](
|
|
|
207
207
|
|
|
208
208
|
# Convert to numpy array and store original type
|
|
209
209
|
original_was_pil: bool = isinstance(image, Image.Image)
|
|
210
|
-
image_array: NDArray[np.number] = np.array(image) if original_was_pil else image
|
|
210
|
+
image_array: NDArray[np.number] = np.array(image) if original_was_pil else image # type: ignore
|
|
211
211
|
|
|
212
212
|
# Create mask if not provided
|
|
213
213
|
if mask is None:
|
|
@@ -263,7 +263,7 @@ def auto_crop[PIL_Image_or_NDArray](
|
|
|
263
263
|
|
|
264
264
|
def numpy_to_gif(
|
|
265
265
|
path: str,
|
|
266
|
-
array: NDArray[np.integer | np.floating | np.bool_],
|
|
266
|
+
array: "NDArray[np.integer | np.floating | np.bool_]",
|
|
267
267
|
duration: int = 100,
|
|
268
268
|
loop: int = 0,
|
|
269
269
|
mkdir: bool = True,
|
|
@@ -344,7 +344,7 @@ def numpy_to_gif(
|
|
|
344
344
|
|
|
345
345
|
def numpy_to_obj(
|
|
346
346
|
path: str,
|
|
347
|
-
array: NDArray[np.integer | np.floating | np.bool_],
|
|
347
|
+
array: "NDArray[np.integer | np.floating | np.bool_]",
|
|
348
348
|
threshold: float = 0.5,
|
|
349
349
|
step_size: int = 1,
|
|
350
350
|
pad_array: bool = True,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: stouputils
|
|
3
|
-
Version: 1.16.
|
|
3
|
+
Version: 1.16.3
|
|
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
|
Keywords: utilities,tools,helpers,development,python
|
|
6
6
|
Author: Stoupy51
|
|
@@ -93,7 +93,7 @@ Start now by installing the package: `pip install stouputils`.<br>
|
|
|
93
93
|
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.io.html">io.py</a> <span class="comment"># 💾 Utilities for file management <span class="paren">(json_dump, json_load, csv_dump, csv_load, read_file, super_copy, super_open, clean_path, ...)</span></span>
|
|
94
94
|
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.parallel.html">parallel.py</a> <span class="comment"># 🔀 Utility functions for parallel processing <span class="paren">(multiprocessing, multithreading, run_in_subprocess)</span></span>
|
|
95
95
|
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.image.html">image.py</a> <span class="comment"># 🖼️ Little utilities for image processing <span class="paren">(image_resize, auto_crop, numpy_to_gif, numpy_to_obj)</span></span>
|
|
96
|
-
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.collections.html">collections.py</a> <span class="comment"># 🧰 Utilities for collection manipulation <span class="paren">(unique_list, sort_dict_keys, upsert_in_dataframe, array_to_disk)</span></span>
|
|
96
|
+
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.collections.html">collections.py</a> <span class="comment"># 🧰 Utilities for collection manipulation <span class="paren">(unique_list, at_least_n, sort_dict_keys, upsert_in_dataframe, array_to_disk)</span></span>
|
|
97
97
|
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.typing.html">typing.py</a> <span class="comment"># 📝 Utilities for typing enhancements <span class="paren">(IterAny, JsonDict, JsonList, ..., convert_to_serializable)</span></span>
|
|
98
98
|
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.all_doctests.html">all_doctests.py</a> <span class="comment"># ✅ Run all doctests for all modules in a given directory <span class="paren">(launch_tests, test_module_with_progress)</span></span>
|
|
99
99
|
├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.backup.html">backup.py</a> <span class="comment"># 💾 Utilities for backup management <span class="paren">(delta backup, consolidate)</span></span>
|
|
@@ -3,11 +3,11 @@ stouputils/__init__.pyi,sha256=as5qRu9FfJdJwb_DheDTq6hA5y4UfIFgPwItNfPHMwU,374
|
|
|
3
3
|
stouputils/__main__.py,sha256=MA3jjc1yL8_0Z9oB55BMqrFq1ot_-e5rNqSxFQGsMzs,2910
|
|
4
4
|
stouputils/_deprecated.py,sha256=Bcq6YjdM9Rk9Vq-WMhc_tuEbPORX6U8HAJ9Vh-VIWTA,1478
|
|
5
5
|
stouputils/_deprecated.pyi,sha256=6-8YsftJd2fRAdBLsysc6jf-uA8V2wiqkiFAbdfWfJQ,664
|
|
6
|
-
stouputils/all_doctests.py,sha256=
|
|
6
|
+
stouputils/all_doctests.py,sha256=PPh081zySANsZme52Bg3DwMqVlQpjrdgO13GctsCtFo,6328
|
|
7
7
|
stouputils/all_doctests.pyi,sha256=R3FRKaQv3sTZbxLvvsChHZZKygVMhmL6pqrYYLqvZCg,2017
|
|
8
8
|
stouputils/applications/__init__.py,sha256=dbjwZt8PZF043KoJSItqCpH32FtRxN5sgV-8Q2b1l10,457
|
|
9
9
|
stouputils/applications/__init__.pyi,sha256=DTYq2Uqq1uLzCMkFByjRqdtREA-9SaQnp4QpgmCEPFg,56
|
|
10
|
-
stouputils/applications/automatic_docs.py,sha256=
|
|
10
|
+
stouputils/applications/automatic_docs.py,sha256=_6XbCuVi2EiSdkiPZ7XHr5mUGh2ZORev8Vd0tJDb0ug,20561
|
|
11
11
|
stouputils/applications/automatic_docs.pyi,sha256=sfFXpVE5y5Z907HEjKzpZ_9zM34d-jKNDQCdMx7E-9s,6189
|
|
12
12
|
stouputils/applications/upscaler/__init__.py,sha256=8vrca93OYu5GQJrZO1GvnAbptzyhu_L0DnP3M9unlA0,1142
|
|
13
13
|
stouputils/applications/upscaler/__init__.pyi,sha256=VSp6Tq09ATCTdfnjhbDnu7lblaLLGbCNi-E22jYxa88,67
|
|
@@ -21,8 +21,8 @@ stouputils/archive.py,sha256=uDrPFxbY_C8SwUZRH4FWnYSoJKkFWynCx751zP9AHaY,12144
|
|
|
21
21
|
stouputils/archive.pyi,sha256=Z2BbQAiErRYntv53QC9uf_XPw3tx3Oy73wB0Bbil11c,3246
|
|
22
22
|
stouputils/backup.py,sha256=AE5WKMLiyk0VkRUfhmNfO2EUeUbZY5GTFVIuI5z7axA,20947
|
|
23
23
|
stouputils/backup.pyi,sha256=-SLVykkR5U8479T84zjNPVBNnV193s0zyWjathY2DDA,4923
|
|
24
|
-
stouputils/collections.py,sha256=
|
|
25
|
-
stouputils/collections.pyi,sha256=
|
|
24
|
+
stouputils/collections.py,sha256=rAIz4acCxGjZkuvUrb3u5laD130TaNKbng3AITMWffY,9851
|
|
25
|
+
stouputils/collections.pyi,sha256=g29fctQAjoJmx-CKh4S6buLSwH2SmivrTGYwc92KqxE,4323
|
|
26
26
|
stouputils/continuous_delivery/__init__.py,sha256=JqPww29xZ-pp6OJDGhUj2dxyV9rgTTMUz0YDDVr9RaA,731
|
|
27
27
|
stouputils/continuous_delivery/__init__.pyi,sha256=_Sz2D10n1CDEyY8qDFwXNKdr01HVxanY4qdq9aN19cc,117
|
|
28
28
|
stouputils/continuous_delivery/cd_utils.py,sha256=fkaHk2V3j66uFAUsM2c_UddNhXW2KAQcrh7jVsH79pU,8594
|
|
@@ -111,7 +111,7 @@ stouputils/data_science/scripts/routine.py,sha256=FkTLzmcdm_qUp69D-dPAKJm2RfXZZL
|
|
|
111
111
|
stouputils/data_science/utils.py,sha256=HFXI2RQZ53RbBOn_4Act2bi0z4xQlTtsuR5Am80v9JU,11084
|
|
112
112
|
stouputils/decorators.py,sha256=miZ8r2g8VhmQs2_knkKuUagdQabriZe7w0fCOEB69Nw,21838
|
|
113
113
|
stouputils/decorators.pyi,sha256=vbPRsvox4dotqcln3StgE6iZ1cWCOeAn56M9zMpdw2U,10948
|
|
114
|
-
stouputils/image.py,sha256=
|
|
114
|
+
stouputils/image.py,sha256=xojXhpXGee6SjvyJ77f7GBQiLskWAW6RQhB_ZhpVpAk,16628
|
|
115
115
|
stouputils/image.pyi,sha256=B7aypF1kHsEHHzwTnbcINLam32H4iJJBRxsegwt2n78,8455
|
|
116
116
|
stouputils/installer/__init__.py,sha256=DBwI9w3xvw0NR_jDMxmURwPi1F79kPLe7EuNjmrxW_U,502
|
|
117
117
|
stouputils/installer/__init__.pyi,sha256=ZB-8frAUOW-0pCEJL-e2AdbFodivv46v3EBYwEXCxRo,117
|
|
@@ -136,7 +136,7 @@ stouputils/typing.py,sha256=TwvxrvxhBRkyHkoOpfyXebN13M3xJb8MAjKXiNIWjew,2205
|
|
|
136
136
|
stouputils/typing.pyi,sha256=U2UmFZausMYpnsUQROQE2JOwHcjx2hKV0rJuOdR57Ew,1341
|
|
137
137
|
stouputils/version_pkg.py,sha256=Jsp-s03L14DkiZ94vQgrlQmaxApfn9DC8M_nzT1SJLk,7014
|
|
138
138
|
stouputils/version_pkg.pyi,sha256=QPvqp1U3QA-9C_CC1dT9Vahv1hXEhstbM7x5uzMZSsQ,755
|
|
139
|
-
stouputils-1.16.
|
|
140
|
-
stouputils-1.16.
|
|
141
|
-
stouputils-1.16.
|
|
142
|
-
stouputils-1.16.
|
|
139
|
+
stouputils-1.16.3.dist-info/WHEEL,sha256=XV0cjMrO7zXhVAIyyc8aFf1VjZ33Fen4IiJk5zFlC3g,80
|
|
140
|
+
stouputils-1.16.3.dist-info/entry_points.txt,sha256=tx0z9VOnE-sfkmbFbA93zaBMzV3XSsKEJa_BWIqUzxw,57
|
|
141
|
+
stouputils-1.16.3.dist-info/METADATA,sha256=vrF8jqYs56Ql7uRR7qcSCr17ehLFOwlL9PDL0rwH2VA,13902
|
|
142
|
+
stouputils-1.16.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|