Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/637.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The ``clear`` method on `trio.Event` has been deprecated.
12 changes: 6 additions & 6 deletions trio/_signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from collections import OrderedDict

import trio
from ._sync import Event
from ._util import (
signal_raise, aiter_compat, is_main_thread, ConflictDetector
)
Expand Down Expand Up @@ -62,7 +61,7 @@ class SignalReceiver:
def __init__(self):
# {signal num: None}
self._pending = OrderedDict()
self._have_pending = Event()
self._lot = trio.hazmat.ParkingLot()
self._conflict_detector = ConflictDetector(
"only one task can iterate on a signal receiver at a time"
)
Expand All @@ -73,7 +72,7 @@ def _add(self, signum):
signal_raise(signum)
else:
self._pending[signum] = None
self._have_pending.set()
self._lot.unpark()

def _redeliver_remaining(self):
# First make sure that any signals still in the delivery pipeline will
Expand Down Expand Up @@ -108,10 +107,11 @@ async def __anext__(self):
# calls to __anext__, but doing it without race conditions is quite
# tricky, and there doesn't seem to be any point in trying.
with self._conflict_detector:
await self._have_pending.wait()
signum, _ = self._pending.popitem(last=False)
if not self._pending:
self._have_pending.clear()
await self._lot.park()
else:
await trio.hazmat.checkpoint()
signum, _ = self._pending.popitem(last=False)
return signum


Expand Down
16 changes: 13 additions & 3 deletions trio/_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from ._util import aiter_compat
from ._core import enable_ki_protection, ParkingLot
from ._deprecate import deprecated

__all__ = [
"Event",
Expand Down Expand Up @@ -36,6 +37,13 @@ class Event:
primitive that doesn't have this protection, consider :class:`Condition`
or :class:`trio.hazmat.ParkingLot`.

.. note:: Unlike `threading.Event`, `trio.Event` has no
`~threading.Event.clear` method. In Trio, once an `Event` has happened,
it cannot un-happen. If you need to represent a series of events,
consider creating a new `Event` object for each one (they're cheap!),
or other synchronization methods like :ref:`channels <channels>` or
`trio.hazmat.ParkingLot`.

"""

_lot = attr.ib(default=attr.Factory(ParkingLot), init=False)
Expand All @@ -55,10 +63,12 @@ def set(self):
self._flag = True
self._lot.unpark_all()

@deprecated(
"0.12.0",
issue=637,
instead="multiple Event objects or other synchronization primitives"
)
def clear(self):
"""Set the internal flag value to False.

"""
self._flag = False

async def wait(self):
Expand Down
13 changes: 11 additions & 2 deletions trio/tests/test_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ async def test_Event():
with assert_checkpoints():
await e.wait()

e.clear()
assert not e.is_set()
e = Event()

record = []

Expand All @@ -41,6 +40,16 @@ async def child():
assert record == ["sleeping", "sleeping", "woken", "woken"]


# When we remove clear() then this test can be removed too
def test_Event_clear(recwarn):
e = Event()
assert not e.is_set()
e.set()
assert e.is_set()
e.clear()
assert not e.is_set()


async def test_CapacityLimiter():
with pytest.raises(TypeError):
CapacityLimiter(1.0)
Expand Down