Skip to content

Commit 9e4e38e

Browse files
committed
Issue python#26801: Added C implementation of asyncio.Future.
Original patch by Yury Selivanov.
1 parent 518599b commit 9e4e38e

File tree

7 files changed

+1101
-37
lines changed

7 files changed

+1101
-37
lines changed

Lib/asyncio/futures.py

Lines changed: 57 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,46 @@ def isfuture(obj):
120120
return getattr(obj, '_asyncio_future_blocking', None) is not None
121121

122122

123+
def _format_callbacks(cb):
124+
"""helper function for Future.__repr__"""
125+
size = len(cb)
126+
if not size:
127+
cb = ''
128+
129+
def format_cb(callback):
130+
return events._format_callback_source(callback, ())
131+
132+
if size == 1:
133+
cb = format_cb(cb[0])
134+
elif size == 2:
135+
cb = '{}, {}'.format(format_cb(cb[0]), format_cb(cb[1]))
136+
elif size > 2:
137+
cb = '{}, <{} more>, {}'.format(format_cb(cb[0]),
138+
size-2,
139+
format_cb(cb[-1]))
140+
return 'cb=[%s]' % cb
141+
142+
143+
def _future_repr_info(future):
144+
# (Future) -> str
145+
"""helper function for Future.__repr__"""
146+
info = [future._state.lower()]
147+
if future._state == _FINISHED:
148+
if future._exception is not None:
149+
info.append('exception={!r}'.format(future._exception))
150+
else:
151+
# use reprlib to limit the length of the output, especially
152+
# for very long strings
153+
result = reprlib.repr(future._result)
154+
info.append('result={}'.format(result))
155+
if future._callbacks:
156+
info.append(_format_callbacks(future._callbacks))
157+
if future._source_traceback:
158+
frame = future._source_traceback[-1]
159+
info.append('created at %s:%s' % (frame[0], frame[1]))
160+
return info
161+
162+
123163
class Future:
124164
"""This class is *almost* compatible with concurrent.futures.Future.
125165
@@ -172,45 +212,10 @@ def __init__(self, *, loop=None):
172212
if self._loop.get_debug():
173213
self._source_traceback = traceback.extract_stack(sys._getframe(1))
174214

175-
def __format_callbacks(self):
176-
cb = self._callbacks
177-
size = len(cb)
178-
if not size:
179-
cb = ''
180-
181-
def format_cb(callback):
182-
return events._format_callback_source(callback, ())
183-
184-
if size == 1:
185-
cb = format_cb(cb[0])
186-
elif size == 2:
187-
cb = '{}, {}'.format(format_cb(cb[0]), format_cb(cb[1]))
188-
elif size > 2:
189-
cb = '{}, <{} more>, {}'.format(format_cb(cb[0]),
190-
size-2,
191-
format_cb(cb[-1]))
192-
return 'cb=[%s]' % cb
193-
194-
def _repr_info(self):
195-
info = [self._state.lower()]
196-
if self._state == _FINISHED:
197-
if self._exception is not None:
198-
info.append('exception={!r}'.format(self._exception))
199-
else:
200-
# use reprlib to limit the length of the output, especially
201-
# for very long strings
202-
result = reprlib.repr(self._result)
203-
info.append('result={}'.format(result))
204-
if self._callbacks:
205-
info.append(self.__format_callbacks())
206-
if self._source_traceback:
207-
frame = self._source_traceback[-1]
208-
info.append('created at %s:%s' % (frame[0], frame[1]))
209-
return info
215+
_repr_info = _future_repr_info
210216

211217
def __repr__(self):
212-
info = self._repr_info()
213-
return '<%s %s>' % (self.__class__.__name__, ' '.join(info))
218+
return '<%s %s>' % (self.__class__.__name__, ' '.join(self._repr_info()))
214219

215220
# On Python 3.3 and older, objects with a destructor part of a reference
216221
# cycle are never destroyed. It's not more the case on Python 3.4 thanks
@@ -426,6 +431,21 @@ def _copy_future_state(source, dest):
426431
dest.set_result(result)
427432

428433

434+
try:
435+
import _futures
436+
except ImportError:
437+
pass
438+
else:
439+
_futures._init_module(
440+
traceback.extract_stack,
441+
events.get_event_loop,
442+
_future_repr_info,
443+
InvalidStateError,
444+
CancelledError)
445+
446+
Future = _futures.Future
447+
448+
429449
def _chain_future(source, destination):
430450
"""Chain two futures so that when one completes, so does the other.
431451

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.6.0 beta 2
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #26801: Added C implementation of asyncio.Future.
14+
Original patch by Yury Selivanov.
15+
1316
- Issue #28379: Added sanity checks and tests for PyUnicode_CopyCharacters().
1417
Patch by Xiang Zhang.
1518

Modules/Setup.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ _symtable symtablemodule.c
181181
#_datetime _datetimemodule.c # datetime accelerator
182182
#_bisect _bisectmodule.c # Bisection algorithms
183183
#_heapq _heapqmodule.c # Heap queue algorithm
184+
#_futures _futuresmodule.c # Fast asyncio Future
184185

185186
#unicodedata unicodedata.c # static Unicode character database
186187

0 commit comments

Comments
 (0)