bpo-32436: Implement PEP 567 (#5027)

This commit is contained in:
Yury Selivanov 2018-01-22 19:11:18 -05:00 committed by GitHub
parent 9089a26591
commit f23746a934
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 6269 additions and 120 deletions

View file

@ -6,6 +6,7 @@ __all__ = (
)
import concurrent.futures
import contextvars
import logging
import sys
@ -144,8 +145,8 @@ class Future:
return
self._callbacks[:] = []
for callback in callbacks:
self._loop.call_soon(callback, self)
for callback, ctx in callbacks:
self._loop.call_soon(callback, self, context=ctx)
def cancelled(self):
"""Return True if the future was cancelled."""
@ -192,7 +193,7 @@ class Future:
self.__log_traceback = False
return self._exception
def add_done_callback(self, fn):
def add_done_callback(self, fn, *, context=None):
"""Add a callback to be run when the future becomes done.
The callback is called with a single argument - the future object. If
@ -200,9 +201,11 @@ class Future:
scheduled with call_soon.
"""
if self._state != _PENDING:
self._loop.call_soon(fn, self)
self._loop.call_soon(fn, self, context=context)
else:
self._callbacks.append(fn)
if context is None:
context = contextvars.copy_context()
self._callbacks.append((fn, context))
# New method not in PEP 3148.
@ -211,7 +214,9 @@ class Future:
Returns the number of callbacks removed.
"""
filtered_callbacks = [f for f in self._callbacks if f != fn]
filtered_callbacks = [(f, ctx)
for (f, ctx) in self._callbacks
if f != fn]
removed_count = len(self._callbacks) - len(filtered_callbacks)
if removed_count:
self._callbacks[:] = filtered_callbacks