Skip to content

Commit c98cff8

Browse files
committed
Introduce, use a 'never' object
This can be used in cases where `await SOMETHING` is required, but the task cannot be put back on the queue like `await sleep(0)` would do. This passes the test and the docs build (locally)
1 parent f22e949 commit c98cff8

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

asyncio/core.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ def __next__(self):
6969
self.exc.__traceback__ = None
7070
raise self.exc
7171

72-
7372
# Pause task execution for the given time (integer in milliseconds, uPy extension)
7473
# Use a SingletonGenerator to do it without allocating on the heap
7574
def sleep_ms(t, sgen=SingletonGenerator()):
@@ -93,6 +92,34 @@ def sleep(t):
9392
return sleep_ms(int(t * 1000))
9493

9594

95+
################################################################################
96+
# "Never schedule" object"
97+
# Don't re-schedule the object that awaits the _never singleton.
98+
# For internal use only. Some constructs, like `await event.wait()`,
99+
# work by NOT re-scheduling the task which calls wait(), but by
100+
# having some other task schedule it later.
101+
class _Never:
102+
def __init__(self):
103+
self.state = None
104+
self.exc = StopIteration()
105+
106+
def __iter__(self):
107+
return self
108+
109+
def __await__(self):
110+
return self
111+
112+
def __next__(self):
113+
if self.state is not None:
114+
self.state = None
115+
return None
116+
else:
117+
self.exc.__traceback__ = None
118+
raise self.exc
119+
120+
_never = _Never()
121+
122+
96123
################################################################################
97124
# Queue and poller for stream IO
98125

asyncio/event.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ async def wait(self):
6262
self.waiting.push_head(core.cur_task)
6363
# Set calling task's data to the event's queue so it can be removed if needed
6464
core.cur_task.data = self.waiting
65-
yield
65+
core._never.state = False
66+
await core._never
6667
return True
6768

6869

asyncio/lock.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ async def acquire(self):
6969
# Set calling task's data to the lock's queue so it can be removed if needed
7070
core.cur_task.data = self.waiting
7171
try:
72-
yield
72+
core._never.state = False
73+
await core._never
7374
except core.CancelledError as er:
7475
if self.state == core.cur_task:
7576
# Cancelled while pending on resume, schedule next waiting Task

0 commit comments

Comments
 (0)