def sync(*func, timeout=None):
"""
coroutine decorator, convert a coroutine into a syncronous function::
@sync(timeout=2)
async def main(sleep_for):
await uvio.sleep(sleep_for)
return 'main returned ok!'
print(main(1))
"""
if not func:
return partial(sync, timeout=timeout)
func = func[0]
@wraps(func)
def inner(*args, **kwargs):
loop = Loop.create(func.__name__)
coro = func(*args, **kwargs)
if not iscoroutine(coro):
raise Exception("{} is not a coroutine (returned from {})".format(coro, func))
loop.next_tick(coro)
if timeout:
def stop_loop():
loop.stop()
raise Exception("timeout")
timer = loop.set_timeout(stop_loop, timeout)
# Don't wait for the timout to exit the loop
timer.unref()
loop.run()
loop.close()
if timeout:
timer.close()
if coro.cr_await is not None:
coro.throw(Exception('coroutine {} should not be running at the end of the loop'.format(coro)))
# This should not happend
assert not loop._awaiting, loop._awaiting
assert not loop.ready, loop.ready
return inner
python类iscoroutine()的实例源码
def invoke_by_args():
import argparse
import asyncio
import coloredlogs
import inspect
import pprint
coloredlogs.install(fmt='[%(levelname).1s %(asctime)s %(module)s:%(lineno)d] %(message)s',
datefmt='%y%m%d %H:%M:%S')
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='')
for name, method in _methods.items():
subparser = subparsers.add_parser(name)
argcount = method.__code__.co_argcount
num_defaults = len(method.__defaults__) if method.__defaults__ else 0
argoffset = argcount - num_defaults
for index, argname in enumerate(method.__code__.co_varnames[:argcount]):
if index < argoffset:
subparser.add_argument(argname, type=method.__annotations__[argname])
elif argname in method.__annotations__:
subparser.add_argument(argname,
type=method.__annotations__[argname],
nargs='?',
default=method.__defaults__[index - argoffset])
args = parser.parse_args(options.leftovers)
name = getattr(args, '')
delattr(args, '')
if not name:
parser.print_help()
else:
loop = asyncio.get_event_loop()
loop.run_until_complete(db.init())
try:
result = _methods[name](**vars(args))
if inspect.iscoroutine(result):
result = loop.run_until_complete(result)
if options.pretty:
print_func = pprint.pprint
else:
print_func = lambda x: print(x) if x is not None else None
if hasattr(result, '__aiter__'):
async def aloop():
async for entry in result:
print_func(entry)
loop.run_until_complete(aloop())
else:
print_func(result)
except KeyboardInterrupt:
pass
finally:
loop.set_exception_handler(lambda loop, context: None)
def _format_coroutine(coro):
assert iscoroutine(coro)
coro_name = None
if isinstance(coro, CoroWrapper):
func = coro.func
coro_name = coro.__qualname__
if coro_name is not None:
coro_name = '{}()'.format(coro_name)
else:
func = coro
if coro_name is None:
coro_name = events._format_callback(func, ())
try:
coro_code = coro.gi_code
except AttributeError:
coro_code = coro.cr_code
try:
coro_frame = coro.gi_frame
except AttributeError:
coro_frame = coro.cr_frame
filename = coro_code.co_filename
lineno = 0
if (isinstance(coro, CoroWrapper) and
not inspect.isgeneratorfunction(coro.func) and
coro.func is not None):
source = events._get_function_source(coro.func)
if source is not None:
filename, lineno = source
if coro_frame is None:
coro_repr = ('%s done, defined at %s:%s'
% (coro_name, filename, lineno))
else:
coro_repr = ('%s running, defined at %s:%s'
% (coro_name, filename, lineno))
elif coro_frame is not None:
lineno = coro_frame.f_lineno
coro_repr = ('%s running at %s:%s'
% (coro_name, filename, lineno))
else:
lineno = coro_code.co_firstlineno
coro_repr = ('%s done, defined at %s:%s'
% (coro_name, filename, lineno))
return coro_repr
def invoke_by_args():
import argparse
import asyncio
import inspect
import pprint
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='')
for name, method in _methods.items():
subparser = subparsers.add_parser(name)
argcount = method.__code__.co_argcount
num_defaults = len(method.__defaults__) if method.__defaults__ else 0
argoffset = argcount - num_defaults
for index, argname in enumerate(method.__code__.co_varnames[:argcount]):
if index < argoffset:
subparser.add_argument(argname, type=method.__annotations__[argname])
elif argname in method.__annotations__:
subparser.add_argument(argname,
type=method.__annotations__[argname],
nargs='?',
default=method.__defaults__[index - argoffset])
args = parser.parse_args(options.leftovers)
name = getattr(args, '')
delattr(args, '')
if not name:
parser.print_help()
else:
loop = asyncio.get_event_loop()
try:
result = _methods[name](**vars(args))
if inspect.iscoroutine(result):
result = loop.run_until_complete(result)
pass
if options.options.pretty:
print_func = pprint.pprint
else:
print_func = lambda x: print(x) if x is not None else None
if hasattr(result, '__aiter__'):
async def aloop():
async for entry in result:
print_func(entry)
loop.run_until_complete(aloop())
else:
print_func(result)
except KeyboardInterrupt:
pass
loop.set_exception_handler(lambda t_loop, context: None)