-
-
Notifications
You must be signed in to change notification settings - Fork 182
Rewrite Semaphore.acquire/release #271
Changes from all commits
2b255ad
dd99680
538dcf8
1d71a9f
5f0cdba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,6 @@ | |
| import asyncio | ||
| from asyncio import test_utils | ||
|
|
||
|
|
||
| STR_RGX_REPR = ( | ||
| r'^<(?P<class>.*?) object at (?P<address>.*?)' | ||
| r'\[(?P<extras>' | ||
|
|
@@ -673,7 +672,6 @@ def test_ambiguous_loops(self): | |
|
|
||
|
|
||
| class SemaphoreTests(test_utils.TestCase): | ||
|
|
||
| def setUp(self): | ||
| self.loop = self.new_test_loop() | ||
|
|
||
|
|
@@ -783,22 +781,20 @@ def c4(result): | |
|
|
||
| test_utils.run_briefly(self.loop) | ||
| self.assertEqual(0, sem._value) | ||
| self.assertEqual([1, 2, 3], result) | ||
| self.assertEqual(3, len(result)) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you change this to something like assertEqual({1, 2, 3}, set(result))?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But only
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gvanrossum Do we need to add assertTrue(1 in result) or remove assertEqual(3, len(result)) here?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I see. Then I think what you have is fine. (Boy this is a complex test. :-) |
||
| self.assertTrue(sem.locked()) | ||
| self.assertEqual(1, len(sem._waiters)) | ||
| self.assertEqual(0, sem._value) | ||
|
|
||
| self.assertTrue(t1.done()) | ||
| self.assertTrue(t1.result()) | ||
| self.assertTrue(t2.done()) | ||
| self.assertTrue(t2.result()) | ||
| self.assertTrue(t3.done()) | ||
| self.assertTrue(t3.result()) | ||
| self.assertFalse(t4.done()) | ||
| race_tasks = [t2, t3, t4] | ||
| done_tasks = [t for t in race_tasks if t.done() and t.result()] | ||
| self.assertTrue(2, len(done_tasks)) | ||
|
|
||
| # cleanup locked semaphore | ||
| sem.release() | ||
| self.loop.run_until_complete(t4) | ||
| self.loop.run_until_complete(asyncio.gather(*race_tasks)) | ||
|
|
||
| def test_acquire_cancel(self): | ||
| sem = asyncio.Semaphore(loop=self.loop) | ||
|
|
@@ -809,7 +805,44 @@ def test_acquire_cancel(self): | |
| self.assertRaises( | ||
| asyncio.CancelledError, | ||
| self.loop.run_until_complete, acquire) | ||
| self.assertFalse(sem._waiters) | ||
| self.assertTrue((not sem._waiters) or | ||
| all(waiter.done() for waiter in sem._waiters)) | ||
|
|
||
| def test_acquire_cancel_before_awoken(self): | ||
| sem = asyncio.Semaphore(value=0, loop=self.loop) | ||
|
|
||
| t1 = asyncio.Task(sem.acquire(), loop=self.loop) | ||
| t2 = asyncio.Task(sem.acquire(), loop=self.loop) | ||
| t3 = asyncio.Task(sem.acquire(), loop=self.loop) | ||
| t4 = asyncio.Task(sem.acquire(), loop=self.loop) | ||
|
|
||
| test_utils.run_briefly(self.loop) | ||
|
|
||
| sem.release() | ||
| t1.cancel() | ||
| t2.cancel() | ||
|
|
||
| test_utils.run_briefly(self.loop) | ||
| num_done = sum(t.done() for t in [t3, t4]) | ||
| self.assertEqual(num_done, 1) | ||
|
|
||
| t3.cancel() | ||
| t4.cancel() | ||
| test_utils.run_briefly(self.loop) | ||
|
|
||
| def test_acquire_hang(self): | ||
| sem = asyncio.Semaphore(value=0, loop=self.loop) | ||
|
|
||
| t1 = asyncio.Task(sem.acquire(), loop=self.loop) | ||
| t2 = asyncio.Task(sem.acquire(), loop=self.loop) | ||
|
|
||
| test_utils.run_briefly(self.loop) | ||
|
|
||
| sem.release() | ||
| t1.cancel() | ||
|
|
||
| test_utils.run_briefly(self.loop) | ||
| self.assertTrue(sem.locked()) | ||
|
|
||
| def test_release_not_acquired(self): | ||
| sem = asyncio.BoundedSemaphore(loop=self.loop) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed my mind on this (again). The except clause should just catch CancelledException and the fut.cancel() is unnecesary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, can you add a comment saying something like "See similar code in Queue"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I was testing
asyncio.Queue, there was only one time that an exception other thanCancelledExceptionwas catch: when a pending task waiting for a future is deleted,GeneratorExitis raised.Do we need to add
assert fut.done()here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wow. Then please leave it as is. The GeneratorExit is worth a comment! This pretty much confirms the hunch I had about other exceptions possibly happening here...