Commit dfbd27f0 authored by Yury Selivanov's avatar Yury Selivanov

asyncio: Merge changes from issue #24400.

parent 6bc217dd
...@@ -34,30 +34,20 @@ _DEBUG = (not sys.flags.ignore_environment ...@@ -34,30 +34,20 @@ _DEBUG = (not sys.flags.ignore_environment
try: try:
types.coroutine _types_coroutine = types.coroutine
except AttributeError: except AttributeError:
native_coroutine_support = False _types_coroutine = None
else:
native_coroutine_support = True
try: try:
_iscoroutinefunction = inspect.iscoroutinefunction _inspect_iscoroutinefunction = inspect.iscoroutinefunction
except AttributeError: except AttributeError:
_iscoroutinefunction = lambda func: False _inspect_iscoroutinefunction = lambda func: False
try: try:
inspect.CO_COROUTINE from collections.abc import Coroutine as _CoroutineABC, \
except AttributeError: Awaitable as _AwaitableABC
_is_native_coro_code = lambda code: False
else:
_is_native_coro_code = lambda code: (code.co_flags &
inspect.CO_COROUTINE)
try:
from collections.abc import Coroutine as CoroutineABC, \
Awaitable as AwaitableABC
except ImportError: except ImportError:
CoroutineABC = AwaitableABC = None _CoroutineABC = _AwaitableABC = None
# Check for CPython issue #21209 # Check for CPython issue #21209
...@@ -89,10 +79,7 @@ def debug_wrapper(gen): ...@@ -89,10 +79,7 @@ def debug_wrapper(gen):
# We only wrap here coroutines defined via 'async def' syntax. # We only wrap here coroutines defined via 'async def' syntax.
# Generator-based coroutines are wrapped in @coroutine # Generator-based coroutines are wrapped in @coroutine
# decorator. # decorator.
if _is_native_coro_code(gen.gi_code):
return CoroWrapper(gen, None) return CoroWrapper(gen, None)
else:
return gen
class CoroWrapper: class CoroWrapper:
...@@ -177,8 +164,7 @@ def coroutine(func): ...@@ -177,8 +164,7 @@ def coroutine(func):
If the coroutine is not yielded from before it is destroyed, If the coroutine is not yielded from before it is destroyed,
an error message is logged. an error message is logged.
""" """
is_coroutine = _iscoroutinefunction(func) if _inspect_iscoroutinefunction(func):
if is_coroutine and _is_native_coro_code(func.__code__):
# In Python 3.5 that's all we need to do for coroutines # In Python 3.5 that's all we need to do for coroutines
# defiend with "async def". # defiend with "async def".
# Wrapping in CoroWrapper will happen via # Wrapping in CoroWrapper will happen via
...@@ -193,7 +179,7 @@ def coroutine(func): ...@@ -193,7 +179,7 @@ def coroutine(func):
res = func(*args, **kw) res = func(*args, **kw)
if isinstance(res, futures.Future) or inspect.isgenerator(res): if isinstance(res, futures.Future) or inspect.isgenerator(res):
res = yield from res res = yield from res
elif AwaitableABC is not None: elif _AwaitableABC is not None:
# If 'func' returns an Awaitable (new in 3.5) we # If 'func' returns an Awaitable (new in 3.5) we
# want to run it. # want to run it.
try: try:
...@@ -201,15 +187,15 @@ def coroutine(func): ...@@ -201,15 +187,15 @@ def coroutine(func):
except AttributeError: except AttributeError:
pass pass
else: else:
if isinstance(res, AwaitableABC): if isinstance(res, _AwaitableABC):
res = yield from await_meth() res = yield from await_meth()
return res return res
if not _DEBUG: if not _DEBUG:
if native_coroutine_support: if _types_coroutine is None:
wrapper = types.coroutine(coro)
else:
wrapper = coro wrapper = coro
else:
wrapper = _types_coroutine(coro)
else: else:
@functools.wraps(func) @functools.wraps(func)
def wrapper(*args, **kwds): def wrapper(*args, **kwds):
...@@ -231,12 +217,12 @@ def coroutine(func): ...@@ -231,12 +217,12 @@ def coroutine(func):
def iscoroutinefunction(func): def iscoroutinefunction(func):
"""Return True if func is a decorated coroutine function.""" """Return True if func is a decorated coroutine function."""
return (getattr(func, '_is_coroutine', False) or return (getattr(func, '_is_coroutine', False) or
_iscoroutinefunction(func)) _inspect_iscoroutinefunction(func))
_COROUTINE_TYPES = (types.GeneratorType, CoroWrapper) _COROUTINE_TYPES = (types.GeneratorType, CoroWrapper)
if CoroutineABC is not None: if _CoroutineABC is not None:
_COROUTINE_TYPES += (CoroutineABC,) _COROUTINE_TYPES += (_CoroutineABC,)
def iscoroutine(obj): def iscoroutine(obj):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment