From 0c2fd87c511af88366e3fa696e13c800bea90a8b Mon Sep 17 00:00:00 2001 From: Brian Merrell Date: Tue, 9 Oct 2018 02:12:08 -0400 Subject: [PATCH 1/6] Allow (and test) CapacityLimiter(math.inf) --- trio/_sync.py | 5 +++-- trio/tests/test_sync.py | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/trio/_sync.py b/trio/_sync.py index edb85ce1bc..930625dd89 100644 --- a/trio/_sync.py +++ b/trio/_sync.py @@ -1,5 +1,6 @@ import operator from collections import deque, OrderedDict +import math import attr import outcome @@ -199,8 +200,8 @@ def total_tokens(self): @total_tokens.setter def total_tokens(self, new_total_tokens): - if not isinstance(new_total_tokens, int): - raise TypeError("total_tokens must be an int") + if not isinstance(new_total_tokens, int) and new_total_tokens != math.inf: + raise TypeError("total_tokens must be an int or math.inf") if new_total_tokens < 1: raise ValueError("total_tokens must be >= 1") self._total_tokens = new_total_tokens diff --git a/trio/tests/test_sync.py b/trio/tests/test_sync.py index 0f39f62008..03d221fff5 100644 --- a/trio/tests/test_sync.py +++ b/trio/tests/test_sync.py @@ -114,6 +114,19 @@ async def test_CapacityLimiter(): c.release_on_behalf_of("value 3") c.release_on_behalf_of("value 1") +async def test_CapacityLimiter_inf(): + from math import inf + c = CapacityLimiter(inf) + repr(c) # smoke test + assert c.total_tokens == inf + assert c.borrowed_tokens == 0 + assert c.available_tokens == inf + with pytest.raises(RuntimeError): + c.release() + assert c.borrowed_tokens == 0 + c.acquire_nowait() + assert c.borrowed_tokens == 1 + assert c.available_tokens == inf async def test_CapacityLimiter_change_total_tokens(): c = CapacityLimiter(2) From 3ebd73d74793e32e87d23190066cb891ee02112e Mon Sep 17 00:00:00 2001 From: Brian Merrell Date: Tue, 9 Oct 2018 02:21:29 -0400 Subject: [PATCH 2/6] Repace StubListener with CapacityLimiter(math.inf) --- trio/_wait_for_object.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/trio/_wait_for_object.py b/trio/_wait_for_object.py index 3e6650bb82..a719d6b807 100644 --- a/trio/_wait_for_object.py +++ b/trio/_wait_for_object.py @@ -1,19 +1,13 @@ +import math from . import _timeouts from . import _core from ._threads import run_sync_in_worker_thread from ._core._windows_cffi import ffi, kernel32, ErrorCodes, raise_winerror, _handle +from ._sync import CapacityLimiter __all__ = ["WaitForSingleObject"] -class StubLimiter: - def release_on_behalf_of(self, x): - pass - - async def acquire_on_behalf_of(self, x): - pass - - async def WaitForSingleObject(obj): """Async and cancellable variant of WaitForSingleObject. Windows only. @@ -45,7 +39,7 @@ async def WaitForSingleObject(obj): handle, cancel_handle, cancellable=True, - limiter=StubLimiter(), + limiter=CapacityLimiter(math.inf), ) finally: # Clean up our cancel handle. In case we get here because this task was From 2b3d96fce9eea17f3a5a004d48db70e7ee2f3711 Mon Sep 17 00:00:00 2001 From: Brian Merrell Date: Wed, 24 Oct 2018 00:13:59 -0400 Subject: [PATCH 3/6] Add blank lines to appease flake8 --- trio/tests/test_sync.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/trio/tests/test_sync.py b/trio/tests/test_sync.py index 03d221fff5..272e97fc4b 100644 --- a/trio/tests/test_sync.py +++ b/trio/tests/test_sync.py @@ -114,6 +114,7 @@ async def test_CapacityLimiter(): c.release_on_behalf_of("value 3") c.release_on_behalf_of("value 1") + async def test_CapacityLimiter_inf(): from math import inf c = CapacityLimiter(inf) @@ -128,6 +129,7 @@ async def test_CapacityLimiter_inf(): assert c.borrowed_tokens == 1 assert c.available_tokens == inf + async def test_CapacityLimiter_change_total_tokens(): c = CapacityLimiter(2) From 12612b0250ad69f0973c9fbbe4dc8451afcc9d04 Mon Sep 17 00:00:00 2001 From: Brian Merrell Date: Wed, 24 Oct 2018 00:25:12 -0400 Subject: [PATCH 4/6] yapf formatting fixes --- trio/_sync.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/trio/_sync.py b/trio/_sync.py index 930625dd89..ab475b9471 100644 --- a/trio/_sync.py +++ b/trio/_sync.py @@ -200,7 +200,9 @@ def total_tokens(self): @total_tokens.setter def total_tokens(self, new_total_tokens): - if not isinstance(new_total_tokens, int) and new_total_tokens != math.inf: + if not isinstance( + new_total_tokens, int + ) and new_total_tokens != math.inf: raise TypeError("total_tokens must be an int or math.inf") if new_total_tokens < 1: raise ValueError("total_tokens must be >= 1") From 337b718587858af04bc4bfa37bf076fa8b7a010d Mon Sep 17 00:00:00 2001 From: Brian Merrell Date: Wed, 24 Oct 2018 00:38:30 -0400 Subject: [PATCH 5/6] Add newsfragment --- newsfragments/618.feature.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/618.feature.rst diff --git a/newsfragments/618.feature.rst b/newsfragments/618.feature.rst new file mode 100644 index 0000000000..40d8865c9c --- /dev/null +++ b/newsfragments/618.feature.rst @@ -0,0 +1 @@ +Support unbounded CapacityLimiter when initializing with math.inf From b989e8748be3c147fbb77437356e435391e2475a Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Sun, 28 Oct 2018 16:48:03 -0700 Subject: [PATCH 6/6] Add sphinx markup to the newsfragment --- newsfragments/618.feature.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newsfragments/618.feature.rst b/newsfragments/618.feature.rst index 40d8865c9c..06b0096717 100644 --- a/newsfragments/618.feature.rst +++ b/newsfragments/618.feature.rst @@ -1 +1 @@ -Support unbounded CapacityLimiter when initializing with math.inf +You can now create an unbounded :class:`CapacityLimiter` by initializing with :obj:`math.inf`