haiway 0.7.0__py3-none-any.whl → 0.7.2__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.
- haiway/state/structure.py +88 -1
- {haiway-0.7.0.dist-info → haiway-0.7.2.dist-info}/METADATA +1 -1
- {haiway-0.7.0.dist-info → haiway-0.7.2.dist-info}/RECORD +6 -6
- {haiway-0.7.0.dist-info → haiway-0.7.2.dist-info}/LICENSE +0 -0
- {haiway-0.7.0.dist-info → haiway-0.7.2.dist-info}/WHEEL +0 -0
- {haiway-0.7.0.dist-info → haiway-0.7.2.dist-info}/top_level.txt +0 -0
haiway/state/structure.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import typing
|
2
|
+
from collections.abc import Mapping
|
1
3
|
from copy import deepcopy
|
2
4
|
from types import EllipsisType, GenericAlias
|
3
5
|
from typing import (
|
@@ -89,10 +91,11 @@ class StateMeta(type):
|
|
89
91
|
),
|
90
92
|
)
|
91
93
|
|
94
|
+
state_type.__TYPE_PARAMETERS__ = type_parameters # pyright: ignore[reportAttributeAccessIssue]
|
92
95
|
state_type.__ATTRIBUTES__ = attributes # pyright: ignore[reportAttributeAccessIssue]
|
93
96
|
state_type.__slots__ = frozenset(attributes.keys()) # pyright: ignore[reportAttributeAccessIssue]
|
94
97
|
state_type.__match_args__ = state_type.__slots__ # pyright: ignore[reportAttributeAccessIssue]
|
95
|
-
state_type._ = AttributePath(state_type, attribute=state_type) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
|
98
|
+
state_type._ = AttributePath(state_type, attribute=state_type) # pyright: ignore[reportCallIssue, reportUnknownMemberType, reportAttributeAccessIssue]
|
96
99
|
|
97
100
|
return state_type
|
98
101
|
|
@@ -102,6 +105,88 @@ class StateMeta(type):
|
|
102
105
|
/,
|
103
106
|
) -> Any: ...
|
104
107
|
|
108
|
+
def __instancecheck__(
|
109
|
+
self,
|
110
|
+
instance: Any,
|
111
|
+
) -> bool:
|
112
|
+
# check for type match
|
113
|
+
if self.__subclasscheck__(type(instance)): # pyright: ignore[reportUnknownArgumentType]
|
114
|
+
return True
|
115
|
+
|
116
|
+
# otherwise check if we are dealing with unparametrized base
|
117
|
+
# against the parametrized one, our generic subtypes have base of unparametrized type
|
118
|
+
if type(instance) not in self.__bases__:
|
119
|
+
return False
|
120
|
+
|
121
|
+
try:
|
122
|
+
# validate instance to check unparametrized fields
|
123
|
+
_ = self(**vars(instance))
|
124
|
+
|
125
|
+
except Exception:
|
126
|
+
return False
|
127
|
+
|
128
|
+
else:
|
129
|
+
return True
|
130
|
+
|
131
|
+
def __subclasscheck__( # noqa: C901, PLR0911, PLR0912
|
132
|
+
self,
|
133
|
+
subclass: type[Any],
|
134
|
+
) -> bool:
|
135
|
+
# check if we are the same class for early exit
|
136
|
+
if self == subclass:
|
137
|
+
return True
|
138
|
+
|
139
|
+
# then check if we are parametrized
|
140
|
+
checked_parameters: Mapping[str, Any] | None = getattr(
|
141
|
+
self,
|
142
|
+
"__TYPE_PARAMETERS__",
|
143
|
+
None,
|
144
|
+
)
|
145
|
+
if checked_parameters is None:
|
146
|
+
# if we are not parametrized allow any subclass
|
147
|
+
return self in subclass.__bases__
|
148
|
+
|
149
|
+
# verify if we have common base next - our generic subtypes have the same base
|
150
|
+
if self.__bases__ == subclass.__bases__:
|
151
|
+
# if we have the same bases we have different generic subtypes
|
152
|
+
# we can verify all of the attributes to check if we have common base
|
153
|
+
available_parameters: Mapping[str, Any] | None = getattr(
|
154
|
+
subclass,
|
155
|
+
"__TYPE_PARAMETERS__",
|
156
|
+
None,
|
157
|
+
)
|
158
|
+
|
159
|
+
if available_parameters is None:
|
160
|
+
# if we have no parameters at this stage this is a serious bug
|
161
|
+
raise RuntimeError("Invalid type parametrization for %s", subclass)
|
162
|
+
|
163
|
+
for key, param in checked_parameters.items():
|
164
|
+
match available_parameters.get(key):
|
165
|
+
case None: # if any parameter is missing we should not be there already
|
166
|
+
return False
|
167
|
+
|
168
|
+
case typing.Any:
|
169
|
+
continue # Any ignores type checks
|
170
|
+
|
171
|
+
case checked:
|
172
|
+
if param is Any:
|
173
|
+
continue # Any ignores type checks
|
174
|
+
|
175
|
+
elif issubclass(checked, param):
|
176
|
+
continue # if we have matching type we are fine
|
177
|
+
|
178
|
+
else:
|
179
|
+
return False # types are not matching
|
180
|
+
|
181
|
+
return True # when all parameters were matching we have matching subclass
|
182
|
+
|
183
|
+
elif subclass in self.__bases__: # our generic subtypes have base of unparametrized type
|
184
|
+
# if subclass parameters were not provided then we can be valid ony if all were Any
|
185
|
+
return all(param is Any for param in checked_parameters.values())
|
186
|
+
|
187
|
+
else:
|
188
|
+
return False # we have different base / comparing to not parametrized
|
189
|
+
|
105
190
|
|
106
191
|
_types_cache: WeakValueDictionary[
|
107
192
|
tuple[
|
@@ -119,6 +204,7 @@ class State(metaclass=StateMeta):
|
|
119
204
|
|
120
205
|
_: ClassVar[Self]
|
121
206
|
__IMMUTABLE__: ClassVar[EllipsisType] = ...
|
207
|
+
__TYPE_PARAMETERS__: ClassVar[Mapping[str, Any] | None] = None
|
122
208
|
__ATTRIBUTES__: ClassVar[dict[str, StateAttribute[Any]]]
|
123
209
|
|
124
210
|
@classmethod
|
@@ -127,6 +213,7 @@ class State(metaclass=StateMeta):
|
|
127
213
|
type_argument: tuple[type[Any], ...] | type[Any],
|
128
214
|
) -> type[Self]:
|
129
215
|
assert Generic in cls.__bases__, "Can't specialize non generic type!" # nosec: B101
|
216
|
+
assert cls.__TYPE_PARAMETERS__ is None, "Can't specialize already specialized type!" # nosec: B101
|
130
217
|
|
131
218
|
type_arguments: tuple[type[Any], ...]
|
132
219
|
match type_argument:
|
@@ -18,7 +18,7 @@ haiway/state/__init__.py,sha256=emTuwGFn7HyjyTJ_ass69J5jQIA7_WHO4teZz_dR05Y,355
|
|
18
18
|
haiway/state/attributes.py,sha256=iQ7TJHnT3hlcYwKcxchXE56zU8WbOTJZhsVn_HocXBc,22903
|
19
19
|
haiway/state/path.py,sha256=4vh-fYQv8_xRWjS0ErMQslKDWRI6-KVECAr8JhYk0UY,17503
|
20
20
|
haiway/state/requirement.py,sha256=3iQqzp5Q7w6y5uClamJGH7S5Hib9pciuTAV27PP5lS8,6161
|
21
|
-
haiway/state/structure.py,sha256=
|
21
|
+
haiway/state/structure.py,sha256=KvWC9_gE9pjtyUAzcFnQ12K8SyBqwbdPK_z8D2xzqDs,11862
|
22
22
|
haiway/state/validation.py,sha256=n5cHcJTbv3Zf-qs05yzuLJIMBReV_4yYVwcH6IL58N0,13836
|
23
23
|
haiway/types/__init__.py,sha256=00Ulp2BxcIWm9vWXKQPodpFEwE8hpqj6OYgrNxelp5s,252
|
24
24
|
haiway/types/frozen.py,sha256=CZhFCXnWAKEhuWSfILxA8smfdpMd5Ku694ycfLh98R8,76
|
@@ -31,8 +31,8 @@ haiway/utils/logs.py,sha256=oDsc1ZdqKDjlTlctLbDcp9iX98Acr-1tdw-Pyg3DElo,1577
|
|
31
31
|
haiway/utils/mimic.py,sha256=BkVjTVP2TxxC8GChPGyDV6UXVwJmiRiSWeOYZNZFHxs,1828
|
32
32
|
haiway/utils/noop.py,sha256=qgbZlOKWY6_23Zs43OLukK2HagIQKRyR04zrFVm5rWI,344
|
33
33
|
haiway/utils/queue.py,sha256=oQ3GXCJ-PGNtMEr6EPdgqAvYZoj8lAa7Z2drBKBEoBM,2345
|
34
|
-
haiway-0.7.
|
35
|
-
haiway-0.7.
|
36
|
-
haiway-0.7.
|
37
|
-
haiway-0.7.
|
38
|
-
haiway-0.7.
|
34
|
+
haiway-0.7.2.dist-info/LICENSE,sha256=GehQEW_I1pkmxkkj3NEa7rCTQKYBn7vTPabpDYJlRuo,1063
|
35
|
+
haiway-0.7.2.dist-info/METADATA,sha256=j-NP-HPcbExPmgEs976hNrlmkmTiyFxgOVjxIRQS00w,3898
|
36
|
+
haiway-0.7.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
37
|
+
haiway-0.7.2.dist-info/top_level.txt,sha256=_LdXVLzUzgkvAGQnQJj5kQfoFhpPW6EF4Kj9NapniLg,7
|
38
|
+
haiway-0.7.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|