jetpytools 1.5.0__py3-none-any.whl → 1.6.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.
Potentially problematic release.
This version of jetpytools might be problematic. Click here for more details.
- jetpytools/__init__.py +5 -5
- jetpytools/_metadata.py +4 -4
- jetpytools/enums/__init__.py +2 -2
- jetpytools/enums/base.py +9 -8
- jetpytools/enums/other.py +4 -9
- jetpytools/exceptions/__init__.py +5 -5
- jetpytools/exceptions/base.py +34 -38
- jetpytools/exceptions/enum.py +5 -4
- jetpytools/exceptions/file.py +6 -8
- jetpytools/exceptions/generic.py +8 -6
- jetpytools/exceptions/module.py +9 -8
- jetpytools/functions/__init__.py +3 -3
- jetpytools/functions/funcs.py +21 -42
- jetpytools/functions/normalize.py +42 -54
- jetpytools/functions/other.py +1 -3
- jetpytools/types/__init__.py +7 -7
- jetpytools/types/builtins.py +62 -43
- jetpytools/types/check.py +6 -9
- jetpytools/types/file.py +89 -46
- jetpytools/types/funcs.py +11 -28
- jetpytools/types/generic.py +1 -11
- jetpytools/types/supports.py +68 -52
- jetpytools/types/utils.py +102 -119
- jetpytools/utils/__init__.py +4 -4
- jetpytools/utils/file.py +94 -69
- jetpytools/utils/funcs.py +8 -13
- jetpytools/utils/math.py +26 -16
- jetpytools/utils/ranges.py +7 -11
- {jetpytools-1.5.0.dist-info → jetpytools-1.6.0.dist-info}/METADATA +10 -23
- jetpytools-1.6.0.dist-info/RECORD +33 -0
- {jetpytools-1.5.0.dist-info → jetpytools-1.6.0.dist-info}/WHEEL +1 -2
- jetpytools-1.5.0.dist-info/RECORD +0 -34
- jetpytools-1.5.0.dist-info/top_level.txt +0 -1
- {jetpytools-1.5.0.dist-info → jetpytools-1.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,33 +1,32 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from fractions import Fraction
|
|
4
3
|
import sys
|
|
4
|
+
from fractions import Fraction
|
|
5
5
|
from typing import Any, Callable, Iterable, Iterator, Sequence, overload
|
|
6
6
|
|
|
7
|
-
from ..types import SoftRange, SoftRangeN, SoftRangesN, StrictRange, SupportsString, T, is_soft_range_n
|
|
8
7
|
from ..exceptions import CustomOverflowError
|
|
8
|
+
from ..types import SoftRange, SoftRangeN, SoftRangesN, StrictRange, SupportsString, T, is_soft_range_n
|
|
9
9
|
|
|
10
10
|
__all__ = [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
"flatten",
|
|
12
|
+
"invert_ranges",
|
|
13
|
+
"norm_display_name",
|
|
14
|
+
"norm_func_name",
|
|
15
|
+
"normalize_list_to_ranges",
|
|
16
|
+
"normalize_range",
|
|
17
|
+
"normalize_ranges",
|
|
18
|
+
"normalize_ranges_to_list",
|
|
19
|
+
"normalize_seq",
|
|
20
|
+
"to_arr",
|
|
20
21
|
]
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
@overload
|
|
24
|
-
def normalize_seq(val: T | Sequence[T], length: int) -> list[T]:
|
|
25
|
-
...
|
|
25
|
+
def normalize_seq(val: T | Sequence[T], length: int) -> list[T]: ...
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
@overload
|
|
29
|
-
def normalize_seq(val: Any, length: int) -> list[Any]:
|
|
30
|
-
...
|
|
29
|
+
def normalize_seq(val: Any, length: int) -> list[Any]: ...
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
def normalize_seq(val: T | Sequence[T], length: int) -> list[T]:
|
|
@@ -50,13 +49,11 @@ def normalize_seq(val: T | Sequence[T], length: int) -> list[T]:
|
|
|
50
49
|
|
|
51
50
|
|
|
52
51
|
@overload
|
|
53
|
-
def to_arr(val: T | Iterable[T]) -> list[T]:
|
|
54
|
-
...
|
|
52
|
+
def to_arr(val: T | Iterable[T]) -> list[T]: ...
|
|
55
53
|
|
|
56
54
|
|
|
57
55
|
@overload
|
|
58
|
-
def to_arr(val: Any) -> list[Any]:
|
|
59
|
-
...
|
|
56
|
+
def to_arr(val: Any) -> list[Any]: ...
|
|
60
57
|
|
|
61
58
|
|
|
62
59
|
def to_arr(val: Any, *, sub: Any = []) -> list[Any]:
|
|
@@ -66,19 +63,18 @@ def to_arr(val: Any, *, sub: Any = []) -> list[Any]:
|
|
|
66
63
|
"""
|
|
67
64
|
if sub:
|
|
68
65
|
import warnings
|
|
66
|
+
|
|
69
67
|
warnings.warn("sub is deprecated.", DeprecationWarning)
|
|
70
68
|
|
|
71
69
|
return list(val) if (isinstance(val, Iterable) and not isinstance(val, (str, bytes))) else [val]
|
|
72
70
|
|
|
73
71
|
|
|
74
72
|
@overload
|
|
75
|
-
def flatten(items: Iterable[Iterable[T]]) -> Iterator[T]:
|
|
76
|
-
...
|
|
73
|
+
def flatten(items: Iterable[Iterable[T]]) -> Iterator[T]: ...
|
|
77
74
|
|
|
78
75
|
|
|
79
76
|
@overload
|
|
80
|
-
def flatten(items: Iterable[Any]) -> Iterator[Any]:
|
|
81
|
-
...
|
|
77
|
+
def flatten(items: Iterable[Any]) -> Iterator[Any]: ...
|
|
82
78
|
|
|
83
79
|
|
|
84
80
|
def flatten(items: Any) -> Iterator[Any]:
|
|
@@ -125,10 +121,9 @@ def normalize_list_to_ranges(flist: Iterable[int], min_length: int = 0, exclusiv
|
|
|
125
121
|
prev_n = -1
|
|
126
122
|
|
|
127
123
|
for n in sorted(set(flist)):
|
|
128
|
-
if prev_n + 1 != n:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
flist3 = []
|
|
124
|
+
if prev_n + 1 != n and flist3:
|
|
125
|
+
flist2.append(flist3)
|
|
126
|
+
flist3.clear()
|
|
132
127
|
flist3.append(n)
|
|
133
128
|
prev_n = n
|
|
134
129
|
|
|
@@ -137,10 +132,7 @@ def normalize_list_to_ranges(flist: Iterable[int], min_length: int = 0, exclusiv
|
|
|
137
132
|
|
|
138
133
|
flist4 = [i for i in flist2 if len(i) > min_length]
|
|
139
134
|
|
|
140
|
-
return list(zip(
|
|
141
|
-
[i[0] for i in flist4],
|
|
142
|
-
[i[-1] + exclusive for i in flist4]
|
|
143
|
-
))
|
|
135
|
+
return list(zip([i[0] for i in flist4], [i[-1] + exclusive for i in flist4]))
|
|
144
136
|
|
|
145
137
|
|
|
146
138
|
def normalize_ranges_to_list(ranges: Iterable[SoftRange], exclusive: bool = False) -> list[int]:
|
|
@@ -153,11 +145,7 @@ def normalize_ranges_to_list(ranges: Iterable[SoftRange], exclusive: bool = Fals
|
|
|
153
145
|
|
|
154
146
|
|
|
155
147
|
def normalize_ranges(
|
|
156
|
-
ranges: SoftRangeN | SoftRangesN,
|
|
157
|
-
length: int,
|
|
158
|
-
exclusive: bool = False,
|
|
159
|
-
*,
|
|
160
|
-
strict: bool = True
|
|
148
|
+
ranges: SoftRangeN | SoftRangesN, length: int, exclusive: bool = False, *, strict: bool = True
|
|
161
149
|
) -> list[StrictRange]:
|
|
162
150
|
"""
|
|
163
151
|
Normalize ranges to a list of positive ranges.
|
|
@@ -216,11 +204,13 @@ def normalize_ranges(
|
|
|
216
204
|
# Always throws an error if start and end are negative
|
|
217
205
|
# or higher than length
|
|
218
206
|
# or start is higher than end (likely mismatched)
|
|
219
|
-
if any(
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
207
|
+
if any(
|
|
208
|
+
[
|
|
209
|
+
start < 0 and end < 0,
|
|
210
|
+
start >= length and end - (not exclusive) > length,
|
|
211
|
+
start >= end + (not exclusive),
|
|
212
|
+
]
|
|
213
|
+
):
|
|
224
214
|
exception = CustomOverflowError(
|
|
225
215
|
f"Range `{r}` with length `{length}` could not be normalized!", normalize_ranges
|
|
226
216
|
)
|
|
@@ -231,14 +221,14 @@ def normalize_ranges(
|
|
|
231
221
|
if start < 0:
|
|
232
222
|
exception = CustomOverflowError(
|
|
233
223
|
f"Start frame `{start}` in range `{r}` with length `{length}` could not be normalized!",
|
|
234
|
-
normalize_ranges
|
|
224
|
+
normalize_ranges,
|
|
235
225
|
)
|
|
236
226
|
exceptions.append(exception)
|
|
237
227
|
continue
|
|
238
228
|
if end - (not exclusive) > length:
|
|
239
229
|
exception = CustomOverflowError(
|
|
240
230
|
f"End frame `{end}` in range `{r}` with length `{length}` could not be normalized!",
|
|
241
|
-
normalize_ranges
|
|
231
|
+
normalize_ranges,
|
|
242
232
|
)
|
|
243
233
|
exceptions.append(exception)
|
|
244
234
|
continue
|
|
@@ -255,8 +245,7 @@ def normalize_ranges(
|
|
|
255
245
|
raise Exception(exceptions)
|
|
256
246
|
|
|
257
247
|
return normalize_list_to_ranges(
|
|
258
|
-
[x for start, end in out for x in range(start, end + (not exclusive))],
|
|
259
|
-
exclusive=exclusive
|
|
248
|
+
[x for start, end in out for x in range(start, end + (not exclusive))], exclusive=exclusive
|
|
260
249
|
)
|
|
261
250
|
|
|
262
251
|
|
|
@@ -281,15 +270,14 @@ def norm_func_name(func_name: SupportsString | Callable[..., Any]) -> str:
|
|
|
281
270
|
|
|
282
271
|
func = func_name
|
|
283
272
|
|
|
284
|
-
if hasattr(func_name,
|
|
273
|
+
if hasattr(func_name, "__name__"):
|
|
285
274
|
func_name = func.__name__
|
|
286
|
-
elif hasattr(func_name,
|
|
275
|
+
elif hasattr(func_name, "__qualname__"):
|
|
287
276
|
func_name = func.__qualname__
|
|
288
277
|
|
|
289
|
-
if callable(func):
|
|
290
|
-
if
|
|
291
|
-
|
|
292
|
-
func_name = f'{func.__name__}.{func_name}'
|
|
278
|
+
if callable(func) and hasattr(func, "__self__"):
|
|
279
|
+
func = func.__self__ if isinstance(func.__self__, type) else func.__self__.__class__
|
|
280
|
+
func_name = f"{func.__name__}.{func_name}"
|
|
293
281
|
|
|
294
282
|
return str(func_name).strip()
|
|
295
283
|
|
|
@@ -298,12 +286,12 @@ def norm_display_name(obj: object) -> str:
|
|
|
298
286
|
"""Get a fancy name from any object."""
|
|
299
287
|
|
|
300
288
|
if isinstance(obj, Iterator):
|
|
301
|
-
return
|
|
289
|
+
return ", ".join(norm_display_name(v) for v in obj).strip()
|
|
302
290
|
|
|
303
291
|
if isinstance(obj, Fraction):
|
|
304
|
-
return f
|
|
292
|
+
return f"{obj.numerator}/{obj.denominator}"
|
|
305
293
|
|
|
306
294
|
if isinstance(obj, dict):
|
|
307
|
-
return
|
|
295
|
+
return "(" + ", ".join(f"{k}={v}" for k, v in obj.items()) + ")"
|
|
308
296
|
|
|
309
297
|
return norm_func_name(obj)
|
jetpytools/functions/other.py
CHANGED
jetpytools/types/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
from .builtins import *
|
|
2
|
-
from .check import *
|
|
3
|
-
from .file import *
|
|
4
|
-
from .funcs import *
|
|
5
|
-
from .generic import *
|
|
6
|
-
from .supports import *
|
|
7
|
-
from .utils import *
|
|
1
|
+
from .builtins import *
|
|
2
|
+
from .check import *
|
|
3
|
+
from .file import *
|
|
4
|
+
from .funcs import *
|
|
5
|
+
from .generic import *
|
|
6
|
+
from .supports import *
|
|
7
|
+
from .utils import *
|
jetpytools/types/builtins.py
CHANGED
|
@@ -3,58 +3,77 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import Any, Callable, ParamSpec, Sequence, SupportsFloat, SupportsIndex, TypeAlias, TypeVar, Union
|
|
4
4
|
|
|
5
5
|
__all__ = [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
6
|
+
"F0",
|
|
7
|
+
"F1",
|
|
8
|
+
"F2",
|
|
9
|
+
"P0",
|
|
10
|
+
"P1",
|
|
11
|
+
"P2",
|
|
12
|
+
"R0",
|
|
13
|
+
"R1",
|
|
14
|
+
"R2",
|
|
15
|
+
"T0",
|
|
16
|
+
"T1",
|
|
17
|
+
"T2",
|
|
18
|
+
"ByteData",
|
|
19
|
+
"F",
|
|
20
|
+
"KwargsT",
|
|
21
|
+
"Nb",
|
|
22
|
+
"P",
|
|
23
|
+
"R",
|
|
24
|
+
"R0_co",
|
|
25
|
+
"R1_co",
|
|
26
|
+
"R_co",
|
|
27
|
+
"R_contra",
|
|
28
|
+
"SimpleByteData",
|
|
29
|
+
"SimpleByteDataArray",
|
|
30
|
+
"SingleOrArr",
|
|
31
|
+
"SingleOrArrOpt",
|
|
32
|
+
"SingleOrSeq",
|
|
33
|
+
"SingleOrSeqOpt",
|
|
34
|
+
"SoftRange",
|
|
35
|
+
"SoftRangeN",
|
|
36
|
+
"SoftRangesN",
|
|
37
|
+
"StrictRange",
|
|
38
|
+
"T",
|
|
39
|
+
"T0_co",
|
|
40
|
+
"T1_co",
|
|
41
|
+
"T_co",
|
|
42
|
+
"T_contra",
|
|
24
43
|
]
|
|
25
44
|
|
|
26
|
-
Nb = TypeVar(
|
|
45
|
+
Nb = TypeVar("Nb", float, int)
|
|
27
46
|
|
|
28
|
-
T = TypeVar(
|
|
29
|
-
T0 = TypeVar(
|
|
30
|
-
T1 = TypeVar(
|
|
31
|
-
T2 = TypeVar(
|
|
47
|
+
T = TypeVar("T")
|
|
48
|
+
T0 = TypeVar("T0")
|
|
49
|
+
T1 = TypeVar("T1")
|
|
50
|
+
T2 = TypeVar("T2")
|
|
32
51
|
|
|
33
|
-
F = TypeVar(
|
|
34
|
-
F0 = TypeVar(
|
|
35
|
-
F1 = TypeVar(
|
|
36
|
-
F2 = TypeVar(
|
|
52
|
+
F = TypeVar("F", bound=Callable[..., Any])
|
|
53
|
+
F0 = TypeVar("F0", bound=Callable[..., Any])
|
|
54
|
+
F1 = TypeVar("F1", bound=Callable[..., Any])
|
|
55
|
+
F2 = TypeVar("F2", bound=Callable[..., Any])
|
|
37
56
|
|
|
38
|
-
P = ParamSpec(
|
|
39
|
-
P0 = ParamSpec(
|
|
40
|
-
P1 = ParamSpec(
|
|
41
|
-
P2 = ParamSpec(
|
|
57
|
+
P = ParamSpec("P")
|
|
58
|
+
P0 = ParamSpec("P0")
|
|
59
|
+
P1 = ParamSpec("P1")
|
|
60
|
+
P2 = ParamSpec("P2")
|
|
42
61
|
|
|
43
|
-
R = TypeVar(
|
|
44
|
-
R0 = TypeVar(
|
|
45
|
-
R1 = TypeVar(
|
|
46
|
-
R2 = TypeVar(
|
|
62
|
+
R = TypeVar("R")
|
|
63
|
+
R0 = TypeVar("R0")
|
|
64
|
+
R1 = TypeVar("R1")
|
|
65
|
+
R2 = TypeVar("R2")
|
|
47
66
|
|
|
48
|
-
T_co = TypeVar(
|
|
49
|
-
T0_co = TypeVar(
|
|
50
|
-
T1_co = TypeVar(
|
|
67
|
+
T_co = TypeVar("T_co", covariant=True)
|
|
68
|
+
T0_co = TypeVar("T0_co", covariant=True)
|
|
69
|
+
T1_co = TypeVar("T1_co", covariant=True)
|
|
51
70
|
|
|
52
|
-
R_co = TypeVar(
|
|
53
|
-
R0_co = TypeVar(
|
|
54
|
-
R1_co = TypeVar(
|
|
71
|
+
R_co = TypeVar("R_co", covariant=True)
|
|
72
|
+
R0_co = TypeVar("R0_co", covariant=True)
|
|
73
|
+
R1_co = TypeVar("R1_co", covariant=True)
|
|
55
74
|
|
|
56
|
-
T_contra = TypeVar(
|
|
57
|
-
R_contra = TypeVar(
|
|
75
|
+
T_contra = TypeVar("T_contra", contravariant=True)
|
|
76
|
+
R_contra = TypeVar("R_contra", contravariant=True)
|
|
58
77
|
|
|
59
78
|
StrictRange: TypeAlias = tuple[int, int]
|
|
60
79
|
SoftRange: TypeAlias = int | StrictRange | Sequence[int]
|
jetpytools/types/check.py
CHANGED
|
@@ -4,9 +4,7 @@ from typing_extensions import TypeIs
|
|
|
4
4
|
|
|
5
5
|
from .builtins import SoftRange, SoftRangeN, SoftRangesN, StrictRange
|
|
6
6
|
|
|
7
|
-
__all__ = [
|
|
8
|
-
"is_strict_range", "is_soft_range", "is_soft_range_n", "is_soft_ranges_n"
|
|
9
|
-
]
|
|
7
|
+
__all__ = ["is_soft_range", "is_soft_range_n", "is_soft_ranges_n", "is_strict_range"]
|
|
10
8
|
|
|
11
9
|
|
|
12
10
|
def is_strict_range(val: Any) -> TypeIs[StrictRange]:
|
|
@@ -14,8 +12,10 @@ def is_strict_range(val: Any) -> TypeIs[StrictRange]:
|
|
|
14
12
|
|
|
15
13
|
|
|
16
14
|
def is_soft_range(val: Any) -> TypeIs[SoftRange]:
|
|
17
|
-
return
|
|
18
|
-
isinstance(val,
|
|
15
|
+
return (
|
|
16
|
+
isinstance(val, int)
|
|
17
|
+
or is_strict_range(val)
|
|
18
|
+
or (isinstance(val, Sequence) and all(isinstance(x, int) for x in val))
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
|
|
@@ -28,7 +28,4 @@ def is_soft_range_n(val: Any) -> TypeIs[SoftRangeN]:
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
def is_soft_ranges_n(val: Any) -> TypeIs[SoftRangesN]:
|
|
31
|
-
return (
|
|
32
|
-
isinstance(val, Sequence)
|
|
33
|
-
and all(is_soft_range_n(x) for x in val)
|
|
34
|
-
)
|
|
31
|
+
return isinstance(val, Sequence) and all(is_soft_range_n(x) for x in val)
|
jetpytools/types/file.py
CHANGED
|
@@ -7,22 +7,22 @@ from pathlib import Path
|
|
|
7
7
|
from sys import version_info
|
|
8
8
|
from typing import TYPE_CHECKING, Any, Callable, Iterable, Literal, TypeAlias, Union
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
'FilePathType', 'FileDescriptor',
|
|
12
|
-
'FileOpener',
|
|
13
|
-
|
|
14
|
-
'OpenTextModeUpdating',
|
|
15
|
-
'OpenTextModeWriting',
|
|
16
|
-
'OpenTextModeReading',
|
|
17
|
-
|
|
18
|
-
'OpenBinaryModeUpdating',
|
|
19
|
-
'OpenBinaryModeWriting',
|
|
20
|
-
'OpenBinaryModeReading',
|
|
10
|
+
from typing_extensions import Self
|
|
21
11
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
12
|
+
__all__ = [
|
|
13
|
+
"FileDescriptor",
|
|
14
|
+
"FileOpener",
|
|
15
|
+
"FilePathType",
|
|
16
|
+
"OpenBinaryMode",
|
|
17
|
+
"OpenBinaryModeReading",
|
|
18
|
+
"OpenBinaryModeUpdating",
|
|
19
|
+
"OpenBinaryModeWriting",
|
|
20
|
+
"OpenTextMode",
|
|
21
|
+
"OpenTextModeReading",
|
|
22
|
+
"OpenTextModeUpdating",
|
|
23
|
+
"OpenTextModeWriting",
|
|
24
|
+
"SPath",
|
|
25
|
+
"SPathLike",
|
|
26
26
|
]
|
|
27
27
|
|
|
28
28
|
|
|
@@ -33,26 +33,70 @@ FilePathType: TypeAlias = str | bytes | PathLike[str] | PathLike[bytes]
|
|
|
33
33
|
FileOpener: TypeAlias = Callable[[str, int], int]
|
|
34
34
|
|
|
35
35
|
OpenTextModeUpdating: TypeAlias = Literal[
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
"r+",
|
|
37
|
+
"+r",
|
|
38
|
+
"rt+",
|
|
39
|
+
"r+t",
|
|
40
|
+
"+rt",
|
|
41
|
+
"tr+",
|
|
42
|
+
"t+r",
|
|
43
|
+
"+tr",
|
|
44
|
+
"w+",
|
|
45
|
+
"+w",
|
|
46
|
+
"wt+",
|
|
47
|
+
"w+t",
|
|
48
|
+
"+wt",
|
|
49
|
+
"tw+",
|
|
50
|
+
"t+w",
|
|
51
|
+
"+tw",
|
|
52
|
+
"a+",
|
|
53
|
+
"+a",
|
|
54
|
+
"at+",
|
|
55
|
+
"a+t",
|
|
56
|
+
"+at",
|
|
57
|
+
"ta+",
|
|
58
|
+
"t+a",
|
|
59
|
+
"+ta",
|
|
60
|
+
"x+",
|
|
61
|
+
"+x",
|
|
62
|
+
"xt+",
|
|
63
|
+
"x+t",
|
|
64
|
+
"+xt",
|
|
65
|
+
"tx+",
|
|
66
|
+
"t+x",
|
|
67
|
+
"+tx",
|
|
44
68
|
]
|
|
69
|
+
OpenTextModeWriting: TypeAlias = Literal["w", "wt", "tw", "a", "at", "ta", "x", "xt", "tx"]
|
|
70
|
+
OpenTextModeReading: TypeAlias = Literal["r", "rt", "tr", "U", "rU", "Ur", "rtU", "rUt", "Urt", "trU", "tUr", "Utr"]
|
|
45
71
|
|
|
46
72
|
OpenBinaryModeUpdating: TypeAlias = Literal[
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
73
|
+
"rb+",
|
|
74
|
+
"r+b",
|
|
75
|
+
"+rb",
|
|
76
|
+
"br+",
|
|
77
|
+
"b+r",
|
|
78
|
+
"+br",
|
|
79
|
+
"wb+",
|
|
80
|
+
"w+b",
|
|
81
|
+
"+wb",
|
|
82
|
+
"bw+",
|
|
83
|
+
"b+w",
|
|
84
|
+
"+bw",
|
|
85
|
+
"ab+",
|
|
86
|
+
"a+b",
|
|
87
|
+
"+ab",
|
|
88
|
+
"ba+",
|
|
89
|
+
"b+a",
|
|
90
|
+
"+ba",
|
|
91
|
+
"xb+",
|
|
92
|
+
"x+b",
|
|
93
|
+
"+xb",
|
|
94
|
+
"bx+",
|
|
95
|
+
"b+x",
|
|
96
|
+
"+bx",
|
|
55
97
|
]
|
|
98
|
+
OpenBinaryModeWriting: TypeAlias = Literal["wb", "bw", "ab", "ba", "xb", "bx"]
|
|
99
|
+
OpenBinaryModeReading: TypeAlias = Literal["rb", "br", "rbU", "rUb", "Urb", "brU", "bUr", "Ubr"]
|
|
56
100
|
|
|
57
101
|
OpenTextMode: TypeAlias = OpenTextModeUpdating | OpenTextModeWriting | OpenTextModeReading
|
|
58
102
|
OpenBinaryMode: TypeAlias = OpenBinaryModeUpdating | OpenBinaryModeReading | OpenBinaryModeWriting
|
|
@@ -65,8 +109,8 @@ class SPath(Path):
|
|
|
65
109
|
_flavour = type(Path())._flavour # type: ignore
|
|
66
110
|
|
|
67
111
|
if TYPE_CHECKING:
|
|
68
|
-
|
|
69
|
-
|
|
112
|
+
|
|
113
|
+
def __new__(cls, *args: SPathLike, **kwargs: Any) -> Self: ...
|
|
70
114
|
|
|
71
115
|
def format(self, *args: Any, **kwargs: Any) -> SPath:
|
|
72
116
|
"""Format the path with the given arguments."""
|
|
@@ -102,22 +146,19 @@ class SPath(Path):
|
|
|
102
146
|
if not missing_ok:
|
|
103
147
|
raise
|
|
104
148
|
|
|
105
|
-
def read_lines(
|
|
106
|
-
self, encoding: str | None = None, errors: str | None = None, keepends: bool = False
|
|
107
|
-
) -> list[str]:
|
|
149
|
+
def read_lines(self, encoding: str | None = None, errors: str | None = None, keepends: bool = False) -> list[str]:
|
|
108
150
|
"""Read the file and return its lines."""
|
|
109
151
|
|
|
110
152
|
return super().read_text(encoding, errors).splitlines(keepends)
|
|
111
153
|
|
|
112
154
|
def write_lines(
|
|
113
|
-
self, data: Iterable[str], encoding: str | None = None,
|
|
114
|
-
errors: str | None = None, newline: str | None = None
|
|
155
|
+
self, data: Iterable[str], encoding: str | None = None, errors: str | None = None, newline: str | None = None
|
|
115
156
|
) -> int:
|
|
116
157
|
"""Open the file and write the given lines."""
|
|
117
158
|
|
|
118
|
-
return super().write_text(
|
|
159
|
+
return super().write_text("\n".join(data), encoding, errors, newline)
|
|
119
160
|
|
|
120
|
-
def append_to_stem(self, suffixes: str | Iterable[str], sep: str =
|
|
161
|
+
def append_to_stem(self, suffixes: str | Iterable[str], sep: str = "_") -> SPath:
|
|
121
162
|
"""Append a suffix to the stem of the path"""
|
|
122
163
|
|
|
123
164
|
from ..functions import to_arr
|
|
@@ -150,19 +191,20 @@ class SPath(Path):
|
|
|
150
191
|
|
|
151
192
|
if not self.is_dir():
|
|
152
193
|
from ..exceptions import PathIsNotADirectoryError
|
|
153
|
-
|
|
194
|
+
|
|
195
|
+
raise PathIsNotADirectoryError('The given path, "{self}" is not a directory!', self.copy_dir)
|
|
154
196
|
|
|
155
197
|
dst.mkdirp()
|
|
156
198
|
shutil.copytree(self, dst, dirs_exist_ok=True)
|
|
157
199
|
|
|
158
200
|
return SPath(dst)
|
|
159
201
|
|
|
160
|
-
def lglob(self, pattern: str =
|
|
202
|
+
def lglob(self, pattern: str = "*") -> list[SPath]:
|
|
161
203
|
"""Glob the path and return the list of paths."""
|
|
162
204
|
|
|
163
205
|
return list(map(SPath, self.glob(pattern)))
|
|
164
206
|
|
|
165
|
-
def fglob(self, pattern: str =
|
|
207
|
+
def fglob(self, pattern: str = "*") -> SPath | None:
|
|
166
208
|
"""Glob the path and return the first match."""
|
|
167
209
|
|
|
168
210
|
for root, dirs, files in walk(self):
|
|
@@ -172,7 +214,7 @@ class SPath(Path):
|
|
|
172
214
|
|
|
173
215
|
return None
|
|
174
216
|
|
|
175
|
-
def find_newest_file(self, pattern: str =
|
|
217
|
+
def find_newest_file(self, pattern: str = "*") -> SPath | None:
|
|
176
218
|
"""Find the most recently modified file matching the given pattern in the directory."""
|
|
177
219
|
|
|
178
220
|
matching_files = self.get_folder().glob(pattern)
|
|
@@ -189,12 +231,13 @@ class SPath(Path):
|
|
|
189
231
|
|
|
190
232
|
if not self.exists():
|
|
191
233
|
from ..exceptions import FileNotExistsError
|
|
192
|
-
|
|
234
|
+
|
|
235
|
+
raise FileNotExistsError('The given path, "{self}" is not a file or directory!', self.get_size)
|
|
193
236
|
|
|
194
237
|
if self.is_file():
|
|
195
238
|
return self.stat().st_size
|
|
196
239
|
|
|
197
|
-
return sum(f.stat().st_size for f in self.rglob(
|
|
240
|
+
return sum(f.stat().st_size for f in self.rglob("*") if f.is_file())
|
|
198
241
|
|
|
199
242
|
def is_executable(self) -> bool:
|
|
200
243
|
"""Check if the path is executable."""
|
jetpytools/types/funcs.py
CHANGED
|
@@ -1,34 +1,22 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from functools import wraps
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Callable, Iterable, Iterator, SupportsIndex, TypeAlias
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Callable, Iterable, Iterator, SupportsIndex, TypeAlias
|
|
5
5
|
|
|
6
6
|
from typing_extensions import Self, TypeIs
|
|
7
7
|
|
|
8
8
|
from .builtins import P, T
|
|
9
9
|
from .supports import SupportsString
|
|
10
10
|
|
|
11
|
-
__all__ = [
|
|
12
|
-
'StrList',
|
|
13
|
-
'Sentinel',
|
|
14
|
-
'SentinelT'
|
|
15
|
-
]
|
|
11
|
+
__all__ = ["Sentinel", "SentinelT", "StrList"]
|
|
16
12
|
|
|
17
13
|
|
|
18
14
|
class StrList(list[SupportsString]):
|
|
19
15
|
"""Custom class for representing a recursively "stringable" list."""
|
|
20
16
|
|
|
21
17
|
if TYPE_CHECKING:
|
|
22
|
-
@overload
|
|
23
|
-
def __init__(self, __iterable: Iterable[SupportsString | None] = []) -> None:
|
|
24
|
-
...
|
|
25
18
|
|
|
26
|
-
|
|
27
|
-
def __init__(self, __iterable: Iterable[Iterable[SupportsString | None] | None] = []) -> None:
|
|
28
|
-
...
|
|
29
|
-
|
|
30
|
-
def __init__(self, __iterable: Any = []) -> None:
|
|
31
|
-
...
|
|
19
|
+
def __init__(self, iterable: Iterable[SupportsString | None] | None = ..., /) -> None: ...
|
|
32
20
|
|
|
33
21
|
@property
|
|
34
22
|
def string(self) -> str:
|
|
@@ -40,21 +28,16 @@ class StrList(list[SupportsString]):
|
|
|
40
28
|
def __str__(self) -> str:
|
|
41
29
|
from ..functions import flatten
|
|
42
30
|
|
|
43
|
-
return
|
|
44
|
-
filter(
|
|
45
|
-
None,
|
|
46
|
-
(str(x).strip() for x in flatten(self) if x is not None)
|
|
47
|
-
)
|
|
48
|
-
)
|
|
31
|
+
return " ".join(filter(None, (str(x).strip() for x in flatten(self) if x is not None)))
|
|
49
32
|
|
|
50
|
-
def __add__(self,
|
|
51
|
-
return StrList(super().__add__(
|
|
33
|
+
def __add__(self, x: list[SupportsString]) -> StrList: # type: ignore[override]
|
|
34
|
+
return StrList(super().__add__(x))
|
|
52
35
|
|
|
53
|
-
def __mul__(self,
|
|
54
|
-
return StrList(super().__mul__(
|
|
36
|
+
def __mul__(self, n: SupportsIndex) -> StrList:
|
|
37
|
+
return StrList(super().__mul__(n))
|
|
55
38
|
|
|
56
|
-
def __rmul__(self,
|
|
57
|
-
return StrList(super().__rmul__(
|
|
39
|
+
def __rmul__(self, n: SupportsIndex) -> StrList:
|
|
40
|
+
return StrList(super().__rmul__(n))
|
|
58
41
|
|
|
59
42
|
@property
|
|
60
43
|
def mlength(self) -> int:
|
|
@@ -98,7 +81,7 @@ class SentinelDispatcher:
|
|
|
98
81
|
_sentinels[name] = SentinelDispatcher()
|
|
99
82
|
return _sentinels[name]
|
|
100
83
|
|
|
101
|
-
def __setattr__(self,
|
|
84
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
|
102
85
|
raise NameError
|
|
103
86
|
|
|
104
87
|
def __call__(self) -> SentinelDispatcher:
|