haiway 0.11.1__py3-none-any.whl → 0.12.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.
@@ -4,7 +4,7 @@ from enum import Enum
4
4
  from pathlib import Path
5
5
  from re import Pattern
6
6
  from types import EllipsisType, NoneType, UnionType
7
- from typing import Any, Literal, Protocol, Self, Union, is_typeddict
7
+ from typing import Any, Literal, Protocol, Self, Union, final, is_typeddict
8
8
  from uuid import UUID
9
9
 
10
10
  from haiway.state.attributes import AttributeAnnotation
@@ -29,6 +29,7 @@ class AttributeValidationError(Exception):
29
29
  pass
30
30
 
31
31
 
32
+ @final
32
33
  class AttributeValidator[Type]:
33
34
  @classmethod
34
35
  def of(
@@ -51,32 +52,86 @@ class AttributeValidator[Type]:
51
52
  recursion_guard[str(annotation)] = validator
52
53
 
53
54
  if common := VALIDATORS.get(annotation.origin):
54
- validator.validation = common(annotation, recursion_guard)
55
+ object.__setattr__(
56
+ validator,
57
+ "validation",
58
+ common(annotation, recursion_guard),
59
+ )
55
60
 
56
61
  elif hasattr(annotation.origin, "__IMMUTABLE__"):
57
- validator.validation = _prepare_validator_of_type(annotation, recursion_guard)
62
+ object.__setattr__(
63
+ validator,
64
+ "validation",
65
+ _prepare_validator_of_type(annotation, recursion_guard),
66
+ )
58
67
 
59
68
  elif is_typeddict(annotation.origin):
60
- validator.validation = _prepare_validator_of_typed_dict(annotation, recursion_guard)
69
+ object.__setattr__(
70
+ validator,
71
+ "validation",
72
+ _prepare_validator_of_typed_dict(annotation, recursion_guard),
73
+ )
61
74
 
62
75
  elif issubclass(annotation.origin, Protocol):
63
- validator.validation = _prepare_validator_of_type(annotation, recursion_guard)
76
+ object.__setattr__(
77
+ validator,
78
+ "validation",
79
+ _prepare_validator_of_type(annotation, recursion_guard),
80
+ )
64
81
 
65
82
  elif issubclass(annotation.origin, Enum):
66
- validator.validation = _prepare_validator_of_type(annotation, recursion_guard)
83
+ object.__setattr__(
84
+ validator,
85
+ "validation",
86
+ _prepare_validator_of_type(annotation, recursion_guard),
87
+ )
67
88
 
68
89
  else:
69
90
  raise TypeError(f"Unsupported type annotation: {annotation}")
70
91
 
71
92
  return validator
72
93
 
94
+ __slots__ = (
95
+ "annotation",
96
+ "validation",
97
+ )
98
+
73
99
  def __init__(
74
100
  self,
75
101
  annotation: AttributeAnnotation,
76
102
  validation: AttributeValidation[Type] | Missing,
77
103
  ) -> None:
78
- self.annotation: AttributeAnnotation = annotation
79
- self.validation: AttributeValidation[Type] | Missing = validation
104
+ self.annotation: AttributeAnnotation
105
+ object.__setattr__(
106
+ self,
107
+ "annotation",
108
+ annotation,
109
+ )
110
+ self.validation: AttributeValidation[Type] | Missing
111
+ object.__setattr__(
112
+ self,
113
+ "validation",
114
+ validation,
115
+ )
116
+
117
+ def __setattr__(
118
+ self,
119
+ name: str,
120
+ value: Any,
121
+ ) -> Any:
122
+ raise AttributeError(
123
+ f"Can't modify immutable {self.__class__.__qualname__},"
124
+ f" attribute - '{name}' cannot be modified"
125
+ )
126
+
127
+ def __delattr__(
128
+ self,
129
+ name: str,
130
+ ) -> None:
131
+ raise AttributeError(
132
+ f"Can't modify immutable {self.__class__.__qualname__},"
133
+ f" attribute - '{name}' cannot be deleted"
134
+ )
80
135
 
81
136
  def __call__(
82
137
  self,
haiway/types/default.py CHANGED
@@ -12,6 +12,8 @@ __all__ = [
12
12
 
13
13
  @final
14
14
  class DefaultValue[Value]:
15
+ __slots__ = ("_value",)
16
+
15
17
  @overload
16
18
  def __init__(
17
19
  self,
haiway/utils/__init__.py CHANGED
@@ -1,6 +1,13 @@
1
1
  from haiway.utils.always import always, async_always
2
2
  from haiway.utils.collections import as_dict, as_list, as_set, as_tuple
3
- from haiway.utils.env import getenv_bool, getenv_float, getenv_int, getenv_str, load_env
3
+ from haiway.utils.env import (
4
+ getenv_base64,
5
+ getenv_bool,
6
+ getenv_float,
7
+ getenv_int,
8
+ getenv_str,
9
+ load_env,
10
+ )
4
11
  from haiway.utils.freezing import freeze
5
12
  from haiway.utils.logs import setup_logging
6
13
  from haiway.utils.mimic import mimic_function
@@ -17,6 +24,7 @@ __all__ = [
17
24
  "async_always",
18
25
  "async_noop",
19
26
  "freeze",
27
+ "getenv_base64",
20
28
  "getenv_bool",
21
29
  "getenv_float",
22
30
  "getenv_int",
haiway/utils/env.py CHANGED
@@ -1,7 +1,10 @@
1
+ from base64 import b64decode
2
+ from collections.abc import Callable
1
3
  from os import environ, getenv
2
4
  from typing import Literal, overload
3
5
 
4
6
  __all__ = [
7
+ "getenv_base64",
5
8
  "getenv_bool",
6
9
  "getenv_float",
7
10
  "getenv_int",
@@ -182,6 +185,53 @@ def getenv_str(
182
185
  return default
183
186
 
184
187
 
188
+ @overload
189
+ def getenv_base64[Value](
190
+ key: str,
191
+ /,
192
+ *,
193
+ decoder: Callable[[bytes], Value],
194
+ ) -> Value | None: ...
195
+
196
+
197
+ @overload
198
+ def getenv_base64[Value](
199
+ key: str,
200
+ /,
201
+ default: Value,
202
+ *,
203
+ decoder: Callable[[bytes], Value],
204
+ ) -> Value: ...
205
+
206
+
207
+ @overload
208
+ def getenv_base64[Value](
209
+ key: str,
210
+ /,
211
+ *,
212
+ decoder: Callable[[bytes], Value],
213
+ required: Literal[True],
214
+ ) -> Value: ...
215
+
216
+
217
+ def getenv_base64[Value](
218
+ key: str,
219
+ /,
220
+ default: Value | None = None,
221
+ *,
222
+ decoder: Callable[[bytes], Value],
223
+ required: bool = False,
224
+ ) -> Value | None:
225
+ if value := getenv(key=key):
226
+ return decoder(b64decode(value))
227
+
228
+ elif required and default is None:
229
+ raise ValueError(f"Required environment value `{key}` is missing!")
230
+
231
+ else:
232
+ return default
233
+
234
+
185
235
  def load_env(
186
236
  path: str | None = None,
187
237
  override: bool = True,
haiway/utils/queue.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from asyncio import AbstractEventLoop, CancelledError, Future, get_running_loop
2
2
  from collections import deque
3
3
  from collections.abc import AsyncIterator
4
+ from typing import Any
4
5
 
5
6
  __all__ = [
6
7
  "AsyncQueue",
@@ -13,15 +14,61 @@ class AsyncQueue[Element](AsyncIterator[Element]):
13
14
  Cannot be concurrently consumed by multiple readers.
14
15
  """
15
16
 
17
+ __slots__ = (
18
+ "_finish_reason",
19
+ "_loop",
20
+ "_queue",
21
+ "_waiting",
22
+ )
23
+
16
24
  def __init__(
17
25
  self,
18
26
  *elements: Element,
19
27
  loop: AbstractEventLoop | None = None,
20
28
  ) -> None:
21
- self._loop: AbstractEventLoop = loop or get_running_loop()
22
- self._queue: deque[Element] = deque(elements)
23
- self._waiting: Future[Element] | None = None
24
- self._finish_reason: BaseException | None = None
29
+ self._loop: AbstractEventLoop
30
+ object.__setattr__(
31
+ self,
32
+ "_loop",
33
+ loop or get_running_loop(),
34
+ )
35
+ self._queue: deque[Element]
36
+ object.__setattr__(
37
+ self,
38
+ "_queue",
39
+ deque(elements),
40
+ )
41
+ self._waiting: Future[Element] | None
42
+ object.__setattr__(
43
+ self,
44
+ "_waiting",
45
+ None,
46
+ )
47
+ self._finish_reason: BaseException | None
48
+ object.__setattr__(
49
+ self,
50
+ "_finish_reason",
51
+ None,
52
+ )
53
+
54
+ def __setattr__(
55
+ self,
56
+ name: str,
57
+ value: Any,
58
+ ) -> Any:
59
+ raise AttributeError(
60
+ f"Can't modify immutable {self.__class__.__qualname__},"
61
+ f" attribute - '{name}' cannot be modified"
62
+ )
63
+
64
+ def __delattr__(
65
+ self,
66
+ name: str,
67
+ ) -> None:
68
+ raise AttributeError(
69
+ f"Can't modify immutable {self.__class__.__qualname__},"
70
+ f" attribute - '{name}' cannot be deleted"
71
+ )
25
72
 
26
73
  @property
27
74
  def is_finished(self) -> bool:
@@ -48,7 +95,11 @@ class AsyncQueue[Element](AsyncIterator[Element]):
48
95
  if self.is_finished:
49
96
  return # already finished, ignore
50
97
 
51
- self._finish_reason = exception or StopAsyncIteration()
98
+ object.__setattr__(
99
+ self,
100
+ "_finish_reason",
101
+ exception or StopAsyncIteration(),
102
+ )
52
103
 
53
104
  if self._waiting is not None and not self._waiting.done():
54
105
  # checking loop only on finish as the rest of operations
@@ -57,11 +108,11 @@ class AsyncQueue[Element](AsyncIterator[Element]):
57
108
  if get_running_loop() is not self._loop:
58
109
  self._loop.call_soon_threadsafe(
59
110
  self._waiting.set_exception,
60
- self._finish_reason,
111
+ self._finish_reason, # pyright: ignore[reportArgumentType]
61
112
  )
62
113
 
63
114
  else:
64
- self._waiting.set_exception(self._finish_reason)
115
+ self._waiting.set_exception(self._finish_reason) # pyright: ignore[reportArgumentType]
65
116
 
66
117
  def cancel(self) -> None:
67
118
  self.finish(exception=CancelledError())
@@ -77,10 +128,18 @@ class AsyncQueue[Element](AsyncIterator[Element]):
77
128
 
78
129
  try:
79
130
  # create a new future to wait for next
80
- self._waiting = self._loop.create_future()
131
+ object.__setattr__(
132
+ self,
133
+ "_waiting",
134
+ self._loop.create_future(),
135
+ )
81
136
  # wait for the result
82
- return await self._waiting
137
+ return await self._waiting # pyright: ignore[reportGeneralTypeIssues]
83
138
 
84
139
  finally:
85
140
  # cleanup
86
- self._waiting = None
141
+ object.__setattr__(
142
+ self,
143
+ "_waiting",
144
+ None,
145
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haiway
3
- Version: 0.11.1
3
+ Version: 0.12.0
4
4
  Summary: Framework for dependency injection and state management within structured concurrency model.
5
5
  Project-URL: Homepage, https://miquido.com
6
6
  Project-URL: Repository, https://github.com/miquido/haiway.git
@@ -0,0 +1,42 @@
1
+ haiway/__init__.py,sha256=ONC4Hk0GaPzhQ3oYmgh6Z4kJdXQiyJ8ZQcM_hCUz-IY,2045
2
+ haiway/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ haiway/context/__init__.py,sha256=feqd0eJnGQwh4B8BZXpS0fQRE-DqoFCFOHipF1jOY8A,762
4
+ haiway/context/access.py,sha256=3dloiRk4v3ljIJ8LkjW0Tj4vx6G_mDvjEy0lKLU3Wug,18963
5
+ haiway/context/disposables.py,sha256=vcsh8jRaJ8Q1ob7oh5LsrSPw9f5AMTcaD_p_Gb7tXAI,2588
6
+ haiway/context/identifier.py,sha256=lz-FuspOtsaEsfb7QPrEVWYfbcMJgd3A6BGG3kLbaV0,3914
7
+ haiway/context/logging.py,sha256=F3dr6MLjodg3MX5WTInxn3r3JuihG-giBzumI0GGUQw,5590
8
+ haiway/context/metrics.py,sha256=N20XQtC8au_e_3iWrsZdej78YBEIWF44fdtWcZBWono,5223
9
+ haiway/context/state.py,sha256=E3Z49XeE_EsXfYcPGtd-5_YLD5idK1WMMLZQ02of6cg,4554
10
+ haiway/context/tasks.py,sha256=J1BFQJis_15SIXbFclppxL-AOIThg2KS4SX8Hg_-YRY,2828
11
+ haiway/context/types.py,sha256=VvJA7wAPZ3ISpgyThVguioYUXqhHf0XkPfRd0M1ERiQ,142
12
+ haiway/helpers/__init__.py,sha256=8XRJWNhidWuBKqRZ1Hyc2xqt7DeWLcoOs2V-oexl8VY,579
13
+ haiway/helpers/asynchrony.py,sha256=-yJsttRhKw0GgnzMc0FqIigS5UJl_G0YgkK12V5IzJg,6292
14
+ haiway/helpers/caching.py,sha256=mz8IMKs6KWWVY62PosPbNQ9sGstC6xCWAAWLYZT2oSg,10132
15
+ haiway/helpers/metrics.py,sha256=lCSvat3IrkmytFdqTvsqkVqYcVOK_bByfwYAe0hJIWg,13614
16
+ haiway/helpers/retries.py,sha256=gIkyUlqJLDYaxIZd3qzeqGFY9y5Gp8dgZLlZ6hs8hoc,7538
17
+ haiway/helpers/throttling.py,sha256=RfQn8GGPqTuPWzA1CJvZvb1s00vryVpo-eqz5EY9vD4,4150
18
+ haiway/helpers/timeouted.py,sha256=T2I2fThDuP_wDq_3QnZdEaUgAD16uRacbSF1fRnzAaE,3326
19
+ haiway/helpers/tracing.py,sha256=8Gpcc_DguuHAdaxM4rGP0mB-S-8E7DKt7ZGym9f6x6Q,4018
20
+ haiway/state/__init__.py,sha256=emTuwGFn7HyjyTJ_ass69J5jQIA7_WHO4teZz_dR05Y,355
21
+ haiway/state/attributes.py,sha256=3chvq3ENoIX688RSYiqZnOCpxbzt-kQ2Wl8Fc3vVyMo,23311
22
+ haiway/state/path.py,sha256=5CLPDDi3xQ-XlrIqMfhkdaA-UzgNyY542PQpQXMIjrk,21324
23
+ haiway/state/requirement.py,sha256=qFAbchAOH0Ivgywr8cLlATX-GnNjOyAlQieart6vHSE,7040
24
+ haiway/state/structure.py,sha256=kWpDVadrjJOKLNozFvEJKqsS24ivdoVh9T1ZjOn0yrw,13418
25
+ haiway/state/validation.py,sha256=G-jnP5IQl4l4RcssSlKM63cU3-KHp89wJqOb2-8dNtE,14996
26
+ haiway/types/__init__.py,sha256=-j4uDN6ix3GBXLBqXC-k_QOJSDlO6zvNCxDej8vVzek,342
27
+ haiway/types/default.py,sha256=h38-zFkbn_UPEiw1SdDF5rkObVmD9UJpmyhOgS1gQ9U,2208
28
+ haiway/types/frozen.py,sha256=CZhFCXnWAKEhuWSfILxA8smfdpMd5Ku694ycfLh98R8,76
29
+ haiway/types/missing.py,sha256=rDnyA2wxPkTbJl0L-zbo0owp7IJ04xkCIp6xD6wh8NI,1712
30
+ haiway/utils/__init__.py,sha256=YBq9hYhrHFB-4d_M53A620-2KEz5SMU31GDBW6gXFnQ,804
31
+ haiway/utils/always.py,sha256=2abp8Lm9rQkrfS3rm1Iqhb-IcWyVfH1BULab3KMxgOw,1234
32
+ haiway/utils/collections.py,sha256=pKHZhXqTMcOth7gV6mXcC5WcSyBl70MmVIELbDSmMoA,3320
33
+ haiway/utils/env.py,sha256=-hI4CgLkzdyueuECVjm-TfR3lQjE2bDsc72w7vNC4nQ,5339
34
+ haiway/utils/freezing.py,sha256=K34ZIMzbkpgkHKH-KF73plEbXExsajNRkRTYp9nJEf4,620
35
+ haiway/utils/logs.py,sha256=oDsc1ZdqKDjlTlctLbDcp9iX98Acr-1tdw-Pyg3DElo,1577
36
+ haiway/utils/mimic.py,sha256=BkVjTVP2TxxC8GChPGyDV6UXVwJmiRiSWeOYZNZFHxs,1828
37
+ haiway/utils/noop.py,sha256=qgbZlOKWY6_23Zs43OLukK2HagIQKRyR04zrFVm5rWI,344
38
+ haiway/utils/queue.py,sha256=Tk1bXvuNbEgapeC3-h_PYBASqVjhEoL8mUvtJnM29xI,4000
39
+ haiway-0.12.0.dist-info/METADATA,sha256=Jh6XHQuZ9lJP851DbdhqZYDvLJKu6Wx0gR4jwWk6Pdk,3857
40
+ haiway-0.12.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
+ haiway-0.12.0.dist-info/licenses/LICENSE,sha256=GehQEW_I1pkmxkkj3NEa7rCTQKYBn7vTPabpDYJlRuo,1063
42
+ haiway-0.12.0.dist-info/RECORD,,
@@ -1,42 +0,0 @@
1
- haiway/__init__.py,sha256=PYMHx7JZwwSsALewho7v6EgIb5MUwYgZEWrVH-OhVx0,2005
2
- haiway/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- haiway/context/__init__.py,sha256=feqd0eJnGQwh4B8BZXpS0fQRE-DqoFCFOHipF1jOY8A,762
4
- haiway/context/access.py,sha256=KeAgxGf78TufqEUSwvw2LPY2aPE00z6xo3hvQ8L6QO4,17146
5
- haiway/context/disposables.py,sha256=DZjnMp-wMfF-em2Wjhbm1MvXubNpuzFBT70BQNIxC7M,2019
6
- haiway/context/identifier.py,sha256=Fyb6OHx5FPaSLLRK249HUEr_KlBSG5F-eW01Oxg_Ke8,2570
7
- haiway/context/logging.py,sha256=ptwgENuyw-WFgokVsYx9OXZGhJENuO_wgfVjcBryUKM,4251
8
- haiway/context/metrics.py,sha256=Ve628X39u0rdLm0vYmVZt7aGeoEeRquR6f67vJIXClY,4213
9
- haiway/context/state.py,sha256=LCcFxXqDBu6prvPyPicN-ecONSNHyR56PfQ5u5jNFCU,3000
10
- haiway/context/tasks.py,sha256=h6OxLxHHqkw0LfQi81NtbsCKfACKxYRZAkDhlJTpqCM,1904
11
- haiway/context/types.py,sha256=VvJA7wAPZ3ISpgyThVguioYUXqhHf0XkPfRd0M1ERiQ,142
12
- haiway/helpers/__init__.py,sha256=8XRJWNhidWuBKqRZ1Hyc2xqt7DeWLcoOs2V-oexl8VY,579
13
- haiway/helpers/asynchrony.py,sha256=9lo9wT3G0TyPb4vfmTnWGBvB_eN6p6nIlj46_9Ag8fQ,6022
14
- haiway/helpers/caching.py,sha256=Ok_WE5Whe7XqnIuLZo4rNNBFeWap-aUWX799s4b1JAQ,9536
15
- haiway/helpers/metrics.py,sha256=0oFBiO-hAzihyC5jvXevNrYOoTcUGc2yGhE1A_866Mc,13314
16
- haiway/helpers/retries.py,sha256=gIkyUlqJLDYaxIZd3qzeqGFY9y5Gp8dgZLlZ6hs8hoc,7538
17
- haiway/helpers/throttling.py,sha256=zo0OwFq64si5KUwhd58cFHLmGAmYwRbFRJMbv9suhPs,3844
18
- haiway/helpers/timeouted.py,sha256=1xU09hQnFdj6p48BwZl5xUvtIr3zC0ZUXehkdrduCjs,3074
19
- haiway/helpers/tracing.py,sha256=8Gpcc_DguuHAdaxM4rGP0mB-S-8E7DKt7ZGym9f6x6Q,4018
20
- haiway/state/__init__.py,sha256=emTuwGFn7HyjyTJ_ass69J5jQIA7_WHO4teZz_dR05Y,355
21
- haiway/state/attributes.py,sha256=plCcYGE5LVU1Nvo0GHkhThqFG96uLR3tFsisQyK1jK0,23122
22
- haiway/state/path.py,sha256=p-ZVSDU02qAUDln12SDc1pGWzhZ88-1zYEBC0hqceXM,17930
23
- haiway/state/requirement.py,sha256=3iQqzp5Q7w6y5uClamJGH7S5Hib9pciuTAV27PP5lS8,6161
24
- haiway/state/structure.py,sha256=bSIj0S_HG-F1Z5GxSlY6VpGtrtiwG82-AIL_PL1lRLo,12465
25
- haiway/state/validation.py,sha256=r0EMIs-nvoXsmSA74oGu6Lrbw8lkzmseaY82_-E8ous,13814
26
- haiway/types/__init__.py,sha256=-j4uDN6ix3GBXLBqXC-k_QOJSDlO6zvNCxDej8vVzek,342
27
- haiway/types/default.py,sha256=IVQsNzDnfukL3-XlScYv2PgTcJ1x_BNP9i5UlS5oEbg,2179
28
- haiway/types/frozen.py,sha256=CZhFCXnWAKEhuWSfILxA8smfdpMd5Ku694ycfLh98R8,76
29
- haiway/types/missing.py,sha256=rDnyA2wxPkTbJl0L-zbo0owp7IJ04xkCIp6xD6wh8NI,1712
30
- haiway/utils/__init__.py,sha256=O7qmAmUktX-X_5D1L5FJMeCFEiOVrrnyYSyiycm4nyg,739
31
- haiway/utils/always.py,sha256=2abp8Lm9rQkrfS3rm1Iqhb-IcWyVfH1BULab3KMxgOw,1234
32
- haiway/utils/collections.py,sha256=pKHZhXqTMcOth7gV6mXcC5WcSyBl70MmVIELbDSmMoA,3320
33
- haiway/utils/env.py,sha256=vlW21LEp8uOVNnUXpBfPtj3zKi9Kkjoemb_H5hQpYPQ,4433
34
- haiway/utils/freezing.py,sha256=K34ZIMzbkpgkHKH-KF73plEbXExsajNRkRTYp9nJEf4,620
35
- haiway/utils/logs.py,sha256=oDsc1ZdqKDjlTlctLbDcp9iX98Acr-1tdw-Pyg3DElo,1577
36
- haiway/utils/mimic.py,sha256=BkVjTVP2TxxC8GChPGyDV6UXVwJmiRiSWeOYZNZFHxs,1828
37
- haiway/utils/noop.py,sha256=qgbZlOKWY6_23Zs43OLukK2HagIQKRyR04zrFVm5rWI,344
38
- haiway/utils/queue.py,sha256=jmz5b4cDvdXpuFnAfrNsGB5wXx4ThCgLHbFlH54o8UY,2657
39
- haiway-0.11.1.dist-info/METADATA,sha256=RAlc7LEyW8N7fizrJI0n_E1e52LlDscJDuEnD_nJdAM,3857
40
- haiway-0.11.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
- haiway-0.11.1.dist-info/licenses/LICENSE,sha256=GehQEW_I1pkmxkkj3NEa7rCTQKYBn7vTPabpDYJlRuo,1063
42
- haiway-0.11.1.dist-info/RECORD,,