python-iterutils 0.2.5.5__tar.gz → 0.2.6__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-iterutils
3
- Version: 0.2.5.5
3
+ Version: 0.2.6
4
4
  Summary: Python another itertools.
5
5
  Home-page: https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-iterutils
6
6
  License: MIT
@@ -2,9 +2,9 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 2, 5)
5
+ __version__ = (0, 2, 6)
6
6
  __all__ = [
7
- "Yield", "YieldFrom", "iterable", "async_iterable",
7
+ "Yield", "YieldFrom", "GenStep", "iterable", "async_iterable",
8
8
  "run_gen_step", "run_gen_step_iter", "as_gen_step",
9
9
  "as_gen_step_iter", "split_cm", "with_iter_next",
10
10
  "map", "filter", "reduce", "zip", "chain",
@@ -63,6 +63,14 @@ class YieldFrom:
63
63
  value: Any
64
64
 
65
65
 
66
+ @dataclass(slots=True, frozen=True, unsafe_hash=True)
67
+ class GenStep:
68
+ """专供 `run_gen_step` 和 `run_gen_step_iter`,说明值需要进一步提取
69
+ """
70
+ value: Generator
71
+ max_depth: int = -1
72
+
73
+
66
74
  iterable = Iterable.__instancecheck__
67
75
  async_iterable = AsyncIterable.__instancecheck__
68
76
  isawaitable = Awaitable.__instancecheck__
@@ -91,37 +99,68 @@ def _get_async[T](back: int = 2, /, *, default: Literal[False] | T = False) -> b
91
99
  return _coalesce(iter_frams(), default)
92
100
 
93
101
 
94
- def _run_gen_step(gen: Generator, /):
95
- send = gen.send
102
+ def _run_gen_step(
103
+ gen: Generator,
104
+ /,
105
+ drive_generator: int = 0,
106
+ ):
107
+ send = gen.send
108
+ throw = gen.throw
109
+ dgen = drive_generator if drive_generator < 0 else drive_generator - 1
96
110
  try:
97
111
  value: Any = send(None)
98
112
  while True:
99
- value = send(value)
113
+ try:
114
+ if isinstance(value, GenStep):
115
+ value = _run_gen_step(value.value, value.max_depth)
116
+ elif drive_generator and isinstance(value, Generator):
117
+ value = _run_gen_step(value, dgen)
118
+ except BaseException as e:
119
+ value = throw(e)
120
+ else:
121
+ value = send(value)
100
122
  except StopIteration as e:
101
- return e.value
123
+ value = e.value
124
+ if isinstance(value, GenStep):
125
+ value = _run_gen_step(value.value, value.max_depth)
126
+ elif drive_generator and isinstance(value, Generator):
127
+ value = _run_gen_step(value, dgen)
128
+ return value
102
129
  finally:
103
130
  gen.close()
104
131
 
105
132
 
106
- async def _run_gen_step_async(gen: Generator, /):
133
+ async def _run_gen_step_async(
134
+ gen: Generator,
135
+ /,
136
+ drive_generator: int = 0,
137
+ ):
107
138
  send = gen.send
108
139
  throw = gen.throw
140
+ dgen = drive_generator if drive_generator < 0 else drive_generator - 1
109
141
  try:
110
- ret: Any = send(None)
142
+ value: Any = send(None)
111
143
  while True:
112
- if isawaitable(ret):
113
- try:
114
- value: Any = (await ret)
115
- except BaseException as e:
116
- ret = throw(e)
117
- else:
118
- ret = send(value)
144
+ try:
145
+ if isawaitable(value):
146
+ value = await value
147
+ elif isinstance(value, GenStep):
148
+ value = await _run_gen_step_async(value.value, value.max_depth)
149
+ elif drive_generator and isinstance(value, Generator):
150
+ value = await _run_gen_step_async(value, dgen)
151
+ except BaseException as e:
152
+ value = throw(e)
119
153
  else:
120
- ret = send(ret)
154
+ value = send(value)
121
155
  except StopIteration as e:
122
- if isawaitable(e.value):
123
- return await e.value
124
- return e.value
156
+ value = e.value
157
+ if isawaitable(value):
158
+ value = await value
159
+ elif isinstance(value, GenStep):
160
+ value = await _run_gen_step_async(value.value, value.max_depth)
161
+ elif drive_generator and isinstance(value, Generator):
162
+ value = await _run_gen_step_async(value, dgen)
163
+ return value
125
164
  finally:
126
165
  gen.close()
127
166
 
@@ -150,69 +189,104 @@ def run_gen_step[**Args](
150
189
  return _run_gen_step(gen_step)
151
190
 
152
191
 
153
- def _run_gen_step_iter(gen: Generator, /) -> Iterator:
154
- send = gen.send
192
+ def _run_gen_step_iter(
193
+ gen: Generator,
194
+ /,
195
+ drive_generator: int = 0,
196
+ ) -> Iterator:
197
+ send = gen.send
198
+ throw = gen.throw
199
+ dgen = drive_generator if drive_generator < 0 else drive_generator - 1
155
200
  try:
156
201
  value: Any = send(None)
157
202
  while True:
158
- if isinstance(value, Yield):
159
- yield value.value
160
- elif isinstance(value, YieldFrom):
161
- yield from value.value
162
- value = send(value)
203
+ try:
204
+ val_type = type(value)
205
+ if issubclass(val_type, (Yield, YieldFrom)):
206
+ value = value.value
207
+ if isinstance(value, GenStep):
208
+ value = _run_gen_step(value.value, value.max_depth)
209
+ elif drive_generator and isinstance(value, Generator):
210
+ value = _run_gen_step(value, dgen)
211
+ if val_type is Yield:
212
+ yield value
213
+ elif val_type is YieldFrom:
214
+ yield from value
215
+ except BaseException as e:
216
+ value = throw(e)
217
+ else:
218
+ value = send(value)
163
219
  except StopIteration as e:
164
220
  value = e.value
165
- if isinstance(value, Yield):
166
- yield value.value
167
- elif isinstance(value, YieldFrom):
168
- yield from value.value
221
+ val_type = type(value)
222
+ if issubclass(val_type, (Yield, YieldFrom)):
223
+ value = value.value
224
+ if isinstance(value, GenStep):
225
+ value = _run_gen_step(value.value, value.max_depth)
226
+ elif drive_generator and isinstance(value, Generator):
227
+ value = _run_gen_step(value, dgen)
228
+ if val_type is Yield:
229
+ yield value
230
+ elif val_type is YieldFrom:
231
+ yield from value
169
232
  finally:
170
233
  gen.close()
171
234
 
172
235
 
173
- async def _run_gen_step_async_iter(gen: Generator, /) -> AsyncIterator:
236
+ async def _run_gen_step_async_iter(
237
+ gen: Generator,
238
+ /,
239
+ drive_generator: int = 0,
240
+ ) -> AsyncIterator:
174
241
  send = gen.send
175
242
  throw = gen.throw
243
+ dgen = drive_generator if drive_generator < 0 else drive_generator - 1
176
244
  try:
177
- ret: Any = send(None)
245
+ value: Any = send(None)
178
246
  while True:
179
247
  try:
180
- if isinstance(ret, (Yield, YieldFrom)):
181
- value: Any = ret.value
182
- if isawaitable(value):
183
- value = await value
184
- if isinstance(ret, Yield):
185
- yield value
186
- elif isinstance(value, AsyncIterable):
187
- async for e in value:
188
- yield e
248
+ val_type = type(value)
249
+ if issubclass(val_type, (Yield, YieldFrom)):
250
+ value = value.value
251
+ if isawaitable(value):
252
+ value = await value
253
+ elif isinstance(value, GenStep):
254
+ value = await _run_gen_step_async(value.value, value.max_depth)
255
+ elif drive_generator and isinstance(value, Generator):
256
+ value = await _run_gen_step_async(value, dgen)
257
+ if val_type is Yield:
258
+ yield value
259
+ elif val_type is YieldFrom:
260
+ if isinstance(value, AsyncIterable):
261
+ async for el in value:
262
+ yield el
189
263
  else:
190
- for e in value:
191
- yield e
192
- elif isawaitable(ret):
193
- value = await ret
194
- else:
195
- value = ret
264
+ for el in value:
265
+ yield el
196
266
  except BaseException as e:
197
- ret = throw(e)
267
+ value = throw(e)
198
268
  else:
199
- ret = send(value)
269
+ value = send(value)
200
270
  except StopIteration as e:
201
- val = e.value
202
- if isinstance(val, (Yield, YieldFrom)):
203
- value = val.value
204
- if isawaitable(value):
205
- value = await value
206
- if isinstance(ret, Yield):
207
- yield value
208
- elif isinstance(value, AsyncIterable):
209
- async for e in value:
210
- yield e
271
+ value = e.value
272
+ val_type = type(value)
273
+ if issubclass(val_type, (Yield, YieldFrom)):
274
+ value = value.value
275
+ if isawaitable(value):
276
+ value = await value
277
+ elif isinstance(value, GenStep):
278
+ value = await _run_gen_step_async(value.value, value.max_depth)
279
+ elif drive_generator and isinstance(value, Generator):
280
+ value = await _run_gen_step_async(value, dgen)
281
+ if val_type is Yield:
282
+ yield value
283
+ elif val_type is YieldFrom:
284
+ if isinstance(value, AsyncIterable):
285
+ async for el in value:
286
+ yield el
211
287
  else:
212
- for e in value:
213
- yield e
214
- elif isawaitable(val):
215
- await val
288
+ for el in value:
289
+ yield el
216
290
  finally:
217
291
  gen.close()
218
292
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-iterutils"
3
- version = "0.2.5.5"
3
+ version = "0.2.6"
4
4
  description = "Python another itertools."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"