123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- from __future__ import print_function
- import sys
- import threading
- from time import sleep
- try:
- import thread
- except ImportError:
- import _thread as thread
- try: # use code that works the same in Python 2 and 3
- range, _print = xrange, print
- def print(*args, **kwargs):
- flush = kwargs.pop('flush', False)
- _print(*args, **kwargs)
- if flush:
- kwargs.get('file', sys.stdout).flush()
- except NameError:
- pass
- def cdquit(fn_name):
- # print to stderr, unbuffered in Python 2.
- print('{0} took too long'.format(fn_name), file=sys.stderr)
- sys.stderr.flush() # Python 3 stderr is likely buffered.
- thread.interrupt_main() # raises KeyboardInterrupt
- def exit_after(s):
- '''
- use as decorator to exit process if
- function takes longer than s seconds
- '''
- def outer(fn):
- def inner(*args, **kwargs):
- timer = threading.Timer(s, cdquit, args=[fn.__name__])
- timer.start()
- try:
- result = fn(*args, **kwargs)
- finally:
- timer.cancel()
- return result
- return inner
- return outer
- def call_method_with_timeout(method, timeout, *args, **kwargs):
- return exit_after(timeout)(method)(*args, **kwargs)
- @exit_after(1)
- def a():
- print('a')
- @exit_after(2)
- def b():
- print('b')
- sleep(1)
- @exit_after(3)
- def c():
- print('c')
- sleep(2)
- @exit_after(4)
- def d():
- print('d started')
- for i in range(10):
- sleep(1)
- print(i)
- @exit_after(5)
- def countdown(n):
- print('countdown started', flush=True)
- for i in range(n, -1, -1):
- print(i, end=', ', flush=True)
- sleep(1)
- print('countdown finished')
- def main():
- a()
- b()
- c()
- try:
- d()
- except KeyboardInterrupt as error:
- print('d should not have finished, printing error as expected:')
- print(error)
- countdown(3)
- countdown(10)
- print('This should not print!!!')
- if __name__ == '__main__':
- main()
|