diff options
author | Andrew Svetlov <andrew.svetlov@gmail.com> | 2017-11-29 16:23:43 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-29 16:23:43 (GMT) |
commit | cc83920ad267c992bc421987829da04d88ae816b (patch) | |
tree | f0d5468502f7c857b6f8afc412898439a257dfad /Lib/asyncio/coroutines.py | |
parent | 5d39e0429029324cae90bba2f19fb689b007c7d6 (diff) | |
download | cpython-cc83920ad267c992bc421987829da04d88ae816b.zip cpython-cc83920ad267c992bc421987829da04d88ae816b.tar.gz cpython-cc83920ad267c992bc421987829da04d88ae816b.tar.bz2 |
bpo-32166: Drop Python 3.4 code from asyncio (#4612)
* Drop Python 3.4 code from asyncio
* Fix notes
* Add missing imports
* Restore comment
* Resort imports
* Drop Python 3.4-3.5 specific code
* Drop redunant check
* Fix tests
* Restore _COROUTINE_TYPES order
* Remove useless code
Diffstat (limited to 'Lib/asyncio/coroutines.py')
-rw-r--r-- | Lib/asyncio/coroutines.py | 94 |
1 files changed, 14 insertions, 80 deletions
diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py index 3e305f9..b6f81a4 100644 --- a/Lib/asyncio/coroutines.py +++ b/Lib/asyncio/coroutines.py @@ -9,16 +9,14 @@ import sys import traceback import types +from collections.abc import Awaitable, Coroutine + from . import constants from . import events from . import base_futures from .log import logger -# Opcode of "yield from" instruction -_YIELD_FROM = opcode.opmap['YIELD_FROM'] - - def _is_debug_mode(): # If you set _DEBUG to true, @coroutine will wrap the resulting # generator objects in a CoroWrapper instance (defined below). That @@ -39,51 +37,6 @@ def _is_debug_mode(): _DEBUG = _is_debug_mode() -try: - _types_coroutine = types.coroutine - _types_CoroutineType = types.CoroutineType -except AttributeError: - # Python 3.4 - _types_coroutine = None - _types_CoroutineType = None - -try: - _inspect_iscoroutinefunction = inspect.iscoroutinefunction -except AttributeError: - # Python 3.4 - _inspect_iscoroutinefunction = lambda func: False - -try: - from collections.abc import Coroutine as _CoroutineABC, \ - Awaitable as _AwaitableABC -except ImportError: - _CoroutineABC = _AwaitableABC = None - - -# Check for CPython issue #21209 -def has_yield_from_bug(): - class MyGen: - def __init__(self): - self.send_args = None - def __iter__(self): - return self - def __next__(self): - return 42 - def send(self, *what): - self.send_args = what - return None - def yield_from_gen(gen): - yield from gen - value = (1, 2, 3) - gen = MyGen() - coro = yield_from_gen(gen) - next(coro) - coro.send(value) - return gen.send_args != (value,) -_YIELD_FROM_BUG = has_yield_from_bug() -del has_yield_from_bug - - def debug_wrapper(gen): # This function is called from 'sys.set_coroutine_wrapper'. # We only wrap here coroutines defined via 'async def' syntax. @@ -116,21 +69,8 @@ class CoroWrapper: def __next__(self): return self.gen.send(None) - if _YIELD_FROM_BUG: - # For for CPython issue #21209: using "yield from" and a custom - # generator, generator.send(tuple) unpacks the tuple instead of passing - # the tuple unchanged. Check if the caller is a generator using "yield - # from" to decide if the parameter should be unpacked or not. - def send(self, *value): - frame = sys._getframe() - caller = frame.f_back - assert caller.f_lasti >= 0 - if caller.f_code.co_code[caller.f_lasti] != _YIELD_FROM: - value = value[0] - return self.gen.send(value) - else: - def send(self, value): - return self.gen.send(value) + def send(self, value): + return self.gen.send(value) def throw(self, type, value=None, traceback=None): return self.gen.throw(type, value, traceback) @@ -202,7 +142,7 @@ def coroutine(func): If the coroutine is not yielded from before it is destroyed, an error message is logged. """ - if _inspect_iscoroutinefunction(func): + if inspect.iscoroutinefunction(func): # In Python 3.5 that's all we need to do for coroutines # defined with "async def". # Wrapping in CoroWrapper will happen via @@ -218,7 +158,7 @@ def coroutine(func): if (base_futures.isfuture(res) or inspect.isgenerator(res) or isinstance(res, CoroWrapper)): res = yield from res - elif _AwaitableABC is not None: + else: # If 'func' returns an Awaitable (new in 3.5) we # want to run it. try: @@ -226,15 +166,12 @@ def coroutine(func): except AttributeError: pass else: - if isinstance(res, _AwaitableABC): + if isinstance(res, Awaitable): res = yield from await_meth() return res if not _DEBUG: - if _types_coroutine is None: - wrapper = coro - else: - wrapper = _types_coroutine(coro) + wrapper = types.coroutine(coro) else: @functools.wraps(func) def wrapper(*args, **kwds): @@ -259,17 +196,14 @@ _is_coroutine = object() def iscoroutinefunction(func): """Return True if func is a decorated coroutine function.""" - return (getattr(func, '_is_coroutine', None) is _is_coroutine or - _inspect_iscoroutinefunction(func)) + return (inspect.iscoroutinefunction(func) or + getattr(func, '_is_coroutine', None) is _is_coroutine) -_COROUTINE_TYPES = (types.GeneratorType, CoroWrapper) -if _CoroutineABC is not None: - _COROUTINE_TYPES += (_CoroutineABC,) -if _types_CoroutineType is not None: - # Prioritize native coroutine check to speed-up - # asyncio.iscoroutine. - _COROUTINE_TYPES = (_types_CoroutineType,) + _COROUTINE_TYPES +# Prioritize native coroutine check to speed-up +# asyncio.iscoroutine. +_COROUTINE_TYPES = (types.CoroutineType, types.GeneratorType, + Coroutine, CoroWrapper) def iscoroutine(obj): |