jetpytools 1.2.5__py3-none-any.whl → 1.2.7__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/_metadata.py +1 -1
- jetpytools/enums/base.py +4 -2
- jetpytools/enums/other.py +5 -7
- jetpytools/exceptions/base.py +10 -5
- jetpytools/exceptions/generic.py +4 -4
- jetpytools/functions/normalize.py +24 -26
- jetpytools/types/__init__.py +1 -0
- jetpytools/types/builtins.py +6 -12
- jetpytools/types/check.py +34 -0
- jetpytools/types/file.py +6 -4
- jetpytools/types/funcs.py +15 -13
- jetpytools/types/utils.py +40 -21
- {jetpytools-1.2.5.dist-info → jetpytools-1.2.7.dist-info}/METADATA +1 -1
- {jetpytools-1.2.5.dist-info → jetpytools-1.2.7.dist-info}/RECORD +17 -16
- {jetpytools-1.2.5.dist-info → jetpytools-1.2.7.dist-info}/WHEEL +1 -1
- {jetpytools-1.2.5.dist-info → jetpytools-1.2.7.dist-info}/LICENSE +0 -0
- {jetpytools-1.2.5.dist-info → jetpytools-1.2.7.dist-info}/top_level.txt +0 -0
jetpytools/_metadata.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Collection of stuff that's useful in general python programming"""
|
|
2
2
|
|
|
3
|
-
__version__ = '1.2.
|
|
3
|
+
__version__ = '1.2.7'
|
|
4
4
|
|
|
5
5
|
__author_name__, __author_email__ = 'Jaded Encoding Thaumaturgy', 'jaded.encoding.thaumaturgy@gmail.com'
|
|
6
6
|
__maintainer_name__, __maintainer_email__ = __author_name__, __author_email__
|
jetpytools/enums/base.py
CHANGED
|
@@ -3,6 +3,8 @@ from __future__ import annotations
|
|
|
3
3
|
from enum import Enum
|
|
4
4
|
from typing import Any, TypeVar
|
|
5
5
|
|
|
6
|
+
from typing_extensions import Self
|
|
7
|
+
|
|
6
8
|
from ..exceptions import CustomValueError, NotFoundEnumValue
|
|
7
9
|
from ..types import FuncExceptT
|
|
8
10
|
|
|
@@ -16,11 +18,11 @@ class CustomEnum(Enum):
|
|
|
16
18
|
"""Base class for custom enums."""
|
|
17
19
|
|
|
18
20
|
@classmethod
|
|
19
|
-
def _missing_(cls
|
|
21
|
+
def _missing_(cls, value: Any) -> Self | None:
|
|
20
22
|
return cls.from_param(value)
|
|
21
23
|
|
|
22
24
|
@classmethod
|
|
23
|
-
def from_param(cls
|
|
25
|
+
def from_param(cls, value: Any, func_except: FuncExceptT | None = None) -> Self | None:
|
|
24
26
|
"""
|
|
25
27
|
Return the enum value from a parameter.
|
|
26
28
|
|
jetpytools/enums/other.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import overload
|
|
4
|
+
from typing_extensions import Self
|
|
4
5
|
|
|
5
6
|
__all__ = [
|
|
6
7
|
'Coordinate',
|
|
@@ -23,14 +24,14 @@ class Coordinate:
|
|
|
23
24
|
"""Vertical coordinate."""
|
|
24
25
|
|
|
25
26
|
@overload
|
|
26
|
-
def __init__(self
|
|
27
|
+
def __init__(self, other: tuple[int, int] | Self, /) -> None:
|
|
27
28
|
...
|
|
28
29
|
|
|
29
30
|
@overload
|
|
30
|
-
def __init__(self
|
|
31
|
+
def __init__(self, x: int, y: int, /) -> None:
|
|
31
32
|
...
|
|
32
33
|
|
|
33
|
-
def __init__(self
|
|
34
|
+
def __init__(self, x_or_self: int | tuple[int, int] | Self, y: int | None = None, /) -> None:
|
|
34
35
|
from ..exceptions import CustomValueError
|
|
35
36
|
|
|
36
37
|
if isinstance(x_or_self, int):
|
|
@@ -48,9 +49,6 @@ class Coordinate:
|
|
|
48
49
|
self.y = y
|
|
49
50
|
|
|
50
51
|
|
|
51
|
-
SelfCoord = TypeVar('SelfCoord', bound=Coordinate)
|
|
52
|
-
|
|
53
|
-
|
|
54
52
|
class Position(Coordinate):
|
|
55
53
|
"""Positive set of an (x,y) offset relative to the top left corner of an area."""
|
|
56
54
|
|
jetpytools/exceptions/base.py
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import sys
|
|
4
|
+
|
|
4
5
|
from copy import deepcopy
|
|
5
6
|
from typing import TYPE_CHECKING, Any, TypeVar
|
|
6
7
|
|
|
7
|
-
from
|
|
8
|
+
from typing_extensions import Self
|
|
9
|
+
|
|
10
|
+
from ..types import MISSING, FuncExceptT, SupportsString, MissingT
|
|
8
11
|
|
|
9
12
|
__all__ = [
|
|
10
13
|
'CustomError',
|
|
@@ -112,10 +115,12 @@ class CustomError(ExceptionT, metaclass=CustomErrorMeta):
|
|
|
112
115
|
return CustomErrorMeta.setup_exception(inner_exception, exception) # type: ignore
|
|
113
116
|
|
|
114
117
|
def __call__(
|
|
115
|
-
self
|
|
116
|
-
|
|
118
|
+
self,
|
|
119
|
+
message: SupportsString | None | MissingT = MISSING,
|
|
120
|
+
func: FuncExceptT | None | MissingT = MISSING,
|
|
121
|
+
reason: SupportsString | FuncExceptT | None | MissingT = MISSING,
|
|
117
122
|
**kwargs: Any
|
|
118
|
-
) ->
|
|
123
|
+
) -> Self:
|
|
119
124
|
"""
|
|
120
125
|
Copy an existing exception with defaults and instantiate a new one.
|
|
121
126
|
|
|
@@ -129,7 +134,7 @@ class CustomError(ExceptionT, metaclass=CustomErrorMeta):
|
|
|
129
134
|
if message is not MISSING:
|
|
130
135
|
err.message = message
|
|
131
136
|
|
|
132
|
-
if func is not MISSING:
|
|
137
|
+
if func is not MISSING:
|
|
133
138
|
err.func = func
|
|
134
139
|
|
|
135
140
|
if reason is not MISSING:
|
jetpytools/exceptions/generic.py
CHANGED
|
@@ -18,8 +18,8 @@ class MismatchError(CustomValueError):
|
|
|
18
18
|
return str(item)
|
|
19
19
|
|
|
20
20
|
@classmethod
|
|
21
|
-
def _reduce(cls, items: Iterable[Any]) -> tuple[str]:
|
|
22
|
-
return tuple
|
|
21
|
+
def _reduce(cls, items: Iterable[Any]) -> tuple[str, ...]:
|
|
22
|
+
return tuple(dict.fromkeys(map(cls._item_to_name, items)).keys())
|
|
23
23
|
|
|
24
24
|
def __init__(
|
|
25
25
|
self, func: FuncExceptT, items: Iterable[Any], message: SupportsString = 'All items must be equal!',
|
|
@@ -28,7 +28,7 @@ class MismatchError(CustomValueError):
|
|
|
28
28
|
super().__init__(message, func, reason, **kwargs, reduced_items=iter(self._reduce(items)))
|
|
29
29
|
|
|
30
30
|
@classmethod
|
|
31
|
-
def check(cls, func: FuncExceptT, *items: Any, **kwargs: Any) -> None:
|
|
31
|
+
def check(cls, func: FuncExceptT, /, *items: Any, **kwargs: Any) -> None:
|
|
32
32
|
if len(cls._reduce(items)) != 1:
|
|
33
33
|
raise cls(func, items, **kwargs)
|
|
34
34
|
|
|
@@ -40,6 +40,6 @@ class MismatchRefError(MismatchError):
|
|
|
40
40
|
super().__init__(func, [base, ref], message, **kwargs)
|
|
41
41
|
|
|
42
42
|
@classmethod
|
|
43
|
-
def check(cls, func: FuncExceptT, *items: Any, **kwargs: Any) -> None:
|
|
43
|
+
def check(cls, func: FuncExceptT, /, *items: Any, **kwargs: Any) -> None:
|
|
44
44
|
if len(cls._reduce(items)) != 1:
|
|
45
45
|
raise cls(func, *items, **kwargs)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from fractions import Fraction
|
|
4
|
-
from typing import Any, Iterable, Iterator, Sequence, overload
|
|
4
|
+
from typing import Any, Callable, Iterable, Iterator, Sequence, overload
|
|
5
5
|
|
|
6
|
-
from ..types import
|
|
6
|
+
from ..types import SoftRange, SoftRangeN, SoftRangesN, StrictRange, SupportsString, T, is_soft_range_n
|
|
7
7
|
|
|
8
8
|
__all__ = [
|
|
9
9
|
'normalize_seq',
|
|
@@ -19,12 +19,12 @@ __all__ = [
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
@overload
|
|
22
|
-
def normalize_seq(val: Sequence[T], length: int) -> list[T]:
|
|
22
|
+
def normalize_seq(val: T | Sequence[T], length: int) -> list[T]:
|
|
23
23
|
...
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
@overload
|
|
27
|
-
def normalize_seq(val:
|
|
27
|
+
def normalize_seq(val: Any, length: int) -> list[Any]:
|
|
28
28
|
...
|
|
29
29
|
|
|
30
30
|
|
|
@@ -47,45 +47,43 @@ def normalize_seq(val: T | Sequence[T], length: int) -> list[T]:
|
|
|
47
47
|
return val[:length]
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
_iterables_t = (list, tuple, range, zip, set, map, enumerate)
|
|
51
|
-
|
|
52
|
-
|
|
53
50
|
@overload
|
|
54
|
-
def to_arr(val:
|
|
51
|
+
def to_arr(val: T | Iterable[T]) -> list[T]:
|
|
55
52
|
...
|
|
56
53
|
|
|
57
54
|
|
|
58
55
|
@overload
|
|
59
|
-
def to_arr(val:
|
|
56
|
+
def to_arr(val: Any) -> list[Any]:
|
|
60
57
|
...
|
|
61
58
|
|
|
62
59
|
|
|
63
|
-
def to_arr(val:
|
|
64
|
-
"""
|
|
65
|
-
|
|
60
|
+
def to_arr(val: Any, *, sub: Any = []) -> list[Any]:
|
|
61
|
+
"""
|
|
62
|
+
Normalize any value to a list.
|
|
63
|
+
Bytes and str are not considered iterable and will not be flattened.
|
|
64
|
+
"""
|
|
66
65
|
if sub:
|
|
67
|
-
|
|
66
|
+
import warnings
|
|
67
|
+
warnings.warn("sub is deprecated.", DeprecationWarning)
|
|
68
68
|
|
|
69
|
-
return list(val) if
|
|
69
|
+
return list(val) if (isinstance(val, Iterable) and not isinstance(val, (str, bytes))) else [val]
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
@overload
|
|
73
|
-
def flatten(items:
|
|
73
|
+
def flatten(items: Iterable[Iterable[T]]) -> Iterator[T]:
|
|
74
74
|
...
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
@overload
|
|
78
|
-
def flatten(items:
|
|
78
|
+
def flatten(items: Iterable[Any]) -> Iterator[Any]:
|
|
79
79
|
...
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def flatten(items: Any) -> Any:
|
|
88
|
-
"""Flatten an array of values."""
|
|
82
|
+
def flatten(items: Any) -> Iterator[Any]:
|
|
83
|
+
"""
|
|
84
|
+
Flatten an array of values.
|
|
85
|
+
Bytes and str are not considered iterable and will not be flattened..
|
|
86
|
+
"""
|
|
89
87
|
|
|
90
88
|
for val in items:
|
|
91
89
|
if isinstance(val, Iterable) and not isinstance(val, (str, bytes)):
|
|
@@ -170,13 +168,13 @@ def normalize_ranges(ranges: SoftRangeN | SoftRangesN, end: int) -> list[StrictR
|
|
|
170
168
|
[(24, 150)]
|
|
171
169
|
|
|
172
170
|
|
|
173
|
-
:param clip: Input clip.
|
|
174
171
|
:param franges: Frame range or list of frame ranges.
|
|
172
|
+
:param end: End number.
|
|
175
173
|
|
|
176
174
|
:return: List of positive frame ranges.
|
|
177
175
|
"""
|
|
178
176
|
|
|
179
|
-
ranges = ranges if
|
|
177
|
+
ranges = [ranges] if is_soft_range_n(ranges) else ranges
|
|
180
178
|
|
|
181
179
|
out = []
|
|
182
180
|
|
|
@@ -215,7 +213,7 @@ def invert_ranges(ranges: SoftRangeN | SoftRangesN, enda: int, endb: int | None)
|
|
|
215
213
|
return normalize_list_to_ranges({*range(enda)} - b_frames)
|
|
216
214
|
|
|
217
215
|
|
|
218
|
-
def norm_func_name(func_name: SupportsString |
|
|
216
|
+
def norm_func_name(func_name: SupportsString | Callable[..., Any]) -> str:
|
|
219
217
|
"""Normalize a class, function, or other object to obtain its name"""
|
|
220
218
|
|
|
221
219
|
if isinstance(func_name, str):
|
jetpytools/types/__init__.py
CHANGED
jetpytools/types/builtins.py
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import
|
|
4
|
-
TYPE_CHECKING, Any, Callable, ParamSpec, Sequence, SupportsFloat, SupportsIndex, TypeAlias, TypeVar, Union
|
|
5
|
-
)
|
|
3
|
+
from typing import Any, Callable, ParamSpec, Sequence, SupportsFloat, SupportsIndex, TypeAlias, TypeVar, Union
|
|
6
4
|
|
|
7
5
|
__all__ = [
|
|
8
6
|
'T', 'T0', 'T1', 'T2', 'T_contra',
|
|
@@ -10,14 +8,12 @@ __all__ = [
|
|
|
10
8
|
'F', 'F0', 'F1', 'F2',
|
|
11
9
|
|
|
12
10
|
'P', 'P0', 'P1', 'P2',
|
|
13
|
-
'R', 'R0', 'R1', 'R2', 'R_contra',
|
|
11
|
+
'R', 'R0', 'R1', 'R2', 'R_co', 'R0_co', 'R_contra',
|
|
14
12
|
|
|
15
13
|
'Nb',
|
|
16
14
|
|
|
17
15
|
'StrictRange', 'SoftRange', 'SoftRangeN', 'SoftRangesN',
|
|
18
16
|
|
|
19
|
-
'Self',
|
|
20
|
-
|
|
21
17
|
'SingleOrArr', 'SingleOrArrOpt',
|
|
22
18
|
'SingleOrSeq', 'SingleOrSeqOpt',
|
|
23
19
|
|
|
@@ -49,20 +45,18 @@ R0 = TypeVar('R0')
|
|
|
49
45
|
R1 = TypeVar('R1')
|
|
50
46
|
R2 = TypeVar('R2')
|
|
51
47
|
|
|
48
|
+
R_co = TypeVar('R_co', covariant=True)
|
|
49
|
+
R0_co = TypeVar('R0_co', covariant=True)
|
|
50
|
+
|
|
52
51
|
T_contra = TypeVar('T_contra', contravariant=True)
|
|
53
52
|
R_contra = TypeVar('R_contra', contravariant=True)
|
|
54
53
|
|
|
55
|
-
Self = TypeVar('Self')
|
|
56
|
-
|
|
57
54
|
StrictRange: TypeAlias = tuple[int, int]
|
|
58
55
|
SoftRange: TypeAlias = int | StrictRange | Sequence[int]
|
|
59
56
|
|
|
60
57
|
SoftRangeN: TypeAlias = int | tuple[int | None, int | None] | None
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
SoftRangesN: TypeAlias = Sequence[SoftRangeN]
|
|
64
|
-
else:
|
|
65
|
-
SoftRangesN: TypeAlias = list[SoftRangeN]
|
|
59
|
+
SoftRangesN: TypeAlias = Sequence[SoftRangeN]
|
|
66
60
|
|
|
67
61
|
SingleOrArr = Union[T, list[T]]
|
|
68
62
|
SingleOrSeq = Union[T, Sequence[T]]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from typing import Any, Sequence
|
|
2
|
+
|
|
3
|
+
from typing_extensions import TypeIs
|
|
4
|
+
|
|
5
|
+
from .builtins import SoftRange, SoftRangeN, SoftRangesN, StrictRange
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"is_strict_range", "is_soft_range", "is_soft_range_n", "is_soft_ranges_n"
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def is_strict_range(val: Any) -> TypeIs[StrictRange]:
|
|
13
|
+
return isinstance(val, tuple) and len(val) == 2 and all(isinstance(x, int) for x in val)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def is_soft_range(val: Any) -> TypeIs[SoftRange]:
|
|
17
|
+
return isinstance(val, int) or is_strict_range(val) or (
|
|
18
|
+
isinstance(val, Sequence) and all(isinstance(x, int) for x in val)
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def is_soft_range_n(val: Any) -> TypeIs[SoftRangeN]:
|
|
23
|
+
return (
|
|
24
|
+
isinstance(val, int)
|
|
25
|
+
or (isinstance(val, tuple) and len(val) == 2 and all(isinstance(x, int) or x is None for x in val))
|
|
26
|
+
or val is None
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
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
|
+
)
|
jetpytools/types/file.py
CHANGED
|
@@ -121,7 +121,7 @@ class SPath(Path):
|
|
|
121
121
|
|
|
122
122
|
from ..functions import to_arr
|
|
123
123
|
|
|
124
|
-
return self.with_stem(sep.join([self.stem, *to_arr(suffixes)]))
|
|
124
|
+
return self.with_stem(sep.join([self.stem, *to_arr(suffixes)]))
|
|
125
125
|
|
|
126
126
|
def is_empty_dir(self) -> bool:
|
|
127
127
|
"""Check if the directory is empty."""
|
|
@@ -176,10 +176,12 @@ class SPath(Path):
|
|
|
176
176
|
|
|
177
177
|
matching_files = self.get_folder().glob(pattern)
|
|
178
178
|
|
|
179
|
-
|
|
179
|
+
try:
|
|
180
|
+
next(matching_files)
|
|
181
|
+
except StopIteration:
|
|
180
182
|
return None
|
|
181
183
|
|
|
182
|
-
return max(matching_files, key=lambda p: p.stat().st_mtime
|
|
184
|
+
return max(matching_files, key=lambda p: p.stat().st_mtime)
|
|
183
185
|
|
|
184
186
|
def get_size(self) -> int:
|
|
185
187
|
"""Get the size of the file or directory in bytes."""
|
|
@@ -194,4 +196,4 @@ class SPath(Path):
|
|
|
194
196
|
return sum(f.stat().st_size for f in self.rglob('*') if f.is_file())
|
|
195
197
|
|
|
196
198
|
|
|
197
|
-
SPathLike = Union[str, Path, SPath]
|
|
199
|
+
SPathLike = Union[str, PathLike[str], Path, SPath]
|
jetpytools/types/funcs.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
|
|
2
3
|
from functools import wraps
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Callable, Iterable, Iterator, SupportsIndex, TypeAlias, overload
|
|
3
5
|
|
|
4
|
-
from
|
|
6
|
+
from typing_extensions import Self, TypeIs
|
|
5
7
|
|
|
6
|
-
from .builtins import
|
|
8
|
+
from .builtins import P, T
|
|
7
9
|
from .supports import SupportsString
|
|
8
10
|
|
|
9
11
|
__all__ = [
|
|
@@ -13,7 +15,7 @@ __all__ = [
|
|
|
13
15
|
]
|
|
14
16
|
|
|
15
17
|
|
|
16
|
-
class StrList(
|
|
18
|
+
class StrList(list[SupportsString]):
|
|
17
19
|
"""Custom class for representing a recursively "stringable" list."""
|
|
18
20
|
|
|
19
21
|
if TYPE_CHECKING:
|
|
@@ -41,7 +43,7 @@ class StrList(List[SupportsString]):
|
|
|
41
43
|
return ' '.join(
|
|
42
44
|
filter(
|
|
43
45
|
None,
|
|
44
|
-
(str(x).strip() for x in flatten(self) if x is not None)
|
|
46
|
+
(str(x).strip() for x in flatten(self) if x is not None)
|
|
45
47
|
)
|
|
46
48
|
)
|
|
47
49
|
|
|
@@ -74,20 +76,22 @@ class SentinelDispatcher:
|
|
|
74
76
|
|
|
75
77
|
return _wrap
|
|
76
78
|
|
|
77
|
-
def filter(self
|
|
79
|
+
def filter(self, items: Iterable[T | Self]) -> Iterator[T]:
|
|
78
80
|
for item in items:
|
|
79
|
-
if item
|
|
81
|
+
if isinstance(item, SentinelDispatcher):
|
|
80
82
|
continue
|
|
81
|
-
|
|
82
|
-
yield item # type: ignore
|
|
83
|
+
yield item
|
|
83
84
|
|
|
84
85
|
@classmethod
|
|
85
|
-
def filter_multi(cls, items: Iterable[T |
|
|
86
|
+
def filter_multi(cls, items: Iterable[T | Self], *sentinels: Self) -> Iterator[T]:
|
|
87
|
+
def _in_sentinels(it: Any) -> TypeIs[SentinelDispatcher]:
|
|
88
|
+
return it in sentinels
|
|
89
|
+
|
|
86
90
|
for item in items:
|
|
87
|
-
if item
|
|
91
|
+
if _in_sentinels(item):
|
|
88
92
|
continue
|
|
89
93
|
|
|
90
|
-
yield item
|
|
94
|
+
yield item
|
|
91
95
|
|
|
92
96
|
def __getattr__(self, name: str) -> SentinelDispatcher:
|
|
93
97
|
if name not in _sentinels:
|
|
@@ -105,5 +109,3 @@ Sentinel = SentinelDispatcher()
|
|
|
105
109
|
SentinelT: TypeAlias = SentinelDispatcher
|
|
106
110
|
|
|
107
111
|
_sentinels = dict[str, SentinelDispatcher]()
|
|
108
|
-
|
|
109
|
-
SelfSentinel = TypeVar('SelfSentinel', bound=SentinelDispatcher)
|
jetpytools/types/utils.py
CHANGED
|
@@ -8,8 +8,9 @@ from typing import (
|
|
|
8
8
|
TYPE_CHECKING, Any, Callable, Concatenate, Generator, Generic, Iterable, Iterator, Mapping,
|
|
9
9
|
NoReturn, Protocol, Sequence, TypeVar, cast, overload
|
|
10
10
|
)
|
|
11
|
+
from typing_extensions import Self
|
|
11
12
|
|
|
12
|
-
from .builtins import F0, F1, P0, P1, R0, R1, T0, T1, T2, KwargsT, P, R, T
|
|
13
|
+
from .builtins import F0, F1, P0, P1, R0, R1, T0, T1, T2, KwargsT, P, R, R_co, R0_co, T
|
|
13
14
|
|
|
14
15
|
__all__ = [
|
|
15
16
|
'copy_signature',
|
|
@@ -97,10 +98,15 @@ class injected_self_func(Generic[T, P, R], Protocol): # type: ignore[misc]
|
|
|
97
98
|
...
|
|
98
99
|
|
|
99
100
|
|
|
100
|
-
self_objects_cache = dict[type
|
|
101
|
+
self_objects_cache = dict[type, Any]()
|
|
101
102
|
|
|
102
103
|
|
|
103
104
|
class inject_self_base(Generic[T, P, R]):
|
|
105
|
+
cache: bool | None
|
|
106
|
+
signature: Signature | None
|
|
107
|
+
init_kwargs: list[str] | None
|
|
108
|
+
first_key: str | None
|
|
109
|
+
|
|
104
110
|
def __init__(self, function: Callable[Concatenate[T, P], R], /, *, cache: bool = False) -> None:
|
|
105
111
|
"""
|
|
106
112
|
Wrap ``function`` to always have a self provided to it.
|
|
@@ -126,20 +132,20 @@ class inject_self_base(Generic[T, P, R]):
|
|
|
126
132
|
def __get__(
|
|
127
133
|
self, class_obj: type[T] | T | None, class_type: type[T] | type[type[T]] # type: ignore
|
|
128
134
|
) -> injected_self_func[T, P, R]:
|
|
129
|
-
if not self.signature or not self.first_key:
|
|
130
|
-
self.signature = Signature.from_callable(self.function, eval_str=True)
|
|
131
|
-
self.first_key = next(iter(list(self.signature.parameters.keys())), None)
|
|
135
|
+
if not self.signature or not self.first_key:
|
|
136
|
+
self.signature = Signature.from_callable(self.function, eval_str=True)
|
|
137
|
+
self.first_key = next(iter(list(self.signature.parameters.keys())), None)
|
|
132
138
|
|
|
133
139
|
if isinstance(self, inject_self.init_kwargs):
|
|
134
140
|
from ..exceptions import CustomValueError
|
|
135
141
|
|
|
136
|
-
if 4 not in {x.kind for x in self.signature.parameters.values()}:
|
|
142
|
+
if 4 not in {x.kind for x in self.signature.parameters.values()}:
|
|
137
143
|
raise CustomValueError(
|
|
138
144
|
'This function hasn\'t got any kwargs!', 'inject_self.init_kwargs', self.function
|
|
139
145
|
)
|
|
140
146
|
|
|
141
|
-
self.init_kwargs = list[str](
|
|
142
|
-
k for k, x in self.signature.parameters.items() if x.kind != 4
|
|
147
|
+
self.init_kwargs = list[str](
|
|
148
|
+
k for k, x in self.signature.parameters.items() if x.kind != 4
|
|
143
149
|
)
|
|
144
150
|
|
|
145
151
|
@wraps(self.function)
|
|
@@ -151,15 +157,15 @@ class inject_self_base(Generic[T, P, R]):
|
|
|
151
157
|
if (
|
|
152
158
|
first_arg and (
|
|
153
159
|
(is_obj := isinstance(first_arg, class_type))
|
|
154
|
-
or isinstance(first_arg, type(class_type))
|
|
155
|
-
or first_arg is class_type
|
|
160
|
+
or isinstance(first_arg, type(class_type))
|
|
161
|
+
or first_arg is class_type
|
|
156
162
|
)
|
|
157
163
|
):
|
|
158
164
|
obj = first_arg if is_obj else first_arg()
|
|
159
165
|
if args:
|
|
160
166
|
args = args[1:]
|
|
161
167
|
elif kwargs and self.first_key:
|
|
162
|
-
kwargs.pop(self.first_key)
|
|
168
|
+
kwargs.pop(self.first_key)
|
|
163
169
|
elif class_obj is None:
|
|
164
170
|
if self.cache:
|
|
165
171
|
if class_type not in self_objects_cache:
|
|
@@ -167,7 +173,7 @@ class inject_self_base(Generic[T, P, R]):
|
|
|
167
173
|
else:
|
|
168
174
|
obj = self_objects_cache[class_type]
|
|
169
175
|
elif self.init_kwargs:
|
|
170
|
-
obj = class_type(
|
|
176
|
+
obj = class_type(
|
|
171
177
|
*self.args, **(self.kwargs | {k: v for k, v in kwargs.items() if k not in self.init_kwargs})
|
|
172
178
|
)
|
|
173
179
|
if self.clean_kwargs:
|
|
@@ -473,7 +479,7 @@ class classproperty(Generic[P, R, T, T0, P0]):
|
|
|
473
479
|
|
|
474
480
|
return self.fget.__get__(__obj, __type)() # type: ignore
|
|
475
481
|
|
|
476
|
-
def __set__(self, __obj: Any, __value:
|
|
482
|
+
def __set__(self, __obj: Any, __value: Any) -> None:
|
|
477
483
|
from ..exceptions import CustomError
|
|
478
484
|
|
|
479
485
|
if not self.fset:
|
|
@@ -503,7 +509,7 @@ class classproperty(Generic[P, R, T, T0, P0]):
|
|
|
503
509
|
return self.fget.__name__
|
|
504
510
|
|
|
505
511
|
|
|
506
|
-
class cachedproperty(property, Generic[P,
|
|
512
|
+
class cachedproperty(property, Generic[P, R_co, T, T0, P0]):
|
|
507
513
|
"""
|
|
508
514
|
Wrapper for a one-time get property, that will be cached.
|
|
509
515
|
|
|
@@ -532,21 +538,29 @@ class cachedproperty(property, Generic[P, R, T, T0, P0]):
|
|
|
532
538
|
|
|
533
539
|
if TYPE_CHECKING:
|
|
534
540
|
def __init__(
|
|
535
|
-
self, fget: Callable[P,
|
|
541
|
+
self, fget: Callable[P, R_co], fset: Callable[[T, T0], None] | None = None,
|
|
536
542
|
fdel: Callable[P0, None] | None = None, doc: str | None = None,
|
|
537
543
|
) -> None:
|
|
538
544
|
...
|
|
539
545
|
|
|
540
|
-
def getter(self, __fget: Callable[P1,
|
|
546
|
+
def getter(self, __fget: Callable[P1, R0_co]) -> cachedproperty[P1, R0_co, T, T0, P0]:
|
|
541
547
|
...
|
|
542
548
|
|
|
543
|
-
def setter(self, __fset: Callable[[T1, T2], None]) -> cachedproperty[P,
|
|
549
|
+
def setter(self, __fset: Callable[[T1, T2], None]) -> cachedproperty[P, R_co, T1, T2, P0]:
|
|
544
550
|
...
|
|
545
551
|
|
|
546
|
-
def deleter(self, __fdel: Callable[P1, None]) -> cachedproperty[P,
|
|
552
|
+
def deleter(self, __fdel: Callable[P1, None]) -> cachedproperty[P, R_co, T, T0, P1]:
|
|
547
553
|
...
|
|
548
554
|
|
|
549
|
-
|
|
555
|
+
@overload
|
|
556
|
+
def __get__(self, __obj: None, __type: type | None = None) -> Self:
|
|
557
|
+
...
|
|
558
|
+
|
|
559
|
+
@overload
|
|
560
|
+
def __get__(self, __obj: object, __type: type | None = None) -> R_co:
|
|
561
|
+
...
|
|
562
|
+
|
|
563
|
+
def __get__(self, __obj: Any, __type: type | None = None) -> Any:
|
|
550
564
|
if isinstance(self.fget, classproperty):
|
|
551
565
|
function = partial(self.fget.__get__, __obj, __type) # type: ignore
|
|
552
566
|
__obj = __type
|
|
@@ -557,14 +571,19 @@ class cachedproperty(property, Generic[P, R, T, T0, P0]):
|
|
|
557
571
|
cache = getattr(__obj, cachedproperty.cache_key)
|
|
558
572
|
name = self.fget.__name__
|
|
559
573
|
else:
|
|
560
|
-
|
|
574
|
+
assert self.fget
|
|
575
|
+
function = self.fget.__get__(__obj, __type)
|
|
561
576
|
cache = __obj.__dict__.get(cachedproperty.cache_key)
|
|
562
577
|
name = function.__name__
|
|
563
578
|
|
|
564
579
|
if name not in cache:
|
|
565
580
|
cache[name] = function()
|
|
566
581
|
|
|
567
|
-
return cache[name]
|
|
582
|
+
return cache[name]
|
|
583
|
+
|
|
584
|
+
if TYPE_CHECKING:
|
|
585
|
+
def __set__(self, obj: Any, value: R_co, /) -> None: # type: ignore[misc]
|
|
586
|
+
...
|
|
568
587
|
|
|
569
588
|
|
|
570
589
|
class KwargsNotNone(KwargsT):
|
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
jetpytools/__init__.py,sha256=FSVZdj69oy4mBXd6OXiRHrUhaSc4Exo1pQHBlXycV98,214
|
|
2
|
-
jetpytools/_metadata.py,sha256=
|
|
2
|
+
jetpytools/_metadata.py,sha256=y_dN8-DDeLCacriLV91BnQjH9vA5oZyzrnDV73-0YaU,414
|
|
3
3
|
jetpytools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
jetpytools/enums/__init__.py,sha256=5n6Cu8Yb9N6hIa_YTsyy_s0cCgCnh0vDb-NyXK2RwV0,81
|
|
5
|
-
jetpytools/enums/base.py,sha256=
|
|
6
|
-
jetpytools/enums/other.py,sha256=
|
|
5
|
+
jetpytools/enums/base.py,sha256=BbePlmj__Vqc7gzhrbZBFnrQcC9WNBjtiBYoXpgVNOA,2079
|
|
6
|
+
jetpytools/enums/other.py,sha256=DerFtmdjNK41ZxSYt601vHV5yzvZHPfTKNDlj-FjHm8,1346
|
|
7
7
|
jetpytools/exceptions/__init__.py,sha256=g8GT0XqcNuHFHgQGSRj6a_X1kBiBQGP05soYNbEIN_Q,205
|
|
8
|
-
jetpytools/exceptions/base.py,sha256=
|
|
8
|
+
jetpytools/exceptions/base.py,sha256=ESwC7H8iCQW9DGMGmaoFwIiid98tE1e6sATjOH_7Duc,6370
|
|
9
9
|
jetpytools/exceptions/enum.py,sha256=9YoWwEfyd9k7NwanAqtXbhJaJQAnjRKqsAO73cDvcpA,223
|
|
10
10
|
jetpytools/exceptions/file.py,sha256=QwhUFAoG3NsFFYuPe5O_I6K969CzlrTCv3RTrfzx8B0,1107
|
|
11
|
-
jetpytools/exceptions/generic.py,sha256=
|
|
11
|
+
jetpytools/exceptions/generic.py,sha256=kMj5lR3ifHk3uNhpxN6Lu4Am0vi7E6TfQezkZulqhaQ,1482
|
|
12
12
|
jetpytools/exceptions/module.py,sha256=drkcpa8hcE7Ee20N15j3qsX_grl8a3Jjv10XJ3xtDmE,1207
|
|
13
13
|
jetpytools/functions/__init__.py,sha256=CeDfQrPCYqjiXyCoZ6jcbfM2d7KmRM11lBSxUK2wl4g,127
|
|
14
14
|
jetpytools/functions/funcs.py,sha256=EMoJ_h2tl8Cgr1PXAsmRvgaOY5YL7AiEnGGo3-H76tk,3797
|
|
15
|
-
jetpytools/functions/normalize.py,sha256=
|
|
15
|
+
jetpytools/functions/normalize.py,sha256=2BACok7TAN5ldANyYrbGhUpOkj84siApAYy6ndlhUfI,6316
|
|
16
16
|
jetpytools/functions/other.py,sha256=TRz91spvdYJUh9vKe3Kuw6xZfSEJvrQs1mZVg7SyYmY,413
|
|
17
|
-
jetpytools/types/__init__.py,sha256=
|
|
18
|
-
jetpytools/types/builtins.py,sha256=
|
|
19
|
-
jetpytools/types/
|
|
20
|
-
jetpytools/types/
|
|
17
|
+
jetpytools/types/__init__.py,sha256=yDT-PYTTzH6DyHsQcKvOy1jrCPmUQRKrjCM3apd0kNw,294
|
|
18
|
+
jetpytools/types/builtins.py,sha256=Em8vybY4wCxtK-6KkeKLVP55X1N9Z8OXji3_7W3wEH8,1771
|
|
19
|
+
jetpytools/types/check.py,sha256=Ivf_JkVLG9OgiKXYjq-8azoROLjJvhNNqPq_KDIiOkI,971
|
|
20
|
+
jetpytools/types/file.py,sha256=j46SCbdhus2wtxddAGSCn6V4nJdWWwpnAfW1K3P3ewg,6205
|
|
21
|
+
jetpytools/types/funcs.py,sha256=9qONnDWdpqvRj7vL3W9BLwWeGyQipXQgxOaPjqpQ1M4,3119
|
|
21
22
|
jetpytools/types/generic.py,sha256=sAyBwGVG5FZ-6HVpfRuczov_6zQ_Uyoi0QWnR2iMm9Q,1128
|
|
22
23
|
jetpytools/types/supports.py,sha256=--VZ-iCUiv-a6K8n-H8-6hSxHjrvdYg9mCLhr_lRplo,3051
|
|
23
|
-
jetpytools/types/utils.py,sha256=
|
|
24
|
+
jetpytools/types/utils.py,sha256=3MaUnjezgTy4VjCstD4jNRMOoZX2Q_T1G6L55su5VhU,22570
|
|
24
25
|
jetpytools/utils/__init__.py,sha256=v5Bkl43-OBWlXx9OWpZoGH-QMaYNsPIi4vfuhC13ZLI,163
|
|
25
26
|
jetpytools/utils/file.py,sha256=9GhMGJ5D7CpvUFnvnwPFMloYTeIX-AJ7aKYKdoJQ374,10455
|
|
26
27
|
jetpytools/utils/funcs.py,sha256=ZuLz63kveBY1CLlBexEqmrQiGC67dY4gaXdNU3CeBMw,898
|
|
27
28
|
jetpytools/utils/math.py,sha256=lNTriLtTXgqN82DVSXJ5KUbhsWgxXoJ5eNGIZ0-_r_c,3335
|
|
28
29
|
jetpytools/utils/ranges.py,sha256=dL3WG235Pz9sk5su8A0VdwVf_oSt6obR7R_JNwLyCjQ,2572
|
|
29
|
-
jetpytools-1.2.
|
|
30
|
-
jetpytools-1.2.
|
|
31
|
-
jetpytools-1.2.
|
|
32
|
-
jetpytools-1.2.
|
|
33
|
-
jetpytools-1.2.
|
|
30
|
+
jetpytools-1.2.7.dist-info/LICENSE,sha256=l0PN-qDtXcgOB5aXP_nSUsvCK5V3o9pQCGsTzyZhKL0,1071
|
|
31
|
+
jetpytools-1.2.7.dist-info/METADATA,sha256=FU7Mfh5s7nnARJMWSshl18-SoTcYYruA-fVy27y1p94,1399
|
|
32
|
+
jetpytools-1.2.7.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
|
33
|
+
jetpytools-1.2.7.dist-info/top_level.txt,sha256=Iy4HjIta33ADJxN9Nyt5t5jRIfotEkZkQcOSw4eG8Cs,11
|
|
34
|
+
jetpytools-1.2.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|