ez-a-sync 0.22.14__py3-none-any.whl → 0.22.15__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 +4 -3
- a_sync/__init__.py +30 -12
- a_sync/_smart.py +132 -28
- a_sync/_typing.py +56 -12
- a_sync/a_sync/__init__.py +35 -10
- a_sync/a_sync/_descriptor.py +74 -26
- a_sync/a_sync/_flags.py +14 -6
- a_sync/a_sync/_helpers.py +8 -7
- a_sync/a_sync/_kwargs.py +3 -2
- a_sync/a_sync/_meta.py +120 -28
- a_sync/a_sync/abstract.py +102 -28
- a_sync/a_sync/base.py +34 -16
- a_sync/a_sync/config.py +47 -13
- a_sync/a_sync/decorator.py +239 -117
- a_sync/a_sync/function.py +416 -146
- a_sync/a_sync/method.py +197 -59
- a_sync/a_sync/modifiers/__init__.py +47 -5
- a_sync/a_sync/modifiers/cache/__init__.py +46 -17
- a_sync/a_sync/modifiers/cache/memory.py +86 -20
- a_sync/a_sync/modifiers/limiter.py +52 -22
- a_sync/a_sync/modifiers/manager.py +98 -16
- a_sync/a_sync/modifiers/semaphores.py +48 -15
- a_sync/a_sync/property.py +383 -82
- a_sync/a_sync/singleton.py +1 -0
- a_sync/aliases.py +0 -1
- a_sync/asyncio/__init__.py +4 -1
- a_sync/asyncio/as_completed.py +177 -49
- a_sync/asyncio/create_task.py +31 -17
- a_sync/asyncio/gather.py +72 -52
- a_sync/asyncio/utils.py +3 -3
- a_sync/exceptions.py +78 -23
- a_sync/executor.py +118 -71
- a_sync/future.py +575 -158
- a_sync/iter.py +110 -50
- a_sync/primitives/__init__.py +14 -2
- a_sync/primitives/_debug.py +13 -13
- a_sync/primitives/_loggable.py +5 -4
- a_sync/primitives/locks/__init__.py +5 -2
- a_sync/primitives/locks/counter.py +38 -36
- a_sync/primitives/locks/event.py +21 -7
- a_sync/primitives/locks/prio_semaphore.py +182 -62
- a_sync/primitives/locks/semaphore.py +78 -77
- a_sync/primitives/queue.py +560 -58
- a_sync/sphinx/__init__.py +0 -1
- a_sync/sphinx/ext.py +160 -50
- a_sync/task.py +262 -97
- a_sync/utils/__init__.py +12 -6
- a_sync/utils/iterators.py +127 -43
- {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.15.dist-info}/METADATA +1 -1
- ez_a_sync-0.22.15.dist-info/RECORD +74 -0
- {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.15.dist-info}/WHEEL +1 -1
- tests/conftest.py +1 -2
- tests/executor.py +112 -9
- tests/fixtures.py +61 -32
- tests/test_abstract.py +7 -4
- tests/test_as_completed.py +54 -21
- tests/test_base.py +66 -17
- tests/test_cache.py +31 -15
- tests/test_decorator.py +54 -28
- tests/test_executor.py +8 -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 +15 -10
- tests/test_task.py +126 -28
- ez_a_sync-0.22.14.dist-info/RECORD +0 -74
- {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.15.dist-info}/LICENSE.txt +0 -0
- {ez_a_sync-0.22.14.dist-info → ez_a_sync-0.22.15.dist-info}/top_level.txt +0 -0
tests/test_iter.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import asyncio
|
|
3
2
|
import contextlib
|
|
4
3
|
import pytest
|
|
@@ -10,30 +9,35 @@ from a_sync.exceptions import SyncModeInAsyncContextError
|
|
|
10
9
|
from a_sync.iter import ASyncIterable, ASyncIterator
|
|
11
10
|
|
|
12
11
|
|
|
13
|
-
|
|
14
12
|
test_both = pytest.mark.parametrize("cls_to_test", [ASyncIterable, ASyncIterator])
|
|
15
13
|
|
|
14
|
+
|
|
16
15
|
@pytest.fixture
|
|
17
16
|
def async_generator():
|
|
18
17
|
async def async_gen(i: int = 3):
|
|
19
18
|
for i in range(i):
|
|
20
19
|
yield i
|
|
20
|
+
|
|
21
21
|
yield async_gen
|
|
22
22
|
|
|
23
|
+
|
|
23
24
|
@pytest.fixture
|
|
24
25
|
def async_generator_empty():
|
|
25
26
|
async def async_gen_empty():
|
|
26
27
|
if True:
|
|
27
28
|
return
|
|
28
29
|
yield
|
|
30
|
+
|
|
29
31
|
yield async_gen_empty
|
|
30
32
|
|
|
33
|
+
|
|
31
34
|
@pytest.fixture
|
|
32
35
|
def async_error_generator():
|
|
33
36
|
async def async_err_gen():
|
|
34
37
|
yield 0
|
|
35
38
|
yield 1
|
|
36
39
|
raise ValueError("Simulated error")
|
|
40
|
+
|
|
37
41
|
return async_err_gen
|
|
38
42
|
|
|
39
43
|
|
|
@@ -42,6 +46,7 @@ def test_wrap_types(cls_to_test, async_generator):
|
|
|
42
46
|
assert isinstance(cls_to_test(async_generator()), cls_to_test)
|
|
43
47
|
assert isinstance(cls_to_test.wrap(async_generator()), cls_to_test)
|
|
44
48
|
|
|
49
|
+
|
|
45
50
|
@test_both
|
|
46
51
|
def test_sync(cls_to_test, async_generator):
|
|
47
52
|
# sourcery skip: identity-comprehension, list-comprehension
|
|
@@ -64,13 +69,17 @@ def test_sync(cls_to_test, async_generator):
|
|
|
64
69
|
assert cls_to_test(async_generator()).materialized == [0, 1, 2]
|
|
65
70
|
assert cls_to_test.wrap(async_generator()).materialized == [0, 1, 2]
|
|
66
71
|
|
|
72
|
+
|
|
67
73
|
@test_both
|
|
68
74
|
@pytest.mark.asyncio_cooperative
|
|
69
75
|
async def test_async(cls_to_test, async_generator):
|
|
70
76
|
ait = cls_to_test(async_generator())
|
|
71
77
|
|
|
72
78
|
# comprehension
|
|
73
|
-
with pytest.raises(
|
|
79
|
+
with pytest.raises(
|
|
80
|
+
SyncModeInAsyncContextError,
|
|
81
|
+
match="The event loop is already running. Try iterating using `async for` instead of `for`.",
|
|
82
|
+
):
|
|
74
83
|
list(ait)
|
|
75
84
|
assert [i async for i in ait] == [0, 1, 2]
|
|
76
85
|
|
|
@@ -79,7 +88,10 @@ async def test_async(cls_to_test, async_generator):
|
|
|
79
88
|
async for item in cls_to_test(async_generator()):
|
|
80
89
|
result.append(item)
|
|
81
90
|
assert result == [0, 1, 2]
|
|
82
|
-
with pytest.raises(
|
|
91
|
+
with pytest.raises(
|
|
92
|
+
SyncModeInAsyncContextError,
|
|
93
|
+
match="The event loop is already running. Try iterating using `async for` instead of `for`.",
|
|
94
|
+
):
|
|
83
95
|
for _ in cls_to_test(async_generator()):
|
|
84
96
|
pass
|
|
85
97
|
|
|
@@ -95,11 +107,15 @@ async def test_async(cls_to_test, async_generator):
|
|
|
95
107
|
def test_sync_empty(cls_to_test, async_generator_empty):
|
|
96
108
|
assert not list(cls_to_test(async_generator_empty()))
|
|
97
109
|
|
|
110
|
+
|
|
98
111
|
@test_both
|
|
99
112
|
@pytest.mark.asyncio_cooperative
|
|
100
113
|
async def test_async_empty(cls_to_test, async_generator_empty):
|
|
101
114
|
ait = cls_to_test(async_generator_empty())
|
|
102
|
-
with pytest.raises(
|
|
115
|
+
with pytest.raises(
|
|
116
|
+
SyncModeInAsyncContextError,
|
|
117
|
+
match="The event loop is already running. Try iterating using `async for` instead of `for`.",
|
|
118
|
+
):
|
|
103
119
|
list(ait)
|
|
104
120
|
assert not [i async for i in ait]
|
|
105
121
|
|
|
@@ -118,6 +134,7 @@ def test_sync_partial(cls_to_test, async_generator):
|
|
|
118
134
|
remaining = list(iterator)
|
|
119
135
|
assert remaining == [3, 4] if cls_to_test is ASyncIterator else [0, 1, 2, 3, 4]
|
|
120
136
|
|
|
137
|
+
|
|
121
138
|
@test_both
|
|
122
139
|
@pytest.mark.asyncio_cooperative
|
|
123
140
|
async def test_async_partial(cls_to_test, async_generator):
|
|
@@ -146,6 +163,7 @@ def test_stop_iteration_sync(cls_to_test, async_generator):
|
|
|
146
163
|
with pytest.raises(StopIteration):
|
|
147
164
|
next(it)
|
|
148
165
|
|
|
166
|
+
|
|
149
167
|
@test_both
|
|
150
168
|
@pytest.mark.asyncio_cooperative
|
|
151
169
|
async def test_stop_iteration_async(cls_to_test, async_generator):
|
|
@@ -162,15 +180,23 @@ async def test_stop_iteration_async(cls_to_test, async_generator):
|
|
|
162
180
|
|
|
163
181
|
# Test decorator
|
|
164
182
|
|
|
183
|
+
|
|
165
184
|
def test_aiterable_decorated_func_sync():
|
|
166
|
-
with pytest.raises(
|
|
185
|
+
with pytest.raises(
|
|
186
|
+
TypeError, match="`async_iterable` must be an AsyncIterable. You passed "
|
|
187
|
+
):
|
|
188
|
+
|
|
167
189
|
@ASyncIterable.wrap
|
|
168
190
|
async def decorated():
|
|
169
191
|
yield 0
|
|
170
|
-
|
|
192
|
+
|
|
193
|
+
|
|
171
194
|
@pytest.mark.asyncio_cooperative
|
|
172
195
|
async def test_aiterable_decorated_func_async(async_generator):
|
|
173
|
-
with pytest.raises(
|
|
196
|
+
with pytest.raises(
|
|
197
|
+
TypeError, match="`async_iterable` must be an AsyncIterable. You passed "
|
|
198
|
+
):
|
|
199
|
+
|
|
174
200
|
@ASyncIterable.wrap
|
|
175
201
|
async def decorated():
|
|
176
202
|
yield 0
|
|
@@ -181,16 +207,19 @@ def test_aiterator_decorated_func_sync(async_generator):
|
|
|
181
207
|
async def decorated():
|
|
182
208
|
async for i in async_generator():
|
|
183
209
|
yield i
|
|
210
|
+
|
|
184
211
|
retval = decorated()
|
|
185
212
|
assert isinstance(retval, ASyncIterator)
|
|
186
213
|
assert list(retval) == [0, 1, 2]
|
|
187
|
-
|
|
214
|
+
|
|
215
|
+
|
|
188
216
|
@pytest.mark.asyncio_cooperative
|
|
189
217
|
async def test_aiterator_decorated_func_async(async_generator):
|
|
190
218
|
@ASyncIterator.wrap
|
|
191
219
|
async def decorated():
|
|
192
220
|
async for i in async_generator():
|
|
193
221
|
yield i
|
|
222
|
+
|
|
194
223
|
retval = decorated()
|
|
195
224
|
assert isinstance(retval, ASyncIterator)
|
|
196
225
|
assert await retval == [0, 1, 2]
|
|
@@ -198,14 +227,17 @@ async def test_aiterator_decorated_func_async(async_generator):
|
|
|
198
227
|
|
|
199
228
|
def test_aiterable_decorated_method_sync():
|
|
200
229
|
with pytest.raises(TypeError, match=""):
|
|
230
|
+
|
|
201
231
|
class Test:
|
|
202
232
|
@ASyncIterable.wrap
|
|
203
233
|
async def decorated(self):
|
|
204
234
|
yield 0
|
|
205
|
-
|
|
235
|
+
|
|
236
|
+
|
|
206
237
|
@pytest.mark.asyncio_cooperative
|
|
207
238
|
async def test_aiterable_decorated_method_async():
|
|
208
239
|
with pytest.raises(TypeError, match=""):
|
|
240
|
+
|
|
209
241
|
class Test:
|
|
210
242
|
@ASyncIterable.wrap
|
|
211
243
|
async def decorated(self):
|
|
@@ -218,10 +250,12 @@ def test_aiterator_decorated_method_sync(async_generator):
|
|
|
218
250
|
async def decorated(self):
|
|
219
251
|
async for i in async_generator():
|
|
220
252
|
yield i
|
|
253
|
+
|
|
221
254
|
retval = Test().decorated()
|
|
222
255
|
assert isinstance(retval, ASyncIterator)
|
|
223
256
|
assert list(retval) == [0, 1, 2]
|
|
224
|
-
|
|
257
|
+
|
|
258
|
+
|
|
225
259
|
@pytest.mark.asyncio_cooperative
|
|
226
260
|
async def test_aiterator_decorated_method_async(async_generator):
|
|
227
261
|
class Test:
|
|
@@ -229,10 +263,11 @@ async def test_aiterator_decorated_method_async(async_generator):
|
|
|
229
263
|
async def decorated(self):
|
|
230
264
|
async for i in async_generator():
|
|
231
265
|
yield i
|
|
266
|
+
|
|
232
267
|
retval = Test().decorated()
|
|
233
268
|
assert isinstance(retval, ASyncIterator)
|
|
234
269
|
assert await retval == [0, 1, 2]
|
|
235
|
-
|
|
270
|
+
|
|
236
271
|
|
|
237
272
|
@test_both
|
|
238
273
|
def test_sync_error_handling(cls_to_test, async_error_generator):
|
|
@@ -243,6 +278,7 @@ def test_sync_error_handling(cls_to_test, async_error_generator):
|
|
|
243
278
|
# we still got some results though
|
|
244
279
|
assert results == [0, 1]
|
|
245
280
|
|
|
281
|
+
|
|
246
282
|
@test_both
|
|
247
283
|
@pytest.mark.asyncio_cooperative
|
|
248
284
|
async def test_async_error_handling(cls_to_test, async_error_generator):
|
|
@@ -257,11 +293,13 @@ async def test_async_error_handling(cls_to_test, async_error_generator):
|
|
|
257
293
|
|
|
258
294
|
# Test failures
|
|
259
295
|
|
|
296
|
+
|
|
260
297
|
@test_both
|
|
261
298
|
def test_sync_with_iterable(cls_to_test):
|
|
262
299
|
with pytest.raises(TypeError):
|
|
263
300
|
cls_to_test([0, 1, 2])
|
|
264
301
|
|
|
302
|
+
|
|
265
303
|
@test_both
|
|
266
304
|
@pytest.mark.asyncio_cooperative
|
|
267
305
|
async def test_async_with_iterable(cls_to_test):
|
|
@@ -271,24 +309,28 @@ async def test_async_with_iterable(cls_to_test):
|
|
|
271
309
|
|
|
272
310
|
# Type check dunder methods
|
|
273
311
|
|
|
312
|
+
|
|
274
313
|
def test_async_iterable_iter_method(async_generator):
|
|
275
314
|
ait = ASyncIterable(async_generator())
|
|
276
315
|
iterator = iter(ait)
|
|
277
316
|
assert isinstance(iterator, Iterator)
|
|
278
317
|
|
|
318
|
+
|
|
279
319
|
def test_async_iterator_iter_method(async_generator):
|
|
280
320
|
ait = ASyncIterator(async_generator())
|
|
281
321
|
iterator = iter(ait)
|
|
282
322
|
assert iterator is ait # Should return self
|
|
283
323
|
|
|
324
|
+
|
|
284
325
|
@pytest.mark.asyncio_cooperative
|
|
285
326
|
async def test_async_aiter_method(async_generator):
|
|
286
327
|
ait = ASyncIterable(async_generator())
|
|
287
328
|
async_iterator = ait.__aiter__()
|
|
288
329
|
assert isinstance(async_iterator, AsyncIterator)
|
|
289
330
|
|
|
331
|
+
|
|
290
332
|
@pytest.mark.asyncio_cooperative
|
|
291
333
|
async def test_async_iterator_aiter_method(async_generator):
|
|
292
334
|
ait = ASyncIterator(async_generator())
|
|
293
335
|
async_iterator = ait.__aiter__()
|
|
294
|
-
assert async_iterator is ait # Should return self
|
|
336
|
+
assert async_iterator is ait # Should return self
|
tests/test_limiter.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import pytest
|
|
3
2
|
from time import time
|
|
4
3
|
from tests.fixtures import TestLimiter, increment
|
|
@@ -9,18 +8,21 @@ from tests.fixtures import TestLimiter, increment
|
|
|
9
8
|
# Maybe a problem with test suite interaction?
|
|
10
9
|
# - semaphore modifier works fine with integer inputs
|
|
11
10
|
|
|
11
|
+
|
|
12
12
|
@increment
|
|
13
13
|
@pytest.mark.asyncio_cooperative
|
|
14
14
|
async def test_semaphore(i: int):
|
|
15
15
|
instance = TestLimiter(i, sync=False)
|
|
16
16
|
assert await instance.test_fn() == i
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
|
|
18
19
|
@increment
|
|
19
20
|
@pytest.mark.asyncio_cooperative
|
|
20
21
|
async def test_semaphore_property(i: int):
|
|
21
22
|
instance = TestLimiter(i, sync=False)
|
|
22
23
|
assert await instance.test_property == i * 2
|
|
23
|
-
|
|
24
|
+
|
|
25
|
+
|
|
24
26
|
@increment
|
|
25
27
|
@pytest.mark.asyncio_cooperative
|
|
26
28
|
async def test_semaphore_cached_property(i: int):
|
tests/test_meta.py
CHANGED
|
@@ -9,7 +9,8 @@ from a_sync.a_sync.property import HiddenMethod
|
|
|
9
9
|
from a_sync.a_sync.singleton import ASyncGenericSingleton
|
|
10
10
|
from tests.fixtures import TestSingleton, TestSingletonMeta, increment
|
|
11
11
|
|
|
12
|
-
classes = pytest.mark.parametrize(
|
|
12
|
+
classes = pytest.mark.parametrize("cls", [TestSingleton, TestSingletonMeta])
|
|
13
|
+
|
|
13
14
|
|
|
14
15
|
@classes
|
|
15
16
|
@increment
|
|
@@ -24,7 +25,9 @@ def test_singleton_meta_sync(cls: type, i: int):
|
|
|
24
25
|
assert sync_instance.test_cached_property == 0
|
|
25
26
|
assert isinstance(sync_instance.test_cached_property, int)
|
|
26
27
|
duration = time.time() - start
|
|
27
|
-
assert
|
|
28
|
+
assert (
|
|
29
|
+
duration < 3
|
|
30
|
+
), "There is a 2 second sleep in 'test_cached_property' but it should only run once."
|
|
28
31
|
|
|
29
32
|
# Can we override with kwargs?
|
|
30
33
|
val = asyncio.get_event_loop().run_until_complete(sync_instance.test_fn(sync=False))
|
|
@@ -41,9 +44,17 @@ def test_singleton_meta_sync(cls: type, i: int):
|
|
|
41
44
|
getter_coro = getter()
|
|
42
45
|
assert asyncio.get_event_loop().run_until_complete(getter_coro) == 0
|
|
43
46
|
# Can we override them too?
|
|
44
|
-
assert
|
|
47
|
+
assert (
|
|
48
|
+
asyncio.get_event_loop().run_until_complete(
|
|
49
|
+
sync_instance.__test_cached_property__(sync=False)
|
|
50
|
+
)
|
|
51
|
+
== 0
|
|
52
|
+
)
|
|
45
53
|
duration = time.time() - start
|
|
46
|
-
assert
|
|
54
|
+
assert (
|
|
55
|
+
duration < 3
|
|
56
|
+
), "There is a 2 second sleep in 'test_cached_property' but it should only run once."
|
|
57
|
+
|
|
47
58
|
|
|
48
59
|
@classes
|
|
49
60
|
@increment
|
|
@@ -59,12 +70,14 @@ async def test_singleton_meta_async(cls: type, i: int):
|
|
|
59
70
|
assert await async_instance.test_cached_property == 0
|
|
60
71
|
assert isinstance(await async_instance.test_cached_property, int)
|
|
61
72
|
duration = time.time() - start
|
|
62
|
-
assert
|
|
73
|
+
assert (
|
|
74
|
+
duration < 3
|
|
75
|
+
), "There is a 2 second sleep in 'test_cached_property' but it should only run once."
|
|
63
76
|
|
|
64
77
|
# Can we override with kwargs?
|
|
65
78
|
with pytest.raises(RuntimeError):
|
|
66
79
|
async_instance.test_fn(sync=True)
|
|
67
|
-
|
|
80
|
+
|
|
68
81
|
# Can we access hidden methods for properties?
|
|
69
82
|
assert await async_instance.__test_property__() == 0
|
|
70
83
|
assert await async_instance.__test_cached_property__() == 0
|
|
@@ -73,24 +86,25 @@ async def test_singleton_meta_async(cls: type, i: int):
|
|
|
73
86
|
async_instance.__test_cached_property__(sync=True)
|
|
74
87
|
|
|
75
88
|
|
|
76
|
-
|
|
77
89
|
class TestUnspecified(ASyncGenericSingleton):
|
|
78
90
|
def __init__(self, sync=True):
|
|
79
91
|
self.sync = sync
|
|
80
92
|
|
|
93
|
+
|
|
81
94
|
def test_singleton_unspecified():
|
|
82
95
|
obj = TestUnspecified()
|
|
83
96
|
assert obj.sync == True
|
|
84
97
|
obj.test_attr = True
|
|
85
98
|
newobj = TestUnspecified()
|
|
86
|
-
assert hasattr(newobj,
|
|
99
|
+
assert hasattr(newobj, "test_attr")
|
|
87
100
|
|
|
88
101
|
assert TestUnspecified(sync=True).sync == True
|
|
89
102
|
assert TestUnspecified(sync=False).sync == False
|
|
90
103
|
|
|
104
|
+
|
|
91
105
|
def test_singleton_switching():
|
|
92
106
|
obj = TestUnspecified()
|
|
93
107
|
assert obj.sync == True
|
|
94
108
|
obj.test_attr = True
|
|
95
109
|
newobj = TestUnspecified(sync=False)
|
|
96
|
-
assert not hasattr(newobj,
|
|
110
|
+
assert not hasattr(newobj, "test_attr")
|
tests/test_modified.py
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
|
|
2
1
|
import a_sync
|
|
3
2
|
|
|
3
|
+
|
|
4
4
|
@a_sync.a_sync
|
|
5
5
|
def sync_def():
|
|
6
6
|
pass
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
@a_sync.a_sync
|
|
9
10
|
async def async_def():
|
|
10
11
|
pass
|
|
11
12
|
|
|
13
|
+
|
|
12
14
|
def test_sync_def_repr():
|
|
13
15
|
assert sync_def.__name__ == "sync_def"
|
|
14
16
|
|
|
17
|
+
|
|
15
18
|
def test_async_def_repr():
|
|
16
19
|
assert async_def.__name__ == "async_def"
|
tests/test_semaphore.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import pytest
|
|
3
2
|
from time import time
|
|
4
3
|
from tests.fixtures import TestSemaphore, increment
|
|
@@ -12,30 +11,38 @@ from tests.fixtures import TestSemaphore, increment
|
|
|
12
11
|
|
|
13
12
|
instance = TestSemaphore(1, sync=False)
|
|
14
13
|
|
|
14
|
+
|
|
15
15
|
@increment
|
|
16
16
|
@pytest.mark.asyncio_cooperative
|
|
17
17
|
async def test_semaphore(i: int):
|
|
18
18
|
start = time()
|
|
19
19
|
assert await instance.test_fn() == 1
|
|
20
20
|
duration = time() - start
|
|
21
|
-
assert
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
assert (
|
|
22
|
+
i < 3 or duration > i
|
|
23
|
+
) # There is a 1 second sleep in this fn. If the semaphore is not working, all tests will complete in 1 second.
|
|
24
|
+
|
|
25
|
+
|
|
24
26
|
@increment
|
|
25
27
|
@pytest.mark.asyncio_cooperative
|
|
26
28
|
async def test_semaphore_property(i: int):
|
|
27
29
|
start = time()
|
|
28
30
|
assert await instance.test_property == 2
|
|
29
31
|
duration = time() - start
|
|
30
|
-
assert
|
|
31
|
-
|
|
32
|
+
assert (
|
|
33
|
+
i < 3 or duration > i
|
|
34
|
+
) # There is a 1 second sleep in this fn. If the semaphore is not working, all tests will complete in 1 second.
|
|
35
|
+
|
|
36
|
+
|
|
32
37
|
@increment
|
|
33
38
|
@pytest.mark.asyncio_cooperative
|
|
34
39
|
async def test_semaphore_cached_property(i: int):
|
|
35
40
|
start = time()
|
|
36
41
|
assert await instance.test_cached_property == 3
|
|
37
42
|
duration = time() - start
|
|
38
|
-
# There is a 1 second sleep in this fn but a semaphore override with a value of 50.
|
|
43
|
+
# There is a 1 second sleep in this fn but a semaphore override with a value of 50.
|
|
39
44
|
# You can tell it worked correctly because the class-defined semaphore value is just one, whch would cause this test to fail if it were used.
|
|
40
45
|
# If the override is not working, all tests will complete in just over 1 second.
|
|
41
|
-
assert
|
|
46
|
+
assert (
|
|
47
|
+
i == 1 or duration < 1.4
|
|
48
|
+
) # We increased the threshold from 1.05 to 1.4 to help tests pass on slow github runners
|
tests/test_singleton.py
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
|
|
2
1
|
from a_sync.a_sync.singleton import ASyncGenericSingleton
|
|
3
2
|
|
|
3
|
+
|
|
4
4
|
def test_flag_predefined():
|
|
5
5
|
"""We had a failure case where the subclass implementation assigned the flag value to the class and did not allow user to determine at init time"""
|
|
6
|
+
|
|
6
7
|
class Test(ASyncGenericSingleton):
|
|
7
|
-
sync=True
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
sync = True
|
|
9
|
+
|
|
10
|
+
def __init__(self): ...
|
|
11
|
+
|
|
10
12
|
Test()
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
|
|
14
|
+
class TestInherit(Test): ...
|
|
15
|
+
|
|
13
16
|
TestInherit()
|
|
14
17
|
|
|
15
18
|
class Test(ASyncGenericSingleton):
|
|
16
|
-
sync=False
|
|
19
|
+
sync = False
|
|
20
|
+
|
|
17
21
|
Test()
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
|
|
23
|
+
class TestInherit(Test): ...
|
|
24
|
+
|
|
25
|
+
TestInherit()
|