diff -r 1d71ce4531ac Lib/asyncio/futures.py --- a/Lib/asyncio/futures.py Sat Sep 10 16:19:45 2016 +0200 +++ b/Lib/asyncio/futures.py Sat Sep 10 23:59:32 2016 +0900 @@ -120,29 +120,7 @@ return getattr(obj, '_asyncio_future_blocking', None) is not None -class Future: - """This class is *almost* compatible with concurrent.futures.Future. - - Differences: - - - result() and exception() do not take a timeout argument and - raise an exception when the future isn't done yet. - - - Callbacks registered with add_done_callback() are always called - via the event loop's call_soon_threadsafe(). - - - This class is not compatible with the wait() and as_completed() - methods in the concurrent.futures package. - - (In Python 3.4 or later we may be able to unify the implementations.) - """ - - # Class variables serving as defaults for instance variables. - _state = _PENDING - _result = None - _exception = None - _loop = None - _source_traceback = None +class _BaseFuture: # This field is used for a dual purpose: # - Its presence is a marker to declare that a class implements @@ -154,24 +132,6 @@ # `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 - - def __init__(self, *, loop=None): - """Initialize the future. - - The optional event_loop argument allows explicitly setting the event - loop object used by the future. If it's not provided, the future uses - the default event loop. - """ - if loop is None: - self._loop = events.get_event_loop() - else: - self._loop = loop - self._callbacks = [] - if self._loop.get_debug(): - self._source_traceback = traceback.extract_stack(sys._getframe(1)) - def __format_callbacks(self): cb = self._callbacks size = len(cb) @@ -232,6 +192,52 @@ context['source_traceback'] = self._source_traceback self._loop.call_exception_handler(context) + +class Future(_BaseFuture): + """This class is *almost* compatible with concurrent.futures.Future. + + Differences: + + - result() and exception() do not take a timeout argument and + raise an exception when the future isn't done yet. + + - Callbacks registered with add_done_callback() are always called + via the event loop's call_soon_threadsafe(). + + - This class is not compatible with the wait() and as_completed() + methods in the concurrent.futures package. + + (In Python 3.4 or later we may be able to unify the implementations.) + """ + + # Class variables serving as defaults for instance variables. + _state = _PENDING + _result = None + _exception = None + _loop = None + _source_traceback = None + + _blocking = False # proper use of future (yield vs yield from) + + _log_traceback = False # Used for Python 3.4 and later + _tb_logger = None # Used for Python 3.3 only + + def __init__(self, *, loop=None): + """Initialize the future. + + The optional event_loop argument allows explicitly setting the event + loop object used by the future. If it's not provided, the future uses + the default event loop. + """ + if loop is None: + self._loop = events.get_event_loop() + else: + self._loop = loop + self._callbacks = [] + if self._loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + def cancel(self): """Cancel the future and schedule callbacks. @@ -426,6 +432,21 @@ dest.set_result(result) +try: + import _futures +except ImportError: + pass +else: + class Future(_BaseFuture, _futures.Future): + pass + + _futures._init_module( + traceback.extract_stack, + events.get_event_loop, + InvalidStateError, + CancelledError) + + def _chain_future(source, destination): """Chain two futures so that when one completes, so does the other. diff -r 1d71ce4531ac Modules/Setup.dist --- a/Modules/Setup.dist Sat Sep 10 16:19:45 2016 +0200 +++ b/Modules/Setup.dist Sat Sep 10 23:59:32 2016 +0900 @@ -181,6 +181,7 @@ #_datetime _datetimemodule.c # datetime accelerator #_bisect _bisectmodule.c # Bisection algorithms #_heapq _heapqmodule.c # Heap queue algorithm +#_futures _futuresmodule.c # Fast asyncio Future #unicodedata unicodedata.c # static Unicode character database diff -r 1d71ce4531ac PCbuild/pythoncore.vcxproj --- a/PCbuild/pythoncore.vcxproj Sat Sep 10 16:19:45 2016 +0200 +++ b/PCbuild/pythoncore.vcxproj Sat Sep 10 23:59:32 2016 +0900 @@ -221,6 +221,7 @@ + diff -r 1d71ce4531ac PCbuild/pythoncore.vcxproj.filters --- a/PCbuild/pythoncore.vcxproj.filters Sat Sep 10 16:19:45 2016 +0200 +++ b/PCbuild/pythoncore.vcxproj.filters Sat Sep 10 23:59:32 2016 +0900 @@ -470,6 +470,9 @@ Modules + + Modules + Modules diff -r 1d71ce4531ac setup.py --- a/setup.py Sat Sep 10 16:19:45 2016 +0200 +++ b/setup.py Sat Sep 10 23:59:32 2016 +0900 @@ -655,6 +655,8 @@ exts.append( Extension('unicodedata', ['unicodedata.c']) ) # _opcode module exts.append( Extension('_opcode', ['_opcode.c']) ) + # Fast asyncio Future implementation + exts.append( Extension("_futures", ["_futuresmodule.c"]) ) # Modules with some UNIX dependencies -- on by default: # (If you have a really backward UNIX, select and socket may not be