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
jetpytools/types/generic.py
CHANGED
|
@@ -6,17 +6,7 @@ from typing import Any, Callable, Literal, TypeAlias, Union
|
|
|
6
6
|
from .builtins import F, SingleOrArr, SingleOrArrOpt
|
|
7
7
|
from .supports import SupportsString
|
|
8
8
|
|
|
9
|
-
__all__ = [
|
|
10
|
-
'MissingT', 'MISSING',
|
|
11
|
-
|
|
12
|
-
'FuncExceptT',
|
|
13
|
-
|
|
14
|
-
'DataType',
|
|
15
|
-
|
|
16
|
-
'StrArr', 'StrArrOpt',
|
|
17
|
-
|
|
18
|
-
'PassthroughC'
|
|
19
|
-
]
|
|
9
|
+
__all__ = ["MISSING", "DataType", "FuncExceptT", "MissingT", "PassthroughC", "StrArr", "StrArrOpt"]
|
|
20
10
|
|
|
21
11
|
|
|
22
12
|
class MissingTBase(Enum):
|
jetpytools/types/supports.py
CHANGED
|
@@ -2,126 +2,142 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from abc import abstractmethod
|
|
4
4
|
from typing import (
|
|
5
|
-
Any,
|
|
5
|
+
Any,
|
|
6
|
+
Callable,
|
|
7
|
+
Iterable,
|
|
8
|
+
Protocol,
|
|
9
|
+
SupportsFloat,
|
|
10
|
+
SupportsIndex,
|
|
11
|
+
TypeAlias,
|
|
12
|
+
TypeVar,
|
|
13
|
+
overload,
|
|
14
|
+
runtime_checkable,
|
|
6
15
|
)
|
|
7
16
|
|
|
8
|
-
from .builtins import T0, T1, T2, T_contra
|
|
17
|
+
from .builtins import T0, T1, T2, T_co, T_contra
|
|
9
18
|
|
|
10
19
|
__all__ = [
|
|
11
|
-
|
|
20
|
+
"ComparatorFunc",
|
|
21
|
+
"SupportsAdd",
|
|
22
|
+
"SupportsAllComparisons",
|
|
23
|
+
"SupportsDunderGE",
|
|
24
|
+
"SupportsDunderGT",
|
|
25
|
+
"SupportsDunderLE",
|
|
26
|
+
"SupportsDunderLT",
|
|
27
|
+
"SupportsFloatOrIndex",
|
|
28
|
+
"SupportsIndexing",
|
|
29
|
+
"SupportsKeysAndGetItem",
|
|
30
|
+
"SupportsRAdd",
|
|
31
|
+
"SupportsRichComparison",
|
|
32
|
+
"SupportsRichComparisonT",
|
|
33
|
+
"SupportsString",
|
|
34
|
+
"SupportsSumNoDefaultT",
|
|
35
|
+
"SupportsTrunc",
|
|
36
|
+
]
|
|
37
|
+
|
|
12
38
|
|
|
13
|
-
|
|
39
|
+
_KT = TypeVar("_KT")
|
|
40
|
+
_VT_co = TypeVar("_VT_co", covariant=True)
|
|
14
41
|
|
|
15
|
-
'SupportsDunderLT', 'SupportsDunderGT',
|
|
16
|
-
'SupportsDunderLE', 'SupportsDunderGE',
|
|
17
42
|
|
|
18
|
-
|
|
43
|
+
@runtime_checkable
|
|
44
|
+
class SupportsAdd(Protocol[T_contra, T_co]):
|
|
45
|
+
def __add__(self, x: T_contra, /) -> T_co: ...
|
|
19
46
|
|
|
20
|
-
'SupportsIndexing',
|
|
21
|
-
'SupportsKeysAndGetItem',
|
|
22
47
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
48
|
+
@runtime_checkable
|
|
49
|
+
class SupportsRAdd(Protocol[T_contra, T_co]):
|
|
50
|
+
def __radd__(self, x: T_contra, /) -> T_co: ...
|
|
51
|
+
|
|
27
52
|
|
|
53
|
+
class _SupportsSumWithNoDefaultGiven(SupportsAdd[Any, Any], SupportsRAdd[int, Any], Protocol): ...
|
|
28
54
|
|
|
29
|
-
|
|
30
|
-
|
|
55
|
+
|
|
56
|
+
SupportsSumNoDefaultT = TypeVar("SupportsSumNoDefaultT", bound=_SupportsSumWithNoDefaultGiven)
|
|
31
57
|
|
|
32
58
|
|
|
33
59
|
@runtime_checkable
|
|
34
60
|
class SupportsTrunc(Protocol):
|
|
35
|
-
def __trunc__(self) -> int:
|
|
36
|
-
...
|
|
61
|
+
def __trunc__(self) -> int: ...
|
|
37
62
|
|
|
38
63
|
|
|
39
64
|
@runtime_checkable
|
|
40
65
|
class SupportsString(Protocol):
|
|
41
66
|
@abstractmethod
|
|
42
|
-
def __str__(self) -> str:
|
|
43
|
-
...
|
|
67
|
+
def __str__(self) -> str: ...
|
|
44
68
|
|
|
45
69
|
|
|
46
70
|
@runtime_checkable
|
|
47
71
|
class SupportsDunderLT(Protocol[T_contra]):
|
|
48
|
-
def __lt__(self,
|
|
49
|
-
...
|
|
72
|
+
def __lt__(self, other: T_contra) -> bool: ...
|
|
50
73
|
|
|
51
74
|
|
|
52
75
|
@runtime_checkable
|
|
53
76
|
class SupportsDunderGT(Protocol[T_contra]):
|
|
54
|
-
def __gt__(self,
|
|
55
|
-
...
|
|
77
|
+
def __gt__(self, other: T_contra) -> bool: ...
|
|
56
78
|
|
|
57
79
|
|
|
58
80
|
@runtime_checkable
|
|
59
81
|
class SupportsDunderLE(Protocol[T_contra]):
|
|
60
|
-
def __le__(self,
|
|
61
|
-
...
|
|
82
|
+
def __le__(self, other: T_contra) -> bool: ...
|
|
62
83
|
|
|
63
84
|
|
|
64
85
|
@runtime_checkable
|
|
65
86
|
class SupportsDunderGE(Protocol[T_contra]):
|
|
66
|
-
def __ge__(self,
|
|
67
|
-
...
|
|
87
|
+
def __ge__(self, other: T_contra) -> bool: ...
|
|
68
88
|
|
|
69
89
|
|
|
70
90
|
@runtime_checkable
|
|
71
91
|
class SupportsAllComparisons(
|
|
72
92
|
SupportsDunderLT[Any], SupportsDunderGT[Any], SupportsDunderLE[Any], SupportsDunderGE[Any], Protocol
|
|
73
|
-
):
|
|
74
|
-
...
|
|
93
|
+
): ...
|
|
75
94
|
|
|
76
95
|
|
|
77
96
|
SupportsRichComparison: TypeAlias = SupportsDunderLT[Any] | SupportsDunderGT[Any]
|
|
78
|
-
SupportsRichComparisonT = TypeVar(
|
|
97
|
+
SupportsRichComparisonT = TypeVar("SupportsRichComparisonT", bound=SupportsRichComparison)
|
|
79
98
|
|
|
80
99
|
|
|
81
100
|
class ComparatorFunc(Protocol):
|
|
82
101
|
@overload
|
|
83
102
|
def __call__(
|
|
84
|
-
self,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
103
|
+
self,
|
|
104
|
+
arg1: SupportsRichComparisonT,
|
|
105
|
+
arg2: SupportsRichComparisonT,
|
|
106
|
+
/,
|
|
107
|
+
*args: SupportsRichComparisonT,
|
|
108
|
+
key: None = ...,
|
|
109
|
+
) -> SupportsRichComparisonT: ...
|
|
88
110
|
|
|
89
111
|
@overload
|
|
90
|
-
def __call__(self,
|
|
91
|
-
...
|
|
112
|
+
def __call__(self, arg1: T0, arg2: T0, /, *_args: T0, key: Callable[[T0], SupportsRichComparison]) -> T0: ...
|
|
92
113
|
|
|
93
114
|
@overload
|
|
94
|
-
def __call__(
|
|
95
|
-
...
|
|
115
|
+
def __call__(
|
|
116
|
+
self, iterable: Iterable[SupportsRichComparisonT], /, *, key: None = ...
|
|
117
|
+
) -> SupportsRichComparisonT: ...
|
|
96
118
|
|
|
97
119
|
@overload
|
|
98
|
-
def __call__(self,
|
|
99
|
-
...
|
|
120
|
+
def __call__(self, iterable: Iterable[T0], /, *, key: Callable[[T0], SupportsRichComparison]) -> T0: ...
|
|
100
121
|
|
|
101
122
|
@overload
|
|
102
123
|
def __call__(
|
|
103
|
-
self,
|
|
104
|
-
) -> SupportsRichComparisonT | T0:
|
|
105
|
-
...
|
|
124
|
+
self, iterable: Iterable[SupportsRichComparisonT], /, *, key: None = ..., default: T0
|
|
125
|
+
) -> SupportsRichComparisonT | T0: ...
|
|
106
126
|
|
|
107
127
|
@overload
|
|
108
128
|
def __call__(
|
|
109
|
-
self,
|
|
110
|
-
) -> T1 | T2:
|
|
111
|
-
...
|
|
129
|
+
self, iterable: Iterable[T1], /, *, key: Callable[[T1], SupportsRichComparison], default: T2
|
|
130
|
+
) -> T1 | T2: ...
|
|
112
131
|
|
|
113
132
|
|
|
114
133
|
class SupportsIndexing(Protocol[_VT_co]):
|
|
115
|
-
def __getitem__(self,
|
|
116
|
-
...
|
|
134
|
+
def __getitem__(self, k: int) -> _VT_co: ...
|
|
117
135
|
|
|
118
136
|
|
|
119
137
|
class SupportsKeysAndGetItem(Protocol[_KT, _VT_co]):
|
|
120
|
-
def keys(self) -> Iterable[_KT]:
|
|
121
|
-
...
|
|
138
|
+
def keys(self) -> Iterable[_KT]: ...
|
|
122
139
|
|
|
123
|
-
def __getitem__(self,
|
|
124
|
-
...
|
|
140
|
+
def __getitem__(self, k: _KT) -> _VT_co: ...
|
|
125
141
|
|
|
126
142
|
|
|
127
143
|
SupportsFloatOrIndex: TypeAlias = SupportsFloat | SupportsIndex
|
jetpytools/types/utils.py
CHANGED
|
@@ -4,8 +4,21 @@ from functools import partial, wraps
|
|
|
4
4
|
from inspect import Signature
|
|
5
5
|
from inspect import _empty as empty_param
|
|
6
6
|
from typing import (
|
|
7
|
-
TYPE_CHECKING,
|
|
8
|
-
|
|
7
|
+
TYPE_CHECKING,
|
|
8
|
+
Any,
|
|
9
|
+
Callable,
|
|
10
|
+
ClassVar,
|
|
11
|
+
Concatenate,
|
|
12
|
+
Generator,
|
|
13
|
+
Generic,
|
|
14
|
+
Iterable,
|
|
15
|
+
Iterator,
|
|
16
|
+
Mapping,
|
|
17
|
+
NoReturn,
|
|
18
|
+
Protocol,
|
|
19
|
+
Sequence,
|
|
20
|
+
cast,
|
|
21
|
+
overload,
|
|
9
22
|
)
|
|
10
23
|
|
|
11
24
|
from typing_extensions import Self
|
|
@@ -13,29 +26,25 @@ from typing_extensions import Self
|
|
|
13
26
|
from .builtins import F0, F1, P0, P1, R0, R1, T0, T1, T2, KwargsT, P, R, R0_co, R1_co, R_co, T, T0_co, T1_co, T_co
|
|
14
27
|
|
|
15
28
|
__all__ = [
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'KwargsNotNone',
|
|
29
|
-
|
|
30
|
-
'Singleton', 'to_singleton',
|
|
31
|
-
|
|
32
|
-
'LinearRangeLut'
|
|
29
|
+
"KwargsNotNone",
|
|
30
|
+
"LinearRangeLut",
|
|
31
|
+
"Singleton",
|
|
32
|
+
"cachedproperty",
|
|
33
|
+
"classproperty",
|
|
34
|
+
"complex_hash",
|
|
35
|
+
"copy_signature",
|
|
36
|
+
"get_subclasses",
|
|
37
|
+
"inject_kwargs_params",
|
|
38
|
+
"inject_self",
|
|
39
|
+
"to_singleton",
|
|
33
40
|
]
|
|
41
|
+
# ruff: noqa: N801
|
|
34
42
|
|
|
35
43
|
|
|
36
44
|
class copy_signature(Generic[F0]):
|
|
37
45
|
"""
|
|
38
|
-
Type util to copy the signature of one function to another function
|
|
46
|
+
Type util to copy the signature of one function to another function.
|
|
47
|
+
|
|
39
48
|
Especially useful for passthrough functions.
|
|
40
49
|
|
|
41
50
|
.. code-block::
|
|
@@ -70,8 +79,7 @@ class copy_signature(Generic[F0]):
|
|
|
70
79
|
class injected_self_func(Protocol[T_co, P, R_co]):
|
|
71
80
|
@overload
|
|
72
81
|
@staticmethod
|
|
73
|
-
def __call__(*args: P.args, **kwargs: P.kwargs) -> R_co:
|
|
74
|
-
...
|
|
82
|
+
def __call__(*args: P.args, **kwargs: P.kwargs) -> R_co: ...
|
|
75
83
|
|
|
76
84
|
@overload
|
|
77
85
|
@staticmethod
|
|
@@ -80,8 +88,7 @@ class injected_self_func(Protocol[T_co, P, R_co]):
|
|
|
80
88
|
|
|
81
89
|
@overload
|
|
82
90
|
@staticmethod
|
|
83
|
-
def __call__(cls: type[T_co], *args: P.args, **kwargs: P.kwargs) -> R_co:
|
|
84
|
-
...
|
|
91
|
+
def __call__(cls: type[T_co], *args: P.args, **kwargs: P.kwargs) -> R_co: ...
|
|
85
92
|
|
|
86
93
|
|
|
87
94
|
self_objects_cache = dict[Any, Any]()
|
|
@@ -116,7 +123,9 @@ class inject_self_base(Generic[T_co, P, R_co]):
|
|
|
116
123
|
self.clean_kwargs = False
|
|
117
124
|
|
|
118
125
|
def __get__(
|
|
119
|
-
self,
|
|
126
|
+
self,
|
|
127
|
+
class_obj: type[T] | T | None,
|
|
128
|
+
class_type: type[T | type[T]] | Any, # type: ignore[valid-type]
|
|
120
129
|
) -> injected_self_func[T_co, P, R_co]:
|
|
121
130
|
if not self.signature or not self.first_key:
|
|
122
131
|
self.signature = Signature.from_callable(self.function, eval_str=True)
|
|
@@ -127,25 +136,19 @@ class inject_self_base(Generic[T_co, P, R_co]):
|
|
|
127
136
|
|
|
128
137
|
if 4 not in {x.kind for x in self.signature.parameters.values()}:
|
|
129
138
|
raise CustomValueError(
|
|
130
|
-
|
|
139
|
+
"This function hasn't got any kwargs!", "inject_self.init_kwargs", self.function
|
|
131
140
|
)
|
|
132
141
|
|
|
133
|
-
self.init_kwargs = list[str](
|
|
134
|
-
k for k, x in self.signature.parameters.items() if x.kind != 4
|
|
135
|
-
)
|
|
142
|
+
self.init_kwargs = list[str](k for k, x in self.signature.parameters.items() if x.kind != 4)
|
|
136
143
|
|
|
137
144
|
@wraps(self.function)
|
|
138
145
|
def _wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
139
|
-
first_arg = (args[0] if args else None) or (
|
|
140
|
-
kwargs.get(self.first_key, None) if self.first_key else None
|
|
141
|
-
)
|
|
146
|
+
first_arg = (args[0] if args else None) or (kwargs.get(self.first_key, None) if self.first_key else None)
|
|
142
147
|
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
or first_arg is class_type
|
|
148
|
-
)
|
|
148
|
+
if first_arg and (
|
|
149
|
+
(is_obj := isinstance(first_arg, class_type))
|
|
150
|
+
or isinstance(first_arg, type(class_type))
|
|
151
|
+
or first_arg is class_type
|
|
149
152
|
):
|
|
150
153
|
obj = first_arg if is_obj else first_arg()
|
|
151
154
|
if args:
|
|
@@ -169,7 +172,7 @@ class inject_self_base(Generic[T_co, P, R_co]):
|
|
|
169
172
|
else:
|
|
170
173
|
obj = class_obj
|
|
171
174
|
|
|
172
|
-
return self.function(obj, *args, **kwargs)
|
|
175
|
+
return self.function(obj, *args, **kwargs) # type: ignore
|
|
173
176
|
|
|
174
177
|
return _wrapper
|
|
175
178
|
|
|
@@ -191,6 +194,7 @@ class inject_self_base(Generic[T_co, P, R_co]):
|
|
|
191
194
|
inj.args = args
|
|
192
195
|
inj.kwargs = kwargs
|
|
193
196
|
return inj # type: ignore
|
|
197
|
+
|
|
194
198
|
return _wrapper
|
|
195
199
|
|
|
196
200
|
|
|
@@ -207,9 +211,7 @@ class inject_self(inject_self_base[T_co, P, R_co]):
|
|
|
207
211
|
def __init__(self, function: Callable[[T1_co], R1_co]) -> None:
|
|
208
212
|
self.function = inject_self(function)
|
|
209
213
|
|
|
210
|
-
def __get__(
|
|
211
|
-
self, class_obj: type[T1_co] | T1_co | None, class_type: type[T1_co] | T1_co
|
|
212
|
-
) -> R1_co:
|
|
214
|
+
def __get__(self, class_obj: type[T1_co] | T1_co | None, class_type: type[T1_co] | T1_co) -> R1_co:
|
|
213
215
|
return self.function.__get__(class_obj, class_type)()
|
|
214
216
|
|
|
215
217
|
class init_kwargs(inject_self_base[T0_co, P0, R0_co]):
|
|
@@ -229,9 +231,7 @@ class inject_self(inject_self_base[T_co, P, R_co]):
|
|
|
229
231
|
def __init__(self, function: Callable[[T0_co], R0_co]) -> None:
|
|
230
232
|
self.function = inject_self(function)
|
|
231
233
|
|
|
232
|
-
def __get__(
|
|
233
|
-
self, class_obj: type[T0_co] | T0_co | None, class_type: type[T0_co] | T0_co
|
|
234
|
-
) -> R0_co:
|
|
234
|
+
def __get__(self, class_obj: type[T0_co] | T0_co | None, class_type: type[T0_co] | T0_co) -> R0_co:
|
|
235
235
|
return self.function.__get__(class_obj, class_type)()
|
|
236
236
|
|
|
237
237
|
|
|
@@ -243,16 +243,14 @@ class inject_kwargs_params_base_func(Generic[T_co, P, R_co]):
|
|
|
243
243
|
class inject_kwargs_params_base(Generic[T_co, P, R_co]):
|
|
244
244
|
signature: Signature | None
|
|
245
245
|
|
|
246
|
-
_kwargs_name =
|
|
246
|
+
_kwargs_name = "kwargs"
|
|
247
247
|
|
|
248
248
|
def __init__(self, function: Callable[Concatenate[T_co, P], R_co]) -> None:
|
|
249
249
|
self.function = function
|
|
250
250
|
|
|
251
251
|
self.signature = None
|
|
252
252
|
|
|
253
|
-
def __get__(
|
|
254
|
-
self, class_obj: T, class_type: type[T]
|
|
255
|
-
) -> inject_kwargs_params_base_func[T_co, P, R_co]:
|
|
253
|
+
def __get__(self, class_obj: T, class_type: type[T]) -> inject_kwargs_params_base_func[T_co, P, R_co]:
|
|
256
254
|
if not self.signature:
|
|
257
255
|
self.signature = Signature.from_callable(self.function, eval_str=True)
|
|
258
256
|
|
|
@@ -263,7 +261,7 @@ class inject_kwargs_params_base(Generic[T_co, P, R_co]):
|
|
|
263
261
|
from ..exceptions import CustomValueError
|
|
264
262
|
|
|
265
263
|
raise CustomValueError(
|
|
266
|
-
|
|
264
|
+
"This function hasn't got any kwargs!", "inject_kwargs_params.add_to_kwargs", self.function
|
|
267
265
|
)
|
|
268
266
|
|
|
269
267
|
this = self
|
|
@@ -329,21 +327,20 @@ class inject_kwargs_params_base(Generic[T_co, P, R_co]):
|
|
|
329
327
|
|
|
330
328
|
|
|
331
329
|
if TYPE_CHECKING: # love you mypy...
|
|
330
|
+
|
|
332
331
|
class _add_to_kwargs:
|
|
333
|
-
def __call__(self, func: F1) -> F1:
|
|
334
|
-
...
|
|
332
|
+
def __call__(self, func: F1) -> F1: ...
|
|
335
333
|
|
|
336
334
|
class _inject_kwargs_params:
|
|
337
|
-
def __call__(self, func: F0) -> F0:
|
|
338
|
-
...
|
|
335
|
+
def __call__(self, func: F0) -> F0: ...
|
|
339
336
|
|
|
340
337
|
add_to_kwargs = _add_to_kwargs()
|
|
341
338
|
|
|
342
339
|
inject_kwargs_params = _inject_kwargs_params()
|
|
343
340
|
else:
|
|
341
|
+
|
|
344
342
|
class inject_kwargs_params(Generic[T, P, R], inject_kwargs_params_base[T, P, R]):
|
|
345
|
-
class add_to_kwargs(Generic[T0, P0, R0], inject_kwargs_params_base[T0, P0, R0]):
|
|
346
|
-
...
|
|
343
|
+
class add_to_kwargs(Generic[T0, P0, R0], inject_kwargs_params_base[T0, P0, R0]): ...
|
|
347
344
|
|
|
348
345
|
|
|
349
346
|
class complex_hash(Generic[T]):
|
|
@@ -356,11 +353,7 @@ class complex_hash(Generic[T]):
|
|
|
356
353
|
def __new__(cls, class_type: T) -> T: # type: ignore
|
|
357
354
|
class inner_class_type(class_type): # type: ignore
|
|
358
355
|
def __hash__(self) -> int:
|
|
359
|
-
return complex_hash.hash(
|
|
360
|
-
self.__class__.__name__, *(
|
|
361
|
-
getattr(self, key) for key in self.__annotations__.keys()
|
|
362
|
-
)
|
|
363
|
-
)
|
|
356
|
+
return complex_hash.hash(self.__class__.__name__, *(getattr(self, key) for key in self.__annotations__))
|
|
364
357
|
|
|
365
358
|
return inner_class_type # type: ignore
|
|
366
359
|
|
|
@@ -379,14 +372,11 @@ class complex_hash(Generic[T]):
|
|
|
379
372
|
try:
|
|
380
373
|
new_hash = hash(value)
|
|
381
374
|
except TypeError:
|
|
382
|
-
if isinstance(value, Iterable)
|
|
383
|
-
new_hash = complex_hash.hash(*value)
|
|
384
|
-
else:
|
|
385
|
-
new_hash = hash(str(value))
|
|
375
|
+
new_hash = complex_hash.hash(*value) if isinstance(value, Iterable) else hash(str(value))
|
|
386
376
|
|
|
387
377
|
values.append(str(new_hash))
|
|
388
378
|
|
|
389
|
-
return hash(
|
|
379
|
+
return hash("_".join(values))
|
|
390
380
|
|
|
391
381
|
|
|
392
382
|
def get_subclasses(family: type[T], exclude: Sequence[type[T]] = []) -> list[type[T]]:
|
|
@@ -436,27 +426,27 @@ class classproperty(Generic[T, R]):
|
|
|
436
426
|
|
|
437
427
|
return func
|
|
438
428
|
|
|
439
|
-
def __get__(self,
|
|
440
|
-
if
|
|
441
|
-
|
|
429
|
+
def __get__(self, obj: T | None, type_: type | None = None) -> R:
|
|
430
|
+
if type_ is None:
|
|
431
|
+
type_ = type(obj)
|
|
442
432
|
|
|
443
|
-
return self.fget.__get__(
|
|
433
|
+
return self.fget.__get__(obj, type_)()
|
|
444
434
|
|
|
445
|
-
def __set__(self,
|
|
435
|
+
def __set__(self, obj: T, value: Any) -> None:
|
|
446
436
|
if not self.fset:
|
|
447
437
|
raise AttributeError(
|
|
448
|
-
f'classproperty with getter "{self.__name__}" of "{
|
|
438
|
+
f'classproperty with getter "{self.__name__}" of "{obj.__class__.__name__}" object has no setter.'
|
|
449
439
|
)
|
|
450
440
|
|
|
451
|
-
self.fset.__get__(None, type(
|
|
441
|
+
self.fset.__get__(None, type(obj))(value)
|
|
452
442
|
|
|
453
|
-
def __delete__(self,
|
|
443
|
+
def __delete__(self, obj: T) -> None:
|
|
454
444
|
if not self.fdel:
|
|
455
445
|
raise AttributeError(
|
|
456
|
-
f'classproperty with getter "{self.__name__}" of "{
|
|
446
|
+
f'classproperty with getter "{self.__name__}" of "{obj.__class__.__name__}" object has no deleter.'
|
|
457
447
|
)
|
|
458
448
|
|
|
459
|
-
self.fdel.__get__(None, type(
|
|
449
|
+
self.fdel.__get__(None, type(obj))()
|
|
460
450
|
|
|
461
451
|
@property
|
|
462
452
|
def __name__(self) -> str:
|
|
@@ -476,12 +466,13 @@ class cachedproperty(property, Generic[P, R_co, T, T0, P0]):
|
|
|
476
466
|
|
|
477
467
|
__isabstractmethod__: bool = False
|
|
478
468
|
|
|
479
|
-
cache_key =
|
|
469
|
+
cache_key = "_jetpt_cachedproperty_cache"
|
|
480
470
|
|
|
481
471
|
class baseclass:
|
|
482
472
|
"""Inherit from this class to automatically set the cache dict."""
|
|
483
473
|
|
|
484
474
|
if not TYPE_CHECKING:
|
|
475
|
+
|
|
485
476
|
def __new__(cls, *args: Any, **kwargs: Any) -> None:
|
|
486
477
|
try:
|
|
487
478
|
self = super().__new__(cls, *args, **kwargs)
|
|
@@ -491,43 +482,41 @@ class cachedproperty(property, Generic[P, R_co, T, T0, P0]):
|
|
|
491
482
|
return self
|
|
492
483
|
|
|
493
484
|
if TYPE_CHECKING:
|
|
485
|
+
|
|
494
486
|
def __init__(
|
|
495
|
-
self,
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
487
|
+
self,
|
|
488
|
+
fget: Callable[P, R_co],
|
|
489
|
+
fset: Callable[[T, T0], None] | None = None,
|
|
490
|
+
fdel: Callable[P0, None] | None = None,
|
|
491
|
+
doc: str | None = None,
|
|
492
|
+
) -> None: ...
|
|
499
493
|
|
|
500
|
-
def getter(self,
|
|
501
|
-
...
|
|
494
|
+
def getter(self, fget: Callable[P1, R0_co]) -> cachedproperty[P1, R0_co, T, T0, P0]: ...
|
|
502
495
|
|
|
503
|
-
def setter(self,
|
|
504
|
-
...
|
|
496
|
+
def setter(self, fset: Callable[[T1, T2], None]) -> cachedproperty[P, R_co, T1, T2, P0]: ...
|
|
505
497
|
|
|
506
|
-
def deleter(self,
|
|
507
|
-
...
|
|
498
|
+
def deleter(self, fdel: Callable[P1, None]) -> cachedproperty[P, R_co, T, T0, P1]: ...
|
|
508
499
|
|
|
509
500
|
@overload
|
|
510
|
-
def __get__(self,
|
|
511
|
-
...
|
|
501
|
+
def __get__(self, obj: None, type_: type | None = None) -> Self: ...
|
|
512
502
|
|
|
513
503
|
@overload
|
|
514
|
-
def __get__(self,
|
|
515
|
-
...
|
|
504
|
+
def __get__(self, obj: object, type_: type | None = None) -> R_co: ...
|
|
516
505
|
|
|
517
|
-
def __get__(self,
|
|
506
|
+
def __get__(self, obj: Any, type_: type | None = None) -> Any:
|
|
518
507
|
if isinstance(self.fget, classproperty):
|
|
519
|
-
function = partial(self.fget.__get__,
|
|
520
|
-
|
|
508
|
+
function = partial(self.fget.__get__, obj, type_) # type: ignore
|
|
509
|
+
obj = type_
|
|
521
510
|
|
|
522
|
-
if not hasattr(
|
|
523
|
-
setattr(
|
|
511
|
+
if not hasattr(obj, cachedproperty.cache_key):
|
|
512
|
+
setattr(obj, cachedproperty.cache_key, dict[str, Any]())
|
|
524
513
|
|
|
525
|
-
cache = getattr(
|
|
514
|
+
cache = getattr(obj, cachedproperty.cache_key)
|
|
526
515
|
name = self.fget.__name__
|
|
527
516
|
else:
|
|
528
517
|
assert self.fget
|
|
529
|
-
function = self.fget.__get__(
|
|
530
|
-
cache =
|
|
518
|
+
function = self.fget.__get__(obj, type_)
|
|
519
|
+
cache = obj.__dict__.get(cachedproperty.cache_key)
|
|
531
520
|
name = function.__name__
|
|
532
521
|
|
|
533
522
|
if name not in cache:
|
|
@@ -536,6 +525,7 @@ class cachedproperty(property, Generic[P, R_co, T, T0, P0]):
|
|
|
536
525
|
return cache[name]
|
|
537
526
|
|
|
538
527
|
if TYPE_CHECKING:
|
|
528
|
+
|
|
539
529
|
def __set__(self, obj: Any, value: R_co, /) -> None: # type: ignore[misc]
|
|
540
530
|
...
|
|
541
531
|
|
|
@@ -544,48 +534,39 @@ class KwargsNotNone(KwargsT):
|
|
|
544
534
|
"""Remove all None objects from this kwargs dict."""
|
|
545
535
|
|
|
546
536
|
if not TYPE_CHECKING:
|
|
547
|
-
def __new__(cls, *args: Any, **kwargs: Any) -> KwargsNotNone:
|
|
548
|
-
return KwargsT(**{
|
|
549
|
-
key: value for key, value in KwargsT(*args, **kwargs).items()
|
|
550
|
-
if value is not None
|
|
551
|
-
})
|
|
552
537
|
|
|
553
|
-
|
|
554
|
-
|
|
538
|
+
def __new__(cls, *args: Any, **kwargs: Any) -> Self:
|
|
539
|
+
return KwargsT(**{key: value for key, value in KwargsT(*args, **kwargs).items() if value is not None})
|
|
555
540
|
|
|
556
541
|
|
|
557
542
|
class SingletonMeta(type):
|
|
558
|
-
_instances
|
|
543
|
+
_instances: ClassVar[dict[type[Any], Any]] = {}
|
|
559
544
|
_singleton_init: bool
|
|
560
545
|
|
|
561
|
-
def __new__(
|
|
562
|
-
|
|
563
|
-
) -> SingletonSelf:
|
|
564
|
-
return type.__new__(cls, name, bases, namespace | {'_singleton_init': kwargs.pop('init', False)})
|
|
546
|
+
def __new__(cls, name: str, bases: tuple[type, ...], namespace: dict[str, Any], **kwargs: Any) -> SingletonMeta:
|
|
547
|
+
return type.__new__(cls, name, bases, namespace | {"_singleton_init": kwargs.pop("init", False)})
|
|
565
548
|
|
|
566
|
-
def __call__(cls
|
|
549
|
+
def __call__(cls, *args: Any, **kwargs: Any) -> SingletonMeta:
|
|
567
550
|
if cls not in cls._instances:
|
|
568
551
|
cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
|
|
569
552
|
elif cls._singleton_init:
|
|
570
|
-
cls._instances[cls].__init__(*args, **kwargs)
|
|
553
|
+
cls._instances[cls].__init__(*args, **kwargs)
|
|
571
554
|
|
|
572
555
|
return cls._instances[cls]
|
|
573
556
|
|
|
574
557
|
|
|
575
|
-
SingletonSelf = TypeVar('SingletonSelf', bound=SingletonMeta)
|
|
576
|
-
|
|
577
|
-
|
|
578
558
|
class Singleton(metaclass=SingletonMeta):
|
|
579
559
|
"""Handy class to inherit to have the SingletonMeta metaclass."""
|
|
580
560
|
|
|
581
561
|
|
|
582
562
|
class to_singleton_impl:
|
|
583
563
|
_ts_args = tuple[str, ...]()
|
|
584
|
-
_ts_kwargs
|
|
564
|
+
_ts_kwargs: Mapping[str, Any] = {}
|
|
585
565
|
_add_classes = tuple[type, ...]()
|
|
586
566
|
|
|
587
567
|
def __new__(_cls, cls: type[T]) -> T: # type: ignore
|
|
588
568
|
if _cls._add_classes:
|
|
569
|
+
|
|
589
570
|
class rcls(cls, *_cls._add_classes): # type: ignore
|
|
590
571
|
...
|
|
591
572
|
else:
|
|
@@ -604,11 +585,11 @@ class to_singleton_impl:
|
|
|
604
585
|
|
|
605
586
|
class to_singleton(to_singleton_impl):
|
|
606
587
|
class as_property(to_singleton_impl):
|
|
607
|
-
_add_classes = (property,
|
|
588
|
+
_add_classes = (property,)
|
|
608
589
|
|
|
609
590
|
|
|
610
591
|
class LinearRangeLut(Mapping[int, int]):
|
|
611
|
-
__slots__ = (
|
|
592
|
+
__slots__ = ("_misses_n", "_ranges_idx_lut", "ranges")
|
|
612
593
|
|
|
613
594
|
def __init__(self, ranges: Mapping[int, range]) -> None:
|
|
614
595
|
self.ranges = ranges
|
|
@@ -617,6 +598,8 @@ class LinearRangeLut(Mapping[int, int]):
|
|
|
617
598
|
self._misses_n = 0
|
|
618
599
|
|
|
619
600
|
def __getitem__(self, n: int) -> int:
|
|
601
|
+
missed_hit = 0
|
|
602
|
+
|
|
620
603
|
for missed_hit, (idx, k) in enumerate(self._ranges_idx_lut):
|
|
621
604
|
if n in k:
|
|
622
605
|
break
|
jetpytools/utils/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from .file import *
|
|
2
|
-
from .funcs import *
|
|
3
|
-
from .math import *
|
|
4
|
-
from .ranges import *
|
|
1
|
+
from .file import *
|
|
2
|
+
from .funcs import *
|
|
3
|
+
from .math import *
|
|
4
|
+
from .ranges import *
|