Skip to content

Commit 45ca439

Browse files
committed
PYTHON-4782 Add tests for _ACondition
1 parent 5144326 commit 45ca439

File tree

2 files changed

+526
-1
lines changed

2 files changed

+526
-1
lines changed

pymongo/lock.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919
import threading
2020
import time
2121
import weakref
22-
from typing import Any, Optional
22+
from typing import Any, Callable, Optional, TypeVar
2323

2424
_HAS_REGISTER_AT_FORK = hasattr(os, "register_at_fork")
2525

2626
# References to instances of _create_lock
2727
_forkable_locks: weakref.WeakSet[threading.Lock] = weakref.WeakSet()
2828

29+
_T = TypeVar("_T")
30+
2931

3032
def _create_lock() -> threading.Lock:
3133
"""Represents a lock that is tracked upon instantiation using a WeakSet and
@@ -163,6 +165,20 @@ async def wait(self, timeout: Optional[float] = None) -> bool:
163165
self.notify(1)
164166
raise
165167

168+
async def wait_for(self, predicate: Callable[[], _T]) -> _T:
169+
"""Wait until a predicate becomes true.
170+
171+
The predicate should be a callable whose result will be
172+
interpreted as a boolean value. The method will repeatedly
173+
wait() until it evaluates to true. The final predicate value is
174+
the return value.
175+
"""
176+
result = predicate()
177+
while not result:
178+
await self.wait()
179+
result = predicate()
180+
return result
181+
166182
def notify(self, n: int = 1) -> None:
167183
"""By default, wake up one coroutine waiting on this condition, if any.
168184
If the calling coroutine has not acquired the lock when this method
@@ -204,6 +220,10 @@ def notify_all(self) -> None:
204220
"""
205221
self.notify(len(self._waiters))
206222

223+
def locked(self) -> bool:
224+
"""Only needed for tests in test_locks."""
225+
return self._condition._lock.locked() # type: ignore[attr-defined]
226+
207227
def release(self) -> None:
208228
self._condition.release()
209229

0 commit comments

Comments
 (0)