ez-a-sync 0.22.14__py3-none-any.whl → 0.22.16__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 ez-a-sync might be problematic. Click here for more details.
- a_sync/ENVIRONMENT_VARIABLES.py +37 -5
- a_sync/__init__.py +53 -12
- a_sync/_smart.py +231 -28
- a_sync/_typing.py +112 -15
- a_sync/a_sync/__init__.py +35 -10
- a_sync/a_sync/_descriptor.py +248 -38
- a_sync/a_sync/_flags.py +78 -9
- a_sync/a_sync/_helpers.py +46 -13
- a_sync/a_sync/_kwargs.py +33 -8
- a_sync/a_sync/_meta.py +149 -28
- a_sync/a_sync/abstract.py +150 -28
- a_sync/a_sync/base.py +34 -16
- a_sync/a_sync/config.py +85 -14
- a_sync/a_sync/decorator.py +441 -139
- a_sync/a_sync/function.py +709 -147
- a_sync/a_sync/method.py +437 -110
- a_sync/a_sync/modifiers/__init__.py +85 -5
- a_sync/a_sync/modifiers/cache/__init__.py +116 -17
- a_sync/a_sync/modifiers/cache/memory.py +130 -20
- a_sync/a_sync/modifiers/limiter.py +101 -22
- a_sync/a_sync/modifiers/manager.py +142 -16
- a_sync/a_sync/modifiers/semaphores.py +121 -15
- a_sync/a_sync/property.py +383 -82
- a_sync/a_sync/singleton.py +44 -19
- a_sync/aliases.py +0 -1
- a_sync/asyncio/__init__.py +140 -1
- a_sync/asyncio/as_completed.py +213 -79
- a_sync/asyncio/create_task.py +70 -20
- a_sync/asyncio/gather.py +125 -58
- a_sync/asyncio/utils.py +3 -3
- a_sync/exceptions.py +248 -26
- a_sync/executor.py +164 -69
- a_sync/future.py +1227 -168
- a_sync/iter.py +173 -56
- a_sync/primitives/__init__.py +14 -2
- a_sync/primitives/_debug.py +72 -18
- a_sync/primitives/_loggable.py +41 -10
- a_sync/primitives/locks/__init__.py +5 -2
- a_sync/primitives/locks/counter.py +107 -38
- a_sync/primitives/locks/event.py +21 -7
- a_sync/primitives/locks/prio_semaphore.py +262 -63
- a_sync/primitives/locks/semaphore.py +138 -89
- a_sync/primitives/queue.py +601 -60
- a_sync/sphinx/__init__.py +0 -1
- a_sync/sphinx/ext.py +160 -50
- a_sync/task.py +313 -112
- a_sync/utils/__init__.py +12 -6
- a_sync/utils/iterators.py +170 -50
- {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.16.dist-info}/METADATA +1 -1
- ez_a_sync-0.22.16.dist-info/RECORD +74 -0
- {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.16.dist-info}/WHEEL +1 -1
- tests/conftest.py +1 -2
- tests/executor.py +250 -9
- tests/fixtures.py +61 -32
- tests/test_abstract.py +22 -4
- tests/test_as_completed.py +54 -21
- tests/test_base.py +264 -19
- tests/test_cache.py +31 -15
- tests/test_decorator.py +54 -28
- tests/test_executor.py +31 -13
- tests/test_future.py +45 -8
- tests/test_gather.py +8 -2
- tests/test_helpers.py +2 -0
- tests/test_iter.py +55 -13
- tests/test_limiter.py +5 -3
- tests/test_meta.py +23 -9
- tests/test_modified.py +4 -1
- tests/test_semaphore.py +15 -8
- tests/test_singleton.py +28 -11
- tests/test_task.py +162 -36
- ez_a_sync-0.22.14.dist-info/RECORD +0 -74
- {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.16.dist-info}/LICENSE.txt +0 -0
- {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.16.dist-info}/top_level.txt +0 -0
a_sync/exceptions.py
CHANGED
|
@@ -14,28 +14,53 @@ if TYPE_CHECKING:
|
|
|
14
14
|
class ASyncFlagException(ValueError):
|
|
15
15
|
"""
|
|
16
16
|
Base exception class for flag-related errors in the a_sync library.
|
|
17
|
+
|
|
18
|
+
A-Sync uses 'flags' to indicate whether objects or function calls will be sync or async.
|
|
19
|
+
You can use any of the provided flags, whichever makes most sense for your use case.
|
|
17
20
|
"""
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Returns the set of viable flags.
|
|
22
|
-
"""
|
|
23
|
-
return VIABLE_FLAGS
|
|
21
|
+
|
|
22
|
+
viable_flags = VIABLE_FLAGS
|
|
23
|
+
"""The set of viable flags."""
|
|
24
24
|
|
|
25
25
|
def desc(self, target) -> str:
|
|
26
|
-
|
|
26
|
+
"""
|
|
27
|
+
Returns a description of the target for the flag error message.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
target: The target object or string to describe.
|
|
31
|
+
|
|
32
|
+
Examples:
|
|
33
|
+
>>> exception = ASyncFlagException()
|
|
34
|
+
>>> exception.desc("kwargs")
|
|
35
|
+
"flags present in 'kwargs'"
|
|
36
|
+
|
|
37
|
+
>>> exception.desc("some_target")
|
|
38
|
+
'flag attributes defined on some_target'
|
|
39
|
+
"""
|
|
40
|
+
if target == "kwargs":
|
|
27
41
|
return "flags present in 'kwargs'"
|
|
28
42
|
else:
|
|
29
|
-
return f
|
|
43
|
+
return f"flag attributes defined on {target}"
|
|
44
|
+
|
|
30
45
|
|
|
31
46
|
class NoFlagsFound(ASyncFlagException):
|
|
32
47
|
"""
|
|
33
48
|
Raised when no viable flags are found in the target.
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
>>> try:
|
|
52
|
+
... raise NoFlagsFound("some_target")
|
|
53
|
+
... except NoFlagsFound as e:
|
|
54
|
+
... print(e)
|
|
55
|
+
There are no viable a_sync flag attributes defined on some_target:
|
|
56
|
+
Viable flags: {'sync', 'asynchronous'}
|
|
57
|
+
This is likely an issue with a custom subclass definition.
|
|
34
58
|
"""
|
|
59
|
+
|
|
35
60
|
def __init__(self, target, kwargs_keys=None):
|
|
36
61
|
"""
|
|
37
62
|
Initializes the NoFlagsFound exception.
|
|
38
|
-
|
|
63
|
+
|
|
39
64
|
Args:
|
|
40
65
|
target: The target object where flags were expected.
|
|
41
66
|
kwargs_keys: Optional; keys in the kwargs if applicable.
|
|
@@ -47,63 +72,117 @@ class NoFlagsFound(ASyncFlagException):
|
|
|
47
72
|
err += "\nThis is likely an issue with a custom subclass definition."
|
|
48
73
|
super().__init__(err)
|
|
49
74
|
|
|
75
|
+
|
|
50
76
|
class TooManyFlags(ASyncFlagException):
|
|
51
77
|
"""
|
|
52
78
|
Raised when multiple flags are found, but only one was expected.
|
|
79
|
+
|
|
80
|
+
Examples:
|
|
81
|
+
>>> try:
|
|
82
|
+
... raise TooManyFlags("some_target", ["flag1", "flag2"])
|
|
83
|
+
... except TooManyFlags as e:
|
|
84
|
+
... print(e)
|
|
85
|
+
There are multiple a_sync flag attributes defined on some_target and there should only be one.
|
|
86
|
+
Present flags: ['flag1', 'flag2']
|
|
87
|
+
This is likely an issue with a custom subclass definition.
|
|
53
88
|
"""
|
|
89
|
+
|
|
54
90
|
def __init__(self, target, present_flags):
|
|
55
91
|
"""
|
|
56
92
|
Initializes the TooManyFlags exception.
|
|
57
|
-
|
|
93
|
+
|
|
58
94
|
Args:
|
|
59
95
|
target: The target object where flags were found.
|
|
60
96
|
present_flags: The flags that were found.
|
|
97
|
+
|
|
98
|
+
See Also:
|
|
99
|
+
- :class:`ASyncFlagException`
|
|
61
100
|
"""
|
|
62
|
-
err = f"There are multiple a_sync {self.
|
|
101
|
+
err = f"There are multiple a_sync {self.desc(target)} and there should only be one.\n"
|
|
63
102
|
err += f"Present flags: {present_flags}\n"
|
|
64
103
|
err += "This is likely an issue with a custom subclass definition."
|
|
65
104
|
super().__init__(err)
|
|
66
105
|
|
|
106
|
+
|
|
67
107
|
class InvalidFlag(ASyncFlagException):
|
|
68
108
|
"""
|
|
69
109
|
Raised when an invalid flag is encountered.
|
|
110
|
+
|
|
111
|
+
Examples:
|
|
112
|
+
>>> try:
|
|
113
|
+
... raise InvalidFlag("invalid_flag")
|
|
114
|
+
... except InvalidFlag as e:
|
|
115
|
+
... print(e)
|
|
116
|
+
'flag' must be one of: {'sync', 'asynchronous'}. You passed invalid_flag.
|
|
117
|
+
This code should not be reached and likely indicates an issue with a custom subclass definition.
|
|
70
118
|
"""
|
|
119
|
+
|
|
71
120
|
def __init__(self, flag: Optional[str]):
|
|
72
121
|
"""
|
|
73
122
|
Initializes the InvalidFlag exception.
|
|
74
|
-
|
|
123
|
+
|
|
75
124
|
Args:
|
|
76
125
|
flag: The invalid flag.
|
|
126
|
+
|
|
127
|
+
See Also:
|
|
128
|
+
- :class:`ASyncFlagException`
|
|
77
129
|
"""
|
|
78
130
|
err = f"'flag' must be one of: {self.viable_flags}. You passed {flag}."
|
|
79
131
|
err += "\nThis code should not be reached and likely indicates an issue with a custom subclass definition."
|
|
80
132
|
super().__init__(err)
|
|
81
133
|
|
|
134
|
+
|
|
82
135
|
class InvalidFlagValue(ASyncFlagException):
|
|
83
136
|
"""
|
|
84
137
|
Raised when a flag has an invalid value.
|
|
138
|
+
|
|
139
|
+
Examples:
|
|
140
|
+
>>> try:
|
|
141
|
+
... raise InvalidFlagValue("some_flag", "not_a_boolean")
|
|
142
|
+
... except InvalidFlagValue as e:
|
|
143
|
+
... print(e)
|
|
144
|
+
'some_flag' should be boolean. You passed not_a_boolean.
|
|
85
145
|
"""
|
|
146
|
+
|
|
86
147
|
def __init__(self, flag: str, flag_value: Any):
|
|
87
148
|
"""
|
|
88
149
|
Initializes the InvalidFlagValue exception.
|
|
89
|
-
|
|
150
|
+
|
|
90
151
|
Args:
|
|
91
152
|
flag: The flag with an invalid value.
|
|
92
153
|
flag_value: The invalid value of the flag.
|
|
154
|
+
|
|
155
|
+
See Also:
|
|
156
|
+
- :class:`ASyncFlagException`
|
|
93
157
|
"""
|
|
94
158
|
super().__init__(f"'{flag}' should be boolean. You passed {flag_value}.")
|
|
95
159
|
|
|
160
|
+
|
|
96
161
|
class FlagNotDefined(ASyncFlagException):
|
|
97
162
|
"""
|
|
98
163
|
Raised when a flag is not defined on an object.
|
|
164
|
+
|
|
165
|
+
Examples:
|
|
166
|
+
>>> class SomeClass:
|
|
167
|
+
... pass
|
|
168
|
+
...
|
|
169
|
+
>>> try:
|
|
170
|
+
... raise FlagNotDefined(SomeClass, "some_flag")
|
|
171
|
+
... except FlagNotDefined as e:
|
|
172
|
+
... print(e)
|
|
173
|
+
<class '__main__.SomeClass'> flag some_flag is not defined.
|
|
99
174
|
"""
|
|
175
|
+
|
|
100
176
|
def __init__(self, obj: Type, flag: str):
|
|
101
177
|
"""
|
|
102
178
|
Initializes the FlagNotDefined exception.
|
|
103
|
-
|
|
179
|
+
|
|
104
180
|
Args:
|
|
105
181
|
obj: The object where the flag is not defined.
|
|
106
182
|
flag: The undefined flag.
|
|
183
|
+
|
|
184
|
+
See Also:
|
|
185
|
+
- :class:`ASyncFlagException`
|
|
107
186
|
"""
|
|
108
187
|
super().__init__(f"{obj} flag {flag} is not defined.")
|
|
109
188
|
|
|
@@ -111,51 +190,118 @@ class FlagNotDefined(ASyncFlagException):
|
|
|
111
190
|
class ImproperFunctionType(ValueError):
|
|
112
191
|
"""
|
|
113
192
|
Raised when a function that should be sync is async or vice-versa.
|
|
193
|
+
|
|
194
|
+
See Also:
|
|
195
|
+
- :class:`FunctionNotAsync`
|
|
196
|
+
- :class:`FunctionNotSync`
|
|
114
197
|
"""
|
|
115
198
|
|
|
199
|
+
|
|
116
200
|
class FunctionNotAsync(ImproperFunctionType):
|
|
117
201
|
"""
|
|
118
202
|
Raised when a function expected to be async is not.
|
|
203
|
+
|
|
204
|
+
Examples:
|
|
205
|
+
>>> def some_function():
|
|
206
|
+
... pass
|
|
207
|
+
...
|
|
208
|
+
>>> try:
|
|
209
|
+
... raise FunctionNotAsync(some_function)
|
|
210
|
+
... except FunctionNotAsync as e:
|
|
211
|
+
... print(e)
|
|
212
|
+
`coro_fn` must be a coroutine function defined with `async def`. You passed <function some_function at 0x...>.
|
|
119
213
|
"""
|
|
214
|
+
|
|
120
215
|
def __init__(self, fn):
|
|
121
216
|
"""
|
|
122
217
|
Initializes the FunctionNotAsync exception.
|
|
123
|
-
|
|
218
|
+
|
|
124
219
|
Args:
|
|
125
220
|
fn: The function that is not async.
|
|
221
|
+
|
|
222
|
+
See Also:
|
|
223
|
+
- :class:`ImproperFunctionType`
|
|
126
224
|
"""
|
|
127
|
-
super().__init__(
|
|
225
|
+
super().__init__(
|
|
226
|
+
f"`coro_fn` must be a coroutine function defined with `async def`. You passed {fn}."
|
|
227
|
+
)
|
|
228
|
+
|
|
128
229
|
|
|
129
230
|
class FunctionNotSync(ImproperFunctionType):
|
|
130
231
|
"""
|
|
131
|
-
Raised when a function expected to be sync is
|
|
232
|
+
Raised when a function expected to be sync is actually async.
|
|
233
|
+
|
|
234
|
+
Examples:
|
|
235
|
+
>>> async def some_async_function():
|
|
236
|
+
... pass
|
|
237
|
+
...
|
|
238
|
+
>>> try:
|
|
239
|
+
... raise FunctionNotSync(some_async_function)
|
|
240
|
+
... except FunctionNotSync as e:
|
|
241
|
+
... print(e)
|
|
242
|
+
`func` must be a coroutine function defined with `def`. You passed <function some_async_function at 0x...>.
|
|
132
243
|
"""
|
|
244
|
+
|
|
133
245
|
def __init__(self, fn):
|
|
134
246
|
"""
|
|
135
247
|
Initializes the FunctionNotSync exception.
|
|
136
|
-
|
|
248
|
+
|
|
137
249
|
Args:
|
|
138
250
|
fn: The function that is not sync.
|
|
251
|
+
|
|
252
|
+
See Also:
|
|
253
|
+
- :class:`ImproperFunctionType`
|
|
139
254
|
"""
|
|
140
|
-
super().__init__(
|
|
141
|
-
|
|
255
|
+
super().__init__(
|
|
256
|
+
f"`func` must be a coroutine function defined with `def`. You passed {fn}."
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
|
|
142
260
|
class ASyncRuntimeError(RuntimeError):
|
|
261
|
+
"""
|
|
262
|
+
Raised for runtime errors in asynchronous operations.
|
|
263
|
+
|
|
264
|
+
Examples:
|
|
265
|
+
>>> try:
|
|
266
|
+
... raise ASyncRuntimeError(RuntimeError("Some runtime error"))
|
|
267
|
+
... except ASyncRuntimeError as e:
|
|
268
|
+
... print(e)
|
|
269
|
+
Some runtime error
|
|
270
|
+
"""
|
|
271
|
+
|
|
143
272
|
def __init__(self, e: RuntimeError):
|
|
144
273
|
"""
|
|
145
274
|
Initializes the ASyncRuntimeError exception.
|
|
146
|
-
|
|
275
|
+
|
|
147
276
|
Args:
|
|
148
277
|
e: The original runtime error.
|
|
278
|
+
|
|
279
|
+
See Also:
|
|
280
|
+
- :class:`RuntimeError`
|
|
149
281
|
"""
|
|
150
282
|
super().__init__(str(e))
|
|
151
283
|
|
|
284
|
+
|
|
152
285
|
class SyncModeInAsyncContextError(ASyncRuntimeError):
|
|
153
286
|
"""
|
|
154
287
|
Raised when synchronous code is used within an asynchronous context.
|
|
288
|
+
|
|
289
|
+
Examples:
|
|
290
|
+
>>> try:
|
|
291
|
+
... raise SyncModeInAsyncContextError()
|
|
292
|
+
... except SyncModeInAsyncContextError as e:
|
|
293
|
+
... print(e)
|
|
294
|
+
The event loop is already running, which means you're trying to use an `ASyncFunction` synchronously from within an async context.
|
|
295
|
+
Check your traceback to determine which, then try calling asynchronously instead with one of the following kwargs:
|
|
296
|
+
{'sync', 'asynchronous'}
|
|
155
297
|
"""
|
|
156
|
-
|
|
298
|
+
|
|
299
|
+
def __init__(self, err: str = ""):
|
|
157
300
|
"""
|
|
158
301
|
Initializes the SyncModeInAsyncContextError exception.
|
|
302
|
+
|
|
303
|
+
See Also:
|
|
304
|
+
- :class:`ASyncRuntimeError`
|
|
159
305
|
"""
|
|
160
306
|
if not err:
|
|
161
307
|
err = "The event loop is already running, which means you're trying to use an `ASyncFunction` synchronously from within an async context.\n"
|
|
@@ -163,45 +309,121 @@ class SyncModeInAsyncContextError(ASyncRuntimeError):
|
|
|
163
309
|
err += f"{VIABLE_FLAGS}"
|
|
164
310
|
super().__init__(err)
|
|
165
311
|
|
|
312
|
+
|
|
166
313
|
class MappingError(Exception):
|
|
167
314
|
"""
|
|
168
315
|
Base class for errors related to :class:`~TaskMapping`.
|
|
316
|
+
|
|
317
|
+
Examples:
|
|
318
|
+
>>> from a_sync import TaskMapping
|
|
319
|
+
>>> try:
|
|
320
|
+
... raise MappingError(TaskMapping(), "Some mapping error")
|
|
321
|
+
... except MappingError as e:
|
|
322
|
+
... print(e)
|
|
323
|
+
Some mapping error:
|
|
324
|
+
<TaskMapping object at 0x...>
|
|
325
|
+
{}
|
|
169
326
|
"""
|
|
327
|
+
|
|
170
328
|
_msg: str
|
|
171
329
|
|
|
172
|
-
def __init__(self, mapping: "TaskMapping", msg: str =
|
|
330
|
+
def __init__(self, mapping: "TaskMapping", msg: str = ""):
|
|
173
331
|
"""
|
|
174
332
|
Initializes the MappingError exception.
|
|
175
|
-
|
|
333
|
+
|
|
176
334
|
Args:
|
|
177
335
|
mapping: The TaskMapping where the error occurred.
|
|
178
336
|
msg: An optional message describing the error.
|
|
337
|
+
|
|
338
|
+
See Also:
|
|
339
|
+
- :class:`TaskMapping`
|
|
179
340
|
"""
|
|
180
|
-
msg = msg or self._msg + f":\n{mapping}"
|
|
341
|
+
msg = (msg or self._msg) + f":\n{mapping}"
|
|
181
342
|
if mapping:
|
|
182
343
|
msg += f"\n{dict(mapping)}"
|
|
183
344
|
super().__init__(msg)
|
|
184
345
|
self.mapping = mapping
|
|
185
346
|
|
|
347
|
+
|
|
186
348
|
class MappingIsEmptyError(MappingError):
|
|
187
349
|
"""
|
|
188
350
|
Raised when a TaskMapping is empty and an operation requires it to have items.
|
|
351
|
+
|
|
352
|
+
Examples:
|
|
353
|
+
>>> from a_sync import TaskMapping
|
|
354
|
+
>>> try:
|
|
355
|
+
... raise MappingIsEmptyError(TaskMapping())
|
|
356
|
+
... except MappingIsEmptyError as e:
|
|
357
|
+
... print(e)
|
|
358
|
+
TaskMapping does not contain anything to yield:
|
|
359
|
+
<TaskMapping object at 0x...>
|
|
360
|
+
{}
|
|
189
361
|
"""
|
|
362
|
+
|
|
190
363
|
_msg = "TaskMapping does not contain anything to yield"
|
|
191
364
|
|
|
365
|
+
|
|
192
366
|
class MappingNotEmptyError(MappingError):
|
|
193
367
|
"""
|
|
194
368
|
Raised when a TaskMapping is not empty and an operation requires it to be empty.
|
|
369
|
+
|
|
370
|
+
Examples:
|
|
371
|
+
>>> from a_sync import TaskMapping
|
|
372
|
+
>>> task_mapping = TaskMapping()
|
|
373
|
+
>>> task_mapping['key'] = 'value'
|
|
374
|
+
>>> try:
|
|
375
|
+
... raise MappingNotEmptyError(task_mapping)
|
|
376
|
+
... except MappingNotEmptyError as e:
|
|
377
|
+
... print(e)
|
|
378
|
+
TaskMapping already contains some data. In order to use `map`, you need a fresh one:
|
|
379
|
+
<TaskMapping object at 0x...>
|
|
380
|
+
{'key': 'value'}
|
|
195
381
|
"""
|
|
382
|
+
|
|
196
383
|
_msg = "TaskMapping already contains some data. In order to use `map`, you need a fresh one"
|
|
197
384
|
|
|
385
|
+
|
|
198
386
|
class PersistedTaskException(Exception):
|
|
387
|
+
"""
|
|
388
|
+
Raised when an exception persists in an asyncio Task.
|
|
389
|
+
|
|
390
|
+
Examples:
|
|
391
|
+
>>> import asyncio
|
|
392
|
+
>>> async def some_task():
|
|
393
|
+
... raise ValueError("Some error")
|
|
394
|
+
...
|
|
395
|
+
>>> task = asyncio.create_task(some_task())
|
|
396
|
+
>>> try:
|
|
397
|
+
... raise PersistedTaskException(ValueError("Some error"), task)
|
|
398
|
+
... except PersistedTaskException as e:
|
|
399
|
+
... print(e)
|
|
400
|
+
ValueError: Some error
|
|
401
|
+
"""
|
|
402
|
+
|
|
199
403
|
def __init__(self, exc: E, task: asyncio.Task) -> None:
|
|
404
|
+
"""
|
|
405
|
+
Initializes the PersistedTaskException exception.
|
|
406
|
+
|
|
407
|
+
Args:
|
|
408
|
+
exc: The exception that persisted.
|
|
409
|
+
task: The asyncio Task where the exception occurred.
|
|
410
|
+
|
|
411
|
+
See Also:
|
|
412
|
+
- :class:`asyncio.Task`
|
|
413
|
+
"""
|
|
200
414
|
super().__init__(f"{exc.__class__.__name__}: {exc}", task)
|
|
201
415
|
self.exception = exc
|
|
202
416
|
self.task = task
|
|
203
417
|
|
|
418
|
+
|
|
204
419
|
class EmptySequenceError(ValueError):
|
|
205
420
|
"""
|
|
206
|
-
Raised when an operation is attempted on an empty sequence but items are
|
|
421
|
+
Raised when an operation is attempted on an empty sequence but items are required.
|
|
422
|
+
|
|
423
|
+
Examples:
|
|
424
|
+
>>> try:
|
|
425
|
+
... raise EmptySequenceError("Sequence is empty")
|
|
426
|
+
... except EmptySequenceError as e:
|
|
427
|
+
... print(e)
|
|
428
|
+
Sequence is empty
|
|
207
429
|
"""
|