kaparoo-python 0.1.0__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.
- kaparoo/__about__.py +3 -0
- kaparoo/__init__.py +0 -0
- kaparoo/beartype/__init__.py +0 -0
- kaparoo/beartype/numerics.py +26 -0
- kaparoo/filesystem/__init__.py +51 -0
- kaparoo/filesystem/exceptions.py +11 -0
- kaparoo/filesystem/path.py +760 -0
- kaparoo/filesystem/types.py +10 -0
- kaparoo/py.typed +0 -0
- kaparoo/utils/__init__.py +0 -0
- kaparoo/utils/optional.py +112 -0
- kaparoo/utils/types.py +15 -0
- kaparoo_python-0.1.0.dist-info/METADATA +89 -0
- kaparoo_python-0.1.0.dist-info/RECORD +16 -0
- kaparoo_python-0.1.0.dist-info/WHEEL +4 -0
- kaparoo_python-0.1.0.dist-info/licenses/LICENSE +21 -0
kaparoo/__about__.py
ADDED
kaparoo/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
__all__ = (
|
|
4
|
+
"PosInt",
|
|
5
|
+
"NegInt",
|
|
6
|
+
"NonPosInt",
|
|
7
|
+
"NonNegInt",
|
|
8
|
+
"PositiveInt",
|
|
9
|
+
"NegativeInt",
|
|
10
|
+
"NonPositiveInt",
|
|
11
|
+
"NonNegativeInt",
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
from typing import Annotated, TypeAlias
|
|
15
|
+
|
|
16
|
+
from beartype.vale import Is
|
|
17
|
+
|
|
18
|
+
NegativeInt: TypeAlias = Annotated[int, Is[lambda x: x < 0]]
|
|
19
|
+
PositiveInt: TypeAlias = Annotated[int, Is[lambda x: x > 0]]
|
|
20
|
+
NonNegativeInt: TypeAlias = Annotated[int, Is[lambda x: x >= 0]]
|
|
21
|
+
NonPositiveInt: TypeAlias = Annotated[int, Is[lambda x: x <= 0]]
|
|
22
|
+
|
|
23
|
+
NegInt: TypeAlias = NegativeInt
|
|
24
|
+
PosInt: TypeAlias = PositiveInt
|
|
25
|
+
NonPosInt: TypeAlias = NonPositiveInt
|
|
26
|
+
NonNegInt: TypeAlias = NonNegativeInt
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
__all__ = (
|
|
4
|
+
# exceptions
|
|
5
|
+
"DirectoryNotFoundError",
|
|
6
|
+
"NotAFileError",
|
|
7
|
+
# types
|
|
8
|
+
"StrPath",
|
|
9
|
+
"StrPaths",
|
|
10
|
+
# path
|
|
11
|
+
# - stringify
|
|
12
|
+
"stringify_path",
|
|
13
|
+
"stringify_paths",
|
|
14
|
+
# - single existence
|
|
15
|
+
"check_if_path_exists",
|
|
16
|
+
"check_if_file_exists",
|
|
17
|
+
"check_if_dir_exists",
|
|
18
|
+
# - multiple existences
|
|
19
|
+
"check_if_paths_exist",
|
|
20
|
+
"check_if_files_exist",
|
|
21
|
+
"check_if_dirs_exist",
|
|
22
|
+
# - child path(s) search
|
|
23
|
+
"get_paths",
|
|
24
|
+
"get_files",
|
|
25
|
+
"get_dirs",
|
|
26
|
+
# - empty directory check
|
|
27
|
+
"is_empty_dir",
|
|
28
|
+
"is_empty_dir_unsafe",
|
|
29
|
+
"are_empty_dirs",
|
|
30
|
+
"are_empty_dirs_unsafe",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
from kaparoo.filesystem.exceptions import DirectoryNotFoundError, NotAFileError
|
|
34
|
+
from kaparoo.filesystem.path import (
|
|
35
|
+
are_empty_dirs,
|
|
36
|
+
are_empty_dirs_unsafe,
|
|
37
|
+
check_if_dir_exists,
|
|
38
|
+
check_if_dirs_exist,
|
|
39
|
+
check_if_file_exists,
|
|
40
|
+
check_if_files_exist,
|
|
41
|
+
check_if_path_exists,
|
|
42
|
+
check_if_paths_exist,
|
|
43
|
+
get_dirs,
|
|
44
|
+
get_files,
|
|
45
|
+
get_paths,
|
|
46
|
+
is_empty_dir,
|
|
47
|
+
is_empty_dir_unsafe,
|
|
48
|
+
stringify_path,
|
|
49
|
+
stringify_paths,
|
|
50
|
+
)
|
|
51
|
+
from kaparoo.filesystem.types import StrPath, StrPaths
|
|
@@ -0,0 +1,760 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = (
|
|
6
|
+
# stringify
|
|
7
|
+
"stringify_path",
|
|
8
|
+
"stringify_paths",
|
|
9
|
+
# single existence
|
|
10
|
+
"check_if_path_exists",
|
|
11
|
+
"check_if_file_exists",
|
|
12
|
+
"check_if_dir_exists",
|
|
13
|
+
# multiple existences
|
|
14
|
+
"check_if_paths_exist",
|
|
15
|
+
"check_if_files_exist",
|
|
16
|
+
"check_if_dirs_exist",
|
|
17
|
+
# child path(s) search
|
|
18
|
+
"get_paths",
|
|
19
|
+
"get_files",
|
|
20
|
+
"get_dirs",
|
|
21
|
+
# empty directory check
|
|
22
|
+
"is_empty_dir",
|
|
23
|
+
"is_empty_dir_unsafe",
|
|
24
|
+
"are_empty_dirs",
|
|
25
|
+
"are_empty_dirs_unsafe",
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
import os
|
|
29
|
+
import random
|
|
30
|
+
from collections.abc import Sequence
|
|
31
|
+
from pathlib import Path
|
|
32
|
+
from typing import TYPE_CHECKING, overload
|
|
33
|
+
|
|
34
|
+
from kaparoo.filesystem.exceptions import DirectoryNotFoundError, NotAFileError
|
|
35
|
+
|
|
36
|
+
if TYPE_CHECKING:
|
|
37
|
+
from collections.abc import Callable
|
|
38
|
+
from typing import Literal
|
|
39
|
+
|
|
40
|
+
from kaparoo.filesystem.types import StrPath, StrPaths
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# ========================== #
|
|
44
|
+
# Stringify #
|
|
45
|
+
# ========================== #
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def stringify_path(path: StrPath) -> str:
|
|
49
|
+
"""Convert a path to a string representation."""
|
|
50
|
+
return os.fspath(path)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def stringify_paths(paths: StrPaths) -> Sequence[str]:
|
|
54
|
+
"""Convert a sequence of paths to a sequence of string representations."""
|
|
55
|
+
return [stringify_path(p) for p in paths]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# ========================== #
|
|
59
|
+
# Single Existence #
|
|
60
|
+
# ========================== #
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@overload
|
|
64
|
+
def check_if_path_exists(path: StrPath, *, stringify: Literal[False] = False) -> Path:
|
|
65
|
+
...
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@overload
|
|
69
|
+
def check_if_path_exists(path: StrPath, *, stringify: Literal[True]) -> str:
|
|
70
|
+
...
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@overload
|
|
74
|
+
def check_if_path_exists(path: StrPath, *, stringify: bool) -> Path | str:
|
|
75
|
+
...
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def check_if_path_exists(path: StrPath, *, stringify: bool = False) -> Path | str:
|
|
79
|
+
"""Check if a given path exists and return it as a `Path` object.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
path: The path to check for existence.
|
|
83
|
+
stringify: Whether to return the path as a string. Defaults to `False`.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
The path as a `Path` object or a string, depending on the value of `stringify`.
|
|
87
|
+
|
|
88
|
+
Raises:
|
|
89
|
+
FileNotFoundError: If the path does not exist.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
if not (path := Path(path)).exists():
|
|
93
|
+
raise FileNotFoundError(f"no such path: {path}")
|
|
94
|
+
|
|
95
|
+
return stringify_path(path) if stringify else path
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@overload
|
|
99
|
+
def check_if_file_exists(path: StrPath, *, stringify: Literal[False] = False) -> Path:
|
|
100
|
+
...
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@overload
|
|
104
|
+
def check_if_file_exists(path: StrPath, *, stringify: Literal[True]) -> str:
|
|
105
|
+
...
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@overload
|
|
109
|
+
def check_if_file_exists(path: StrPath, *, stringify: bool) -> Path | str:
|
|
110
|
+
...
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def check_if_file_exists(path: StrPath, *, stringify: bool = False) -> Path | str:
|
|
114
|
+
"""Check if a given path exists and is a file, and return it as a `Path` object.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
path: The file path to check for existence.
|
|
118
|
+
stringify: Whether to return the path as a string. Defaults to `False`.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
The path as a `Path` object or a string, depending on the value of `stringify`.
|
|
122
|
+
|
|
123
|
+
Raises:
|
|
124
|
+
FileNotFoundError: If the path does not exist.
|
|
125
|
+
NotAFileError: If the path exists but is not a file.
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
if not (path := Path(path)).exists():
|
|
129
|
+
raise FileNotFoundError(f"no such file: {path}")
|
|
130
|
+
elif not path.is_file():
|
|
131
|
+
raise NotAFileError(f"not a file: {path}")
|
|
132
|
+
|
|
133
|
+
return stringify_path(path) if stringify else path
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@overload
|
|
137
|
+
def check_if_dir_exists(
|
|
138
|
+
path: StrPath, *, make: bool | int = False, stringify: Literal[False] = False
|
|
139
|
+
) -> Path:
|
|
140
|
+
...
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@overload
|
|
144
|
+
def check_if_dir_exists(
|
|
145
|
+
path: StrPath, *, make: bool | int = False, stringify: Literal[True]
|
|
146
|
+
) -> str:
|
|
147
|
+
...
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@overload
|
|
151
|
+
def check_if_dir_exists(
|
|
152
|
+
path: StrPath, *, make: bool | int = False, stringify: bool
|
|
153
|
+
) -> Path | str:
|
|
154
|
+
...
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def check_if_dir_exists(
|
|
158
|
+
path: StrPath, *, make: bool | int = False, stringify: bool = False
|
|
159
|
+
) -> Path | str:
|
|
160
|
+
"""Check if a given path exists and is a directory, and return it as a `Path` object.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
path: The directory path to check for existence.
|
|
164
|
+
make: Whether to create the directory if it does not exist. If an `int` is provided,
|
|
165
|
+
use it as the octal mode for the directory. Defaults to `False`.
|
|
166
|
+
stringify: Whether to return the path as a string. Defaults to `False`.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
The path as a `Path` object or a string, depending on the value of `stringify`.
|
|
170
|
+
|
|
171
|
+
Raises:
|
|
172
|
+
DirectoryNotFoundError: If the path does not exist and `make` is False.
|
|
173
|
+
NotADirectoryError: If the path exists but is not a directory.
|
|
174
|
+
""" # noqa: E501
|
|
175
|
+
|
|
176
|
+
if not (path := Path(path)).exists():
|
|
177
|
+
if make is False:
|
|
178
|
+
raise DirectoryNotFoundError(f"no such directory: {path}")
|
|
179
|
+
path.mkdir(mode=511 if make is True else make, parents=True) # 511 == 0o777
|
|
180
|
+
elif not path.is_dir():
|
|
181
|
+
raise NotADirectoryError(f"not a directory: {path}")
|
|
182
|
+
|
|
183
|
+
return stringify_path(path) if stringify else path
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# ========================== #
|
|
187
|
+
# Multiple Existences #
|
|
188
|
+
# ========================== #
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
@overload
|
|
192
|
+
def check_if_paths_exist(
|
|
193
|
+
paths: StrPaths,
|
|
194
|
+
*,
|
|
195
|
+
root: StrPath | None = None,
|
|
196
|
+
stringify: Literal[False] = False,
|
|
197
|
+
) -> Sequence[Path]:
|
|
198
|
+
...
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@overload
|
|
202
|
+
def check_if_paths_exist(
|
|
203
|
+
paths: StrPaths, *, root: StrPath | None = None, stringify: Literal[True]
|
|
204
|
+
) -> Sequence[str]:
|
|
205
|
+
...
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@overload
|
|
209
|
+
def check_if_paths_exist(
|
|
210
|
+
paths: StrPaths, *, root: StrPath | None = None, stringify: bool
|
|
211
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
212
|
+
...
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def check_if_paths_exist(
|
|
216
|
+
paths: StrPaths, *, root: StrPath | None = None, stringify: bool = False
|
|
217
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
218
|
+
"""Check if multiple paths exist and return them as a sequence of `Path` objects.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
paths: A sequence of paths to check for existence.
|
|
222
|
+
root: The root directory to resolve relative paths. If provided, the `paths`
|
|
223
|
+
will be resolved relative to the `root` directory. Defaults to `None`.
|
|
224
|
+
stringify: Whether to return a sequence of strings. Defaults to `False`.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
The paths as a sequence of `Path` objects or a sequence of strings,
|
|
228
|
+
depending on the value of `stringify`.
|
|
229
|
+
|
|
230
|
+
Raises:
|
|
231
|
+
DirectoryNotFoundError: If the `root` directory does not exist.
|
|
232
|
+
NotADirectoryError: If `root` exists but is not a directory.
|
|
233
|
+
FileNotFoundError: If any of the paths does not exist.
|
|
234
|
+
"""
|
|
235
|
+
|
|
236
|
+
if root is not None:
|
|
237
|
+
root = check_if_dir_exists(root)
|
|
238
|
+
paths = [root / p for p in paths]
|
|
239
|
+
|
|
240
|
+
paths = [check_if_path_exists(p) for p in paths]
|
|
241
|
+
|
|
242
|
+
return stringify_paths(paths) if stringify else paths
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
@overload
|
|
246
|
+
def check_if_files_exist(
|
|
247
|
+
paths: StrPaths,
|
|
248
|
+
*,
|
|
249
|
+
root: StrPath | None = None,
|
|
250
|
+
stringify: Literal[False] = False,
|
|
251
|
+
) -> Sequence[Path]:
|
|
252
|
+
...
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@overload
|
|
256
|
+
def check_if_files_exist(
|
|
257
|
+
paths: StrPaths, *, root: StrPath | None = None, stringify: Literal[True]
|
|
258
|
+
) -> Sequence[str]:
|
|
259
|
+
...
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
@overload
|
|
263
|
+
def check_if_files_exist(
|
|
264
|
+
paths: StrPaths, *, root: StrPath | None = None, stringify: bool
|
|
265
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
266
|
+
...
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def check_if_files_exist(
|
|
270
|
+
paths: StrPaths, *, root: StrPath | None = None, stringify: bool = False
|
|
271
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
272
|
+
"""Check if multiple files exist and return them as a sequence of `Path` objects.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
paths: A sequence of file paths to check for existence.
|
|
276
|
+
root: The root directory to resolve relative paths. If provided, the `paths`
|
|
277
|
+
will be resolved relative to the `root` directory. Defaults to `None`.
|
|
278
|
+
stringify: Whether to return a sequence of strings. Defaults to `False`.
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
The file paths as a sequence of `Path` objects or a sequence of strings,
|
|
282
|
+
depending on the value of `stringify`.
|
|
283
|
+
|
|
284
|
+
Raises:
|
|
285
|
+
DirectoryNotFoundError: If the `root` directory does not exist.
|
|
286
|
+
NotADirectoryError: If `root` exists but is not a directory.
|
|
287
|
+
FileNotFoundError: If any of the file paths does not exist.
|
|
288
|
+
NotAFileError: If any of the paths exists but is not a file.
|
|
289
|
+
""" # noqa: E501
|
|
290
|
+
|
|
291
|
+
if root is not None:
|
|
292
|
+
root = check_if_dir_exists(root)
|
|
293
|
+
paths = [root / p for p in paths]
|
|
294
|
+
|
|
295
|
+
paths = [check_if_file_exists(p) for p in paths]
|
|
296
|
+
|
|
297
|
+
return stringify_paths(paths) if stringify else paths
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
@overload
|
|
301
|
+
def check_if_dirs_exist(
|
|
302
|
+
paths: StrPaths,
|
|
303
|
+
*,
|
|
304
|
+
root: StrPath | None = None,
|
|
305
|
+
make: bool | int = False,
|
|
306
|
+
stringify: Literal[False] = False,
|
|
307
|
+
) -> Sequence[Path]:
|
|
308
|
+
...
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
@overload
|
|
312
|
+
def check_if_dirs_exist(
|
|
313
|
+
paths: StrPaths,
|
|
314
|
+
*,
|
|
315
|
+
root: StrPath | None = None,
|
|
316
|
+
make: bool | int = False,
|
|
317
|
+
stringify: Literal[True],
|
|
318
|
+
) -> Sequence[str]:
|
|
319
|
+
...
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
@overload
|
|
323
|
+
def check_if_dirs_exist(
|
|
324
|
+
paths: StrPaths,
|
|
325
|
+
*,
|
|
326
|
+
root: StrPath | None = None,
|
|
327
|
+
make: bool | int = False,
|
|
328
|
+
stringify: bool,
|
|
329
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
330
|
+
...
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def check_if_dirs_exist(
|
|
334
|
+
paths: StrPaths,
|
|
335
|
+
*,
|
|
336
|
+
root: StrPath | None = None,
|
|
337
|
+
make: bool | int = False,
|
|
338
|
+
stringify: bool = False,
|
|
339
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
340
|
+
"""Check if multiple directories exist and return them as a sequence of `Path` objects.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
paths: A sequence of directory paths to check for existence.
|
|
344
|
+
root: The root directory to resolve relative paths. If provided, the `paths`
|
|
345
|
+
will be resolved relative to the `root` directory. Defaults to `None`.
|
|
346
|
+
make: Whether to create the directory if it does not exist. If an `int` is provided,
|
|
347
|
+
use it as the octal mode for the directory. Defaults to `False`.
|
|
348
|
+
stringify: Whether to return a sequence of strings. Defaults to `False`.
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
The directory paths as a sequence of `Path` objects or a sequence of strings,
|
|
352
|
+
depending on the value of `stringify`.
|
|
353
|
+
|
|
354
|
+
Raises:
|
|
355
|
+
DirectoryNotFoundError: If the `root` directory does not exist
|
|
356
|
+
DirectoryNotFoundError: If any of the directory paths does not exist.
|
|
357
|
+
NotADirectoryError: If `root` exists but is not a directory.
|
|
358
|
+
NotADirectoryError: If any of the paths exists but is not a directory.
|
|
359
|
+
""" # noqa: E501
|
|
360
|
+
|
|
361
|
+
if root is not None:
|
|
362
|
+
root = check_if_dir_exists(root)
|
|
363
|
+
paths = [root / p for p in paths]
|
|
364
|
+
|
|
365
|
+
paths = [check_if_dir_exists(p, make=make) for p in paths]
|
|
366
|
+
|
|
367
|
+
return stringify_paths(paths) if stringify else paths
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
# ========================== #
|
|
371
|
+
# Child Path(s) Search #
|
|
372
|
+
# ========================== #
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
@overload
|
|
376
|
+
def get_paths(
|
|
377
|
+
root: StrPath,
|
|
378
|
+
*,
|
|
379
|
+
pattern: str | None = None,
|
|
380
|
+
num_samples: int | None = None,
|
|
381
|
+
ignores: StrPaths | None = None,
|
|
382
|
+
condition: Callable[[Path], bool] | None = None,
|
|
383
|
+
recursive: bool = True,
|
|
384
|
+
stringify: Literal[False] = False,
|
|
385
|
+
) -> Sequence[Path]:
|
|
386
|
+
...
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
@overload
|
|
390
|
+
def get_paths(
|
|
391
|
+
root: StrPath,
|
|
392
|
+
*,
|
|
393
|
+
pattern: str | None = None,
|
|
394
|
+
num_samples: int | None = None,
|
|
395
|
+
ignores: StrPaths | None = None,
|
|
396
|
+
condition: Callable[[Path], bool] | None = None,
|
|
397
|
+
recursive: bool = True,
|
|
398
|
+
stringify: Literal[True],
|
|
399
|
+
) -> Sequence[str]:
|
|
400
|
+
...
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
@overload
|
|
404
|
+
def get_paths(
|
|
405
|
+
root: StrPath,
|
|
406
|
+
*,
|
|
407
|
+
pattern: str | None = None,
|
|
408
|
+
num_samples: int | None = None,
|
|
409
|
+
ignores: StrPaths | None = None,
|
|
410
|
+
condition: Callable[[Path], bool] | None = None,
|
|
411
|
+
recursive: bool = True,
|
|
412
|
+
stringify: bool,
|
|
413
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
414
|
+
...
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def get_paths(
|
|
418
|
+
root: StrPath,
|
|
419
|
+
*,
|
|
420
|
+
pattern: str | None = None,
|
|
421
|
+
num_samples: int | None = None,
|
|
422
|
+
ignores: StrPaths | None = None,
|
|
423
|
+
condition: Callable[[Path], bool] | None = None,
|
|
424
|
+
recursive: bool = True,
|
|
425
|
+
stringify: bool = False,
|
|
426
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
427
|
+
"""Get paths of files or directories in a given directory.
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
root: The directory to search for paths.
|
|
431
|
+
pattern: A glob pattern to match the paths against. Defaults to `None` and
|
|
432
|
+
automatically uses "*" to list all paths included in the `root` directory.
|
|
433
|
+
num_samples: A maximum number of paths to return. If given and its value is
|
|
434
|
+
smaller than the total number of paths, only the `num_samples` paths of the
|
|
435
|
+
total are randomly selected and returned. Hence, even using the same value
|
|
436
|
+
of `num_samples`, may return a different result. Defaults to `None`.
|
|
437
|
+
ignores: A sequence of paths to ignore. If any path in `ignores` does not start
|
|
438
|
+
with `root`, it is treated as a relative path. For example, `any/path` is
|
|
439
|
+
treated as `root/any/path`. Defaults to `None`.
|
|
440
|
+
condition: A predicate that takes a `Path` object and decides whether to include
|
|
441
|
+
the path in the results. Defaults to `None`.
|
|
442
|
+
recursive: Whether to search for paths recursively in subdirectories of the
|
|
443
|
+
`root` directory. Defaults to `True`.
|
|
444
|
+
stringify: Whether to return a sequence of strings. Defaults to `False`.
|
|
445
|
+
|
|
446
|
+
Returns:
|
|
447
|
+
The paths that match the specified criteria as a sequence of `Path` objects or a
|
|
448
|
+
sequence of strings, depending on the value of `stringify`.
|
|
449
|
+
|
|
450
|
+
Raises:
|
|
451
|
+
DirectoryNotFoundError: If `root` does not exist.
|
|
452
|
+
NotADirectoryError: If `root` exists but is not a directory.
|
|
453
|
+
ValueError: If `num_samples` is not a positive int.
|
|
454
|
+
""" # noqa: E501
|
|
455
|
+
|
|
456
|
+
root = check_if_dir_exists(root)
|
|
457
|
+
|
|
458
|
+
if not isinstance(pattern, str):
|
|
459
|
+
pattern = "*"
|
|
460
|
+
|
|
461
|
+
matched = root.rglob(pattern) if recursive else root.glob(pattern)
|
|
462
|
+
paths = [p for p in matched]
|
|
463
|
+
|
|
464
|
+
if root in paths:
|
|
465
|
+
paths.remove(root)
|
|
466
|
+
|
|
467
|
+
if not ignores:
|
|
468
|
+
ignores = []
|
|
469
|
+
|
|
470
|
+
for ignore in ignores:
|
|
471
|
+
ignore_path = Path(ignore)
|
|
472
|
+
if root not in ignore_path.parents:
|
|
473
|
+
ignore_path = root / ignore_path
|
|
474
|
+
|
|
475
|
+
if ignore_path in paths:
|
|
476
|
+
paths.remove(ignore_path)
|
|
477
|
+
|
|
478
|
+
if callable(condition):
|
|
479
|
+
paths = [p for p in paths if condition(p)]
|
|
480
|
+
|
|
481
|
+
if isinstance(num_samples, int) and num_samples < len(paths):
|
|
482
|
+
if num_samples <= 0:
|
|
483
|
+
raise ValueError("`num_samples` must be a positive int")
|
|
484
|
+
paths = random.sample(paths, num_samples)
|
|
485
|
+
|
|
486
|
+
return stringify_paths(paths) if stringify else paths
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
@overload
|
|
490
|
+
def get_files(
|
|
491
|
+
root: StrPath,
|
|
492
|
+
*,
|
|
493
|
+
pattern: str | None = None,
|
|
494
|
+
num_samples: int | None = None,
|
|
495
|
+
ignores: StrPaths | None = None,
|
|
496
|
+
condition: Callable[[Path], bool] | None = None,
|
|
497
|
+
recursive: bool = True,
|
|
498
|
+
stringify: Literal[False] = False,
|
|
499
|
+
) -> Sequence[Path]:
|
|
500
|
+
...
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
@overload
|
|
504
|
+
def get_files(
|
|
505
|
+
root: StrPath,
|
|
506
|
+
*,
|
|
507
|
+
pattern: str | None = None,
|
|
508
|
+
num_samples: int | None = None,
|
|
509
|
+
ignores: StrPaths | None = None,
|
|
510
|
+
condition: Callable[[Path], bool] | None = None,
|
|
511
|
+
recursive: bool = True,
|
|
512
|
+
stringify: Literal[True],
|
|
513
|
+
) -> Sequence[str]:
|
|
514
|
+
...
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
@overload
|
|
518
|
+
def get_files(
|
|
519
|
+
root: StrPath,
|
|
520
|
+
*,
|
|
521
|
+
pattern: str | None = None,
|
|
522
|
+
num_samples: int | None = None,
|
|
523
|
+
ignores: StrPaths | None = None,
|
|
524
|
+
condition: Callable[[Path], bool] | None = None,
|
|
525
|
+
recursive: bool = True,
|
|
526
|
+
stringify: bool,
|
|
527
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
528
|
+
...
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
def get_files(
|
|
532
|
+
root: StrPath,
|
|
533
|
+
*,
|
|
534
|
+
pattern: str | None = None,
|
|
535
|
+
num_samples: int | None = None,
|
|
536
|
+
ignores: StrPaths | None = None,
|
|
537
|
+
condition: Callable[[Path], bool] | None = None,
|
|
538
|
+
recursive: bool = True,
|
|
539
|
+
stringify: bool = False,
|
|
540
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
541
|
+
"""Get paths of files in a given directory.
|
|
542
|
+
|
|
543
|
+
Args:
|
|
544
|
+
root: The directory to search for paths.
|
|
545
|
+
pattern: A glob pattern to match the paths against. Defaults to `None` and
|
|
546
|
+
automatically uses "*" to list all paths included in the `root` directory.
|
|
547
|
+
num_samples: A maximum number of paths to return. If given and its value is
|
|
548
|
+
smaller than the total number of paths, only the `num_samples` paths of the
|
|
549
|
+
total are randomly selected and returned. Hence, even using the same value
|
|
550
|
+
of `num_samples`, may return a different result. Defaults to `None`.
|
|
551
|
+
ignores: A sequence of paths to ignore. If any path in `ignores` does not start
|
|
552
|
+
with `root`, it is treated as a relative path. For example, `any/path` is
|
|
553
|
+
treated as `root/any/path`. Defaults to `None`.
|
|
554
|
+
condition: A predicate that takes a `Path` object and decides whether to include
|
|
555
|
+
the path in the results. Defaults to `None`.
|
|
556
|
+
recursive: Whether to search for paths recursively in subdirectories of the
|
|
557
|
+
`root` directory. Defaults to `True`.
|
|
558
|
+
stringify: Whether to return a sequence of strings. Defaults to `False`.
|
|
559
|
+
|
|
560
|
+
Returns:
|
|
561
|
+
The file paths that match the specified criteria as a sequence of `Path` objects
|
|
562
|
+
or a sequence of strings, depending on the value of `stringify`.
|
|
563
|
+
|
|
564
|
+
Raises:
|
|
565
|
+
DirectoryNotFoundError: If `root` does not exist.
|
|
566
|
+
NotADirectoryError: If `root` exists but is not a directory.
|
|
567
|
+
ValueError: If `num_samples` is not a positive int.
|
|
568
|
+
""" # noqa: E501
|
|
569
|
+
|
|
570
|
+
if not callable(condition):
|
|
571
|
+
file_condition = lambda p: p.is_file() # noqa: E731
|
|
572
|
+
else:
|
|
573
|
+
file_condition = lambda p: p.is_file() and condition(p) # type: ignore[misc] # noqa: E501, E731
|
|
574
|
+
|
|
575
|
+
file_paths = get_paths(
|
|
576
|
+
root,
|
|
577
|
+
pattern=pattern,
|
|
578
|
+
num_samples=num_samples,
|
|
579
|
+
ignores=ignores,
|
|
580
|
+
condition=file_condition,
|
|
581
|
+
recursive=recursive,
|
|
582
|
+
stringify=stringify,
|
|
583
|
+
)
|
|
584
|
+
|
|
585
|
+
return file_paths
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
@overload
|
|
589
|
+
def get_dirs(
|
|
590
|
+
root: StrPath,
|
|
591
|
+
*,
|
|
592
|
+
pattern: str | None = None,
|
|
593
|
+
num_samples: int | None = None,
|
|
594
|
+
ignores: StrPaths | None = None,
|
|
595
|
+
condition: Callable[[Path], bool] | None = None,
|
|
596
|
+
recursive: bool = True,
|
|
597
|
+
stringify: Literal[False] = False,
|
|
598
|
+
) -> Sequence[Path]:
|
|
599
|
+
...
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
@overload
|
|
603
|
+
def get_dirs(
|
|
604
|
+
root: StrPath,
|
|
605
|
+
*,
|
|
606
|
+
pattern: str | None = None,
|
|
607
|
+
num_samples: int | None = None,
|
|
608
|
+
ignores: StrPaths | None = None,
|
|
609
|
+
condition: Callable[[Path], bool] | None = None,
|
|
610
|
+
recursive: bool = True,
|
|
611
|
+
stringify: Literal[True],
|
|
612
|
+
) -> Sequence[str]:
|
|
613
|
+
...
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
@overload
|
|
617
|
+
def get_dirs(
|
|
618
|
+
root: StrPath,
|
|
619
|
+
*,
|
|
620
|
+
pattern: str | None = None,
|
|
621
|
+
num_samples: int | None = None,
|
|
622
|
+
ignores: StrPaths | None = None,
|
|
623
|
+
condition: Callable[[Path], bool] | None = None,
|
|
624
|
+
recursive: bool = True,
|
|
625
|
+
stringify: bool,
|
|
626
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
627
|
+
...
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
def get_dirs(
|
|
631
|
+
root: StrPath,
|
|
632
|
+
*,
|
|
633
|
+
pattern: str | None = None,
|
|
634
|
+
num_samples: int | None = None,
|
|
635
|
+
ignores: StrPaths | None = None,
|
|
636
|
+
condition: Callable[[Path], bool] | None = None,
|
|
637
|
+
recursive: bool = True,
|
|
638
|
+
stringify: bool = False,
|
|
639
|
+
) -> Sequence[Path] | Sequence[str]:
|
|
640
|
+
"""Get paths of directories in a given directory.
|
|
641
|
+
|
|
642
|
+
Args:
|
|
643
|
+
root: The directory to search for paths.
|
|
644
|
+
pattern: A glob pattern to match the paths against. Defaults to `None` and
|
|
645
|
+
automatically uses "*" to list all paths included in the `root` directory.
|
|
646
|
+
num_samples: A maximum number of paths to return. If given and its value is
|
|
647
|
+
smaller than the total number of paths, only the `num_samples` paths of the
|
|
648
|
+
total are randomly selected and returned. Hence, even using the same value
|
|
649
|
+
of `num_samples`, may return a different result. Defaults to `None`.
|
|
650
|
+
ignores: A sequence of paths to ignore. If any path in `ignores` does not start
|
|
651
|
+
with `root`, it is treated as a relative path. For example, `any/path` is
|
|
652
|
+
treated as `root/any/path`. Defaults to `None`.
|
|
653
|
+
condition: A predicate that takes a `Path` object and decides whether to include
|
|
654
|
+
the path in the results. Defaults to `None`.
|
|
655
|
+
recursive: Whether to search for paths recursively in subdirectories of the
|
|
656
|
+
`root` directory. Defaults to `True`.
|
|
657
|
+
stringify: Whether to return a sequence of strings. Defaults to `False`.
|
|
658
|
+
|
|
659
|
+
Returns:
|
|
660
|
+
The directory paths that match the specified criteria as a sequence of `Path`
|
|
661
|
+
objects or a sequence of strings, depending on the value of `stringify`.
|
|
662
|
+
|
|
663
|
+
Raises:
|
|
664
|
+
DirectoryNotFoundError: If `root` does not exist.
|
|
665
|
+
NotADirectoryError: If `root` exists but is not a directory.
|
|
666
|
+
ValueError: If `num_samples` is not a positive int.
|
|
667
|
+
""" # noqa: E501
|
|
668
|
+
|
|
669
|
+
if not callable(condition):
|
|
670
|
+
dir_condition = lambda p: p.is_dir() # noqa: E731
|
|
671
|
+
else:
|
|
672
|
+
dir_condition = lambda p: p.is_dir() and condition(p) # type: ignore[misc] # noqa: E501, E731
|
|
673
|
+
|
|
674
|
+
dir_paths = get_paths(
|
|
675
|
+
root,
|
|
676
|
+
pattern=pattern,
|
|
677
|
+
num_samples=num_samples,
|
|
678
|
+
ignores=ignores,
|
|
679
|
+
condition=dir_condition,
|
|
680
|
+
recursive=recursive,
|
|
681
|
+
stringify=stringify,
|
|
682
|
+
)
|
|
683
|
+
|
|
684
|
+
return dir_paths
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
# ========================== #
|
|
688
|
+
# Empty Directory Check #
|
|
689
|
+
# ========================== #
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
def is_empty_dir_unsafe(path: StrPath) -> bool:
|
|
693
|
+
"""Check if a directory is empty.
|
|
694
|
+
|
|
695
|
+
Unlike the function `is_empty_dir()`, this function does not check the existence of
|
|
696
|
+
the input argument `path`. Use this function only if you are sure it exists.
|
|
697
|
+
|
|
698
|
+
Args:
|
|
699
|
+
path: The path to the directory.
|
|
700
|
+
|
|
701
|
+
Returns:
|
|
702
|
+
A boolean indicating whether the directory is empty.
|
|
703
|
+
"""
|
|
704
|
+
return not os.listdir(path)
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
def is_empty_dir(path: StrPath) -> bool:
|
|
708
|
+
"""Check if a directory is empty.
|
|
709
|
+
|
|
710
|
+
Args:
|
|
711
|
+
path: The path to the directory.
|
|
712
|
+
|
|
713
|
+
Returns:
|
|
714
|
+
A boolean indicating whether the directory is empty.
|
|
715
|
+
|
|
716
|
+
Raises:
|
|
717
|
+
DirectoryNotFoundError: If the directory does not exist.
|
|
718
|
+
NotADirectoryError: If `path` exists but is not a directory.
|
|
719
|
+
"""
|
|
720
|
+
path = check_if_dir_exists(path)
|
|
721
|
+
return is_empty_dir_unsafe(path)
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
def are_empty_dirs_unsafe(paths: StrPaths, *, root: StrPath | None = None) -> bool:
|
|
725
|
+
"""Check if multiple directories are empty.
|
|
726
|
+
|
|
727
|
+
Unlike the function `are_empty_dirs()`, this function does not check the existence
|
|
728
|
+
of the input arguments `paths` and `root`. Use this function only if you are sure
|
|
729
|
+
they exist.
|
|
730
|
+
|
|
731
|
+
Args:
|
|
732
|
+
paths: A sequence of directory paths to check.
|
|
733
|
+
root: The root directory to resolve relative paths. Defaults to `None`.
|
|
734
|
+
|
|
735
|
+
Returns:
|
|
736
|
+
A boolean indicating whether all directories are empty.
|
|
737
|
+
"""
|
|
738
|
+
if root is not None:
|
|
739
|
+
paths = [os.path.join(root, p) for p in paths]
|
|
740
|
+
return all(is_empty_dir_unsafe(p) for p in paths)
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
def are_empty_dirs(paths: StrPaths, *, root: StrPath | None = None) -> bool:
|
|
744
|
+
"""Check if multiple directories are empty.
|
|
745
|
+
|
|
746
|
+
Args:
|
|
747
|
+
paths: A sequence of directory paths to check.
|
|
748
|
+
root: The root directory to resolve relative paths. Defaults to `None`.
|
|
749
|
+
|
|
750
|
+
Returns:
|
|
751
|
+
A boolean indicating whether all directories are empty.
|
|
752
|
+
|
|
753
|
+
Raises:
|
|
754
|
+
DirectoryNotFoundError: If the `root` directory does not exist.
|
|
755
|
+
DirectoryNotFoundError: If any of the directory paths does not exist.
|
|
756
|
+
NotADirectoryError: If `root` exists but is not a directory.
|
|
757
|
+
NotADirectoryError: If any of the paths exists but is not a directory.
|
|
758
|
+
"""
|
|
759
|
+
paths = check_if_dirs_exist(paths, root=root)
|
|
760
|
+
return all(is_empty_dir_unsafe(p) for p in paths)
|
kaparoo/py.typed
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = (
|
|
6
|
+
"replace_if_none",
|
|
7
|
+
"factory_if_none",
|
|
8
|
+
"unwrap_or_default",
|
|
9
|
+
"unwrap_or_factory",
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from typing import TYPE_CHECKING, overload
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from collections.abc import Callable
|
|
16
|
+
|
|
17
|
+
from kaparoo.utils.types import T, U
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@overload
|
|
21
|
+
def replace_if_none(optional: None, surrogate: U) -> U:
|
|
22
|
+
...
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@overload
|
|
26
|
+
def replace_if_none(optional: T, surrogate: U) -> T:
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def replace_if_none(optional: T | None, surrogate: U) -> T | U:
|
|
31
|
+
"""Replace the value with a surrogate if it is None.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
optional: The optional value to be checked.
|
|
35
|
+
surrogate: The surrogate value to use if `optional` is None.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
The `optional` value if it is not None, otherwise the `surrogate` value.
|
|
39
|
+
"""
|
|
40
|
+
return surrogate if optional is None else optional
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@overload
|
|
44
|
+
def factory_if_none(
|
|
45
|
+
optional: None,
|
|
46
|
+
factory: Callable[[], U],
|
|
47
|
+
) -> U:
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@overload
|
|
52
|
+
def factory_if_none(
|
|
53
|
+
optional: T,
|
|
54
|
+
factory: Callable[[], U],
|
|
55
|
+
) -> T:
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def factory_if_none(
|
|
60
|
+
optional: T | None,
|
|
61
|
+
factory: Callable[[], U],
|
|
62
|
+
) -> T | U:
|
|
63
|
+
"""Create a value using a factory if the optional value is None.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
optional: The optional value to be checked.
|
|
67
|
+
factory: A callable that returns the value to be used if `optional` is None.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
The `optional` value if it is not None, otherwise the value returned by `factory`.
|
|
71
|
+
""" # noqa: E501
|
|
72
|
+
return factory() if optional is None else optional
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def unwrap_or_default(
|
|
76
|
+
optional: T | None,
|
|
77
|
+
default: T,
|
|
78
|
+
callback: Callable[[T], T] | None = None,
|
|
79
|
+
) -> T:
|
|
80
|
+
"""Unwrap the value or return a default value if it is None.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
optional: The optional value to be checked.
|
|
84
|
+
default: The default value to be returned if `optional` is None.
|
|
85
|
+
callback: An optional callable to be applied to the result. Defaults to None.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
The `optional` value if it is not None, otherwise the `default` value.
|
|
89
|
+
If a `callback` is provided, it is applied to the result before returning.
|
|
90
|
+
"""
|
|
91
|
+
result = replace_if_none(optional, default)
|
|
92
|
+
return callback(result) if callable(callback) else result
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def unwrap_or_factory(
|
|
96
|
+
optional: T | None,
|
|
97
|
+
factory: Callable[[], T],
|
|
98
|
+
callback: Callable[[T], T] | None = None,
|
|
99
|
+
) -> T:
|
|
100
|
+
"""Unwrap the value or create a value using a factory if it is None.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
optional: The optional value to be checked.
|
|
104
|
+
factory: A callable that returns the value to be used if `optional` is None.
|
|
105
|
+
callback: An optional callable to be applied to the result. Defaults to None.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
The `optional` value if it is not None, otherwise the value returned by `factory`.
|
|
109
|
+
If a `callback` is provided, it is applied to the result before returning.
|
|
110
|
+
""" # noqa: E501
|
|
111
|
+
result = factory_if_none(optional, factory)
|
|
112
|
+
return callback(result) if callable(callback) else result
|
kaparoo/utils/types.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from typing import TypeVar
|
|
4
|
+
|
|
5
|
+
# type variables
|
|
6
|
+
T = TypeVar("T")
|
|
7
|
+
U = TypeVar("U")
|
|
8
|
+
K = TypeVar("K")
|
|
9
|
+
V = TypeVar("V")
|
|
10
|
+
|
|
11
|
+
# covariant type variables
|
|
12
|
+
T_co = TypeVar("T_co", covariant=True)
|
|
13
|
+
U_co = TypeVar("U_co", covariant=True)
|
|
14
|
+
K_co = TypeVar("K_co", covariant=True)
|
|
15
|
+
V_co = TypeVar("V_co", covariant=True)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: kaparoo-python
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python package for (personally) common and useful features.
|
|
5
|
+
Project-URL: GitHub, https://www.github.com/kaparoo/python-package
|
|
6
|
+
Author-email: Jaewoo Park <kaparoo2001@gmail.com>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2023 Jaewoo Park
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Classifier: Development Status :: 4 - Beta
|
|
30
|
+
Classifier: Intended Audience :: Developers
|
|
31
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
32
|
+
Classifier: Operating System :: OS Independent
|
|
33
|
+
Classifier: Programming Language :: Python
|
|
34
|
+
Classifier: Programming Language :: Python :: 3
|
|
35
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
37
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
38
|
+
Classifier: Typing :: Typed
|
|
39
|
+
Requires-Python: >=3.10
|
|
40
|
+
Requires-Dist: beartype>=0.14.1
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: black>=23.3.0; extra == 'dev'
|
|
43
|
+
Requires-Dist: hatch>=1.7.0; extra == 'dev'
|
|
44
|
+
Requires-Dist: mypy>=1.3.0; extra == 'dev'
|
|
45
|
+
Requires-Dist: pytest-order>=1.1.0; extra == 'dev'
|
|
46
|
+
Requires-Dist: pytest>=7.3.2; extra == 'dev'
|
|
47
|
+
Requires-Dist: ruff>=0.0.274; extra == 'dev'
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
# ***kaparoo-python-package***
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
<!-- [ MARKDOWN BADGES ] -->
|
|
55
|
+
|
|
56
|
+
[](https://www.python.org/downloads/)
|
|
57
|
+
[](https://opensource.org/licenses/MIT)
|
|
58
|
+
[](https://github.com/pypa/hatch)
|
|
59
|
+
[](https://github.com/astral-sh/ruff)
|
|
60
|
+
[](https://mypy-lang.org/)
|
|
61
|
+
[](https://github.com/psf/black)
|
|
62
|
+
[](https://gitmoji.dev)
|
|
63
|
+
|
|
64
|
+
<!-- [ END ] -->
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
<!-- [ TABLE OF CONTENTS ] -->
|
|
69
|
+
|
|
70
|
+
<details>
|
|
71
|
+
<summary><strong>Table of Contents</strong></summary>
|
|
72
|
+
|
|
73
|
+
- [***kaparoo-python-package***](#kaparoo-python-package)
|
|
74
|
+
- [:wave: **Overview**](#wave-overview)
|
|
75
|
+
- [:balance\_scale: **License**](#balance_scale-license)
|
|
76
|
+
|
|
77
|
+
</details>
|
|
78
|
+
|
|
79
|
+
<!-- [ END ] -->
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
## :wave: **Overview**
|
|
84
|
+
|
|
85
|
+
A Python package for (personally) common and useful features.
|
|
86
|
+
|
|
87
|
+
## :balance_scale: **License**
|
|
88
|
+
|
|
89
|
+
This project is distributed under the terms of [MIT](./LICENSE) license.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
kaparoo/__about__.py,sha256=b2fCZ20Exwr_01zDxnOFRvxbDylQLSzlPJRJj2l7ZmI,50
|
|
2
|
+
kaparoo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
kaparoo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
kaparoo/beartype/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
kaparoo/beartype/numerics.py,sha256=rDTmnuOGhBW7wQ_9vesHqx7sHkELIxyaUwuq9TQIHa4,674
|
|
6
|
+
kaparoo/filesystem/__init__.py,sha256=K9KUnRcFXZQQRTEcP5jALce0QGn2XSN0gtf7558I6iQ,1206
|
|
7
|
+
kaparoo/filesystem/exceptions.py,sha256=E9IOyZdA37QefamPrG9QMV9afMcmMf3zNyKk8n4Aewk,191
|
|
8
|
+
kaparoo/filesystem/path.py,sha256=FYN4alF1f3ubA72fdKhGxvDtAhyNrFyAKDZeDag8y3M,23982
|
|
9
|
+
kaparoo/filesystem/types.py,sha256=qISJYLhd8rW7nOdH5GQJEPiwkxwQD5b75zZi8Fowzqg,242
|
|
10
|
+
kaparoo/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
kaparoo/utils/optional.py,sha256=oX05_K04xSx1mKqiDra5V4pIm8F7h_1dKtJV03ojCis,3134
|
|
12
|
+
kaparoo/utils/types.py,sha256=5LNQkhtVO9QLRGHcSc6hplwPxiEeA9U_J4SSYIKQfGY,337
|
|
13
|
+
kaparoo_python-0.1.0.dist-info/METADATA,sha256=QSerqz89GVxr52Y7cdr3gK8NHuPndolW1aYPZQteMa4,3876
|
|
14
|
+
kaparoo_python-0.1.0.dist-info/WHEEL,sha256=9QBuHhg6FNW7lppboF2vKVbCGTVzsFykgRQjjlajrhA,87
|
|
15
|
+
kaparoo_python-0.1.0.dist-info/licenses/LICENSE,sha256=_6aA_CoB_YWkSfqkGFxghm2GIsBRE2rp_g7vhz11DM8,1087
|
|
16
|
+
kaparoo_python-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Jaewoo Park
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|