[Python-checkins] cpython (3.5): Rename Future._blocking to _asyncio_future_blocking.
guido.van.rossum
python-checkins at python.org
Fri Sep 9 16:01:19 EDT 2016
https://hg.python.org/cpython/rev/ab1e10e3dc35
changeset: 103454:ab1e10e3dc35
branch: 3.5
parent: 103448:8e74e76deda1
user: Guido van Rossum <guido at python.org>
date: Fri Sep 09 12:54:54 2016 -0700
summary:
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.
files:
Lib/asyncio/futures.py | 12 ++++++++++--
Lib/asyncio/tasks.py | 7 ++++---
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -134,7 +134,15 @@
_loop = None
_source_traceback = None
- _blocking = False # proper use of future (yield vs yield from)
+ # This field is used for a dual purpose:
+ # - Its presence is a marker to declare that a class implements
+ # the Future protocol (i.e. is intended to be duck-type compatible).
+ # The value must also be not-None, to enable a subclass to declare
+ # that it is not compatible by setting this to None.
+ # - It is set by __iter__() below so that Task._step() can tell
+ # the difference between `yield from Future()` (correct) vs.
+ # `yield Future()` (incorrect).
+ _asyncio_future_blocking = False
_log_traceback = False # Used for Python 3.4 and later
_tb_logger = None # Used for Python 3.3 only
@@ -357,7 +365,7 @@
def __iter__(self):
if not self.done():
- self._blocking = True
+ self._asyncio_future_blocking = True
yield self # This tells Task to wait for completion.
assert self.done(), "yield from wasn't used with future"
return self.result() # May raise too.
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -249,7 +249,8 @@
self.set_exception(exc)
raise
else:
- if isinstance(result, futures.Future):
+ blocking = getattr(result, '_asyncio_future_blocking', None)
+ if blocking is not None:
# Yielded Future must come from Future.__iter__().
if result._loop is not self._loop:
self._loop.call_soon(
@@ -257,8 +258,8 @@
RuntimeError(
'Task {!r} got Future {!r} attached to a '
'different loop'.format(self, result)))
- elif result._blocking:
- result._blocking = False
+ elif blocking:
+ result._asyncio_future_blocking = False
result.add_done_callback(self._wakeup)
self._fut_waiter = result
if self._must_cancel:
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list