Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Commit 8805f2a

Browse files
committed
Rename Future._blocking to _asyncio_future_blocking.
This is now an official "protected" API that can be used to write classes that are duck-type-compatible with Future without subclassing it. (For that purpose I also changed isinstance(result, Future) to check for this attribute instead.) Hopefully Amber Brown can use this to make Twisted.Deferred compatible with asyncio.Future. Tests and docs are TBD.
1 parent 532c096 commit 8805f2a

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

asyncio/futures.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,15 @@ class Future:
134134
_loop = None
135135
_source_traceback = None
136136

137-
_blocking = False # proper use of future (yield vs yield from)
137+
# This field is used for a dual purpose:
138+
# - Its presence is a marker to declare that a class implements
139+
# the Future protocol (i.e. is intended to be duck-type compatible).
140+
# The value must also be not-None, to enable a subclass to declare
141+
# that it is not compatible by setting this to None.
142+
# - It is set by __iter__() below so that Task._step() can tell
143+
# the difference between `yield from Future()` (correct) vs.
144+
# `yield Future()` (incorrect).
145+
_asyncio_future_blocking = False
138146

139147
_log_traceback = False # Used for Python 3.4 and later
140148
_tb_logger = None # Used for Python 3.3 only
@@ -357,7 +365,7 @@ def set_exception(self, exception):
357365

358366
def __iter__(self):
359367
if not self.done():
360-
self._blocking = True
368+
self._asyncio_future_blocking = True
361369
yield self # This tells Task to wait for completion.
362370
assert self.done(), "yield from wasn't used with future"
363371
return self.result() # May raise too.

asyncio/tasks.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,16 +249,17 @@ def _step(self, exc=None):
249249
self.set_exception(exc)
250250
raise
251251
else:
252-
if isinstance(result, futures.Future):
252+
blocking = getattr(result, '_asyncio_future_blocking', None)
253+
if blocking is not None:
253254
# Yielded Future must come from Future.__iter__().
254255
if result._loop is not self._loop:
255256
self._loop.call_soon(
256257
self._step,
257258
RuntimeError(
258259
'Task {!r} got Future {!r} attached to a '
259260
'different loop'.format(self, result)))
260-
elif result._blocking:
261-
result._blocking = False
261+
elif blocking:
262+
result._asyncio_future_blocking = False
262263
result.add_done_callback(self._wakeup)
263264
self._fut_waiter = result
264265
if self._must_cancel:

0 commit comments

Comments
 (0)