summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio/coroutines.py
diff options
context:
space:
mode:
authorAndrew Svetlov <andrew.svetlov@gmail.com>2017-11-29 16:23:43 (GMT)
committerGitHub <noreply@github.com>2017-11-29 16:23:43 (GMT)
commitcc83920ad267c992bc421987829da04d88ae816b (patch)
treef0d5468502f7c857b6f8afc412898439a257dfad /Lib/asyncio/coroutines.py
parent5d39e0429029324cae90bba2f19fb689b007c7d6 (diff)
downloadcpython-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.py94
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):