Merge pull request #957 from Badiboy/master

Empty list optimization, Py2 arteacts removed
This commit is contained in:
Badiboy
2020-08-25 16:46:28 +03:00
committed by GitHub
7 changed files with 169 additions and 110 deletions

View File

@@ -1,5 +1,4 @@
py==1.4.29 py==1.4.29
pytest==3.0.2 pytest==3.0.2
requests==2.20.0 requests==2.20.0
six==1.9.0
wheel==0.24.0 wheel==0.24.0

View File

@@ -22,7 +22,7 @@ setup(name='pyTelegramBotAPI',
packages=['telebot'], packages=['telebot'],
license='GPL2', license='GPL2',
keywords='telegram bot api tools', keywords='telegram bot api tools',
install_requires=['requests', 'six'], install_requires=['requests'],
extras_require={ extras_require={
'json': 'ujson', 'json': 'ujson',
'redis': 'redis>=3.4.1' 'redis': 'redis>=3.4.1'

View File

@@ -7,8 +7,6 @@ import sys
import threading import threading
import time import time
import six
logger = logging.getLogger('TeleBot') logger = logging.getLogger('TeleBot')
formatter = logging.Formatter( formatter = logging.Formatter(
'%(asctime)s (%(filename)s:%(lineno)d %(threadName)s) %(levelname)s - %(name)s: "%(message)s"' '%(asctime)s (%(filename)s:%(lineno)d %(threadName)s) %(levelname)s - %(name)s: "%(message)s"'
@@ -42,6 +40,15 @@ class Handler:
return getattr(self, item) return getattr(self, item)
class ExceptionHandler:
"""
Class for handling exceptions while Polling
"""
def handle(self, exception):
return False
class TeleBot: class TeleBot:
""" This is TeleBot Class """ This is TeleBot Class
Methods: Methods:
@@ -86,7 +93,7 @@ class TeleBot:
def __init__( def __init__(
self, token, parse_mode=None, threaded=True, skip_pending=False, num_threads=2, self, token, parse_mode=None, threaded=True, skip_pending=False, num_threads=2,
next_step_backend=None, reply_backend=None next_step_backend=None, reply_backend=None, exception_handler=None
): ):
""" """
:param token: bot API token :param token: bot API token
@@ -111,6 +118,8 @@ class TeleBot:
if not self.reply_backend: if not self.reply_backend:
self.reply_backend = MemoryHandlerBackend() self.reply_backend = MemoryHandlerBackend()
self.exception_handler = exception_handler
self.message_handlers = [] self.message_handlers = []
self.edited_message_handlers = [] self.edited_message_handlers = []
self.channel_post_handlers = [] self.channel_post_handlers = []
@@ -123,20 +132,20 @@ class TeleBot:
self.poll_handlers = [] self.poll_handlers = []
self.poll_answer_handlers = [] self.poll_answer_handlers = []
self.typed_middleware_handlers = { if apihelper.ENABLE_MIDDLEWARE:
'message': [], self.typed_middleware_handlers = {
'edited_message': [], 'message': [],
'channel_post': [], 'edited_message': [],
'edited_channel_post': [], 'channel_post': [],
'inline_query': [], 'edited_channel_post': [],
'chosen_inline_result': [], 'inline_query': [],
'callback_query': [], 'chosen_inline_result': [],
'shipping_query': [], 'callback_query': [],
'pre_checkout_query': [], 'shipping_query': [],
'poll': [], 'pre_checkout_query': [],
} 'poll': [],
}
self.default_middleware_handlers = [] self.default_middleware_handlers = []
self.threaded = threaded self.threaded = threaded
if self.threaded: if self.threaded:
@@ -286,17 +295,22 @@ class TeleBot:
self.process_new_updates(updates) self.process_new_updates(updates)
def process_new_updates(self, updates): def process_new_updates(self, updates):
new_messages = [] upd_count = len(updates)
new_edited_messages = [] logger.debug('Received {0} new updates'.format(upd_count))
new_channel_posts = [] if (upd_count == 0):
new_edited_channel_posts = [] return
new_inline_querys = []
new_chosen_inline_results = [] new_messages = None
new_callback_querys = [] new_edited_messages = None
new_shipping_querys = [] new_channel_posts = None
new_pre_checkout_querys = [] new_edited_channel_posts = None
new_polls = [] new_inline_queries = None
new_poll_answers = [] new_chosen_inline_results = None
new_callback_queries = None
new_shipping_queries = None
new_pre_checkout_queries = None
new_polls = None
new_poll_answers = None
for update in updates: for update in updates:
if apihelper.ENABLE_MIDDLEWARE: if apihelper.ENABLE_MIDDLEWARE:
@@ -305,50 +319,60 @@ class TeleBot:
if update.update_id > self.last_update_id: if update.update_id > self.last_update_id:
self.last_update_id = update.update_id self.last_update_id = update.update_id
if update.message: if update.message:
if new_messages is None: new_messages = []
new_messages.append(update.message) new_messages.append(update.message)
if update.edited_message: if update.edited_message:
if new_edited_messages is None: new_edited_messages = []
new_edited_messages.append(update.edited_message) new_edited_messages.append(update.edited_message)
if update.channel_post: if update.channel_post:
if new_channel_posts is None: new_channel_posts = []
new_channel_posts.append(update.channel_post) new_channel_posts.append(update.channel_post)
if update.edited_channel_post: if update.edited_channel_post:
if new_edited_channel_posts is None: new_edited_channel_posts = []
new_edited_channel_posts.append(update.edited_channel_post) new_edited_channel_posts.append(update.edited_channel_post)
if update.inline_query: if update.inline_query:
new_inline_querys.append(update.inline_query) if new_inline_queries is None: new_inline_queries = []
new_inline_queries.append(update.inline_query)
if update.chosen_inline_result: if update.chosen_inline_result:
if new_chosen_inline_results is None: new_chosen_inline_results = []
new_chosen_inline_results.append(update.chosen_inline_result) new_chosen_inline_results.append(update.chosen_inline_result)
if update.callback_query: if update.callback_query:
new_callback_querys.append(update.callback_query) if new_callback_queries is None: new_callback_queries = []
new_callback_queries.append(update.callback_query)
if update.shipping_query: if update.shipping_query:
new_shipping_querys.append(update.shipping_query) if new_shipping_queries is None: new_shipping_queries = []
new_shipping_queries.append(update.shipping_query)
if update.pre_checkout_query: if update.pre_checkout_query:
new_pre_checkout_querys.append(update.pre_checkout_query) if new_pre_checkout_queries is None: new_pre_checkout_queries = []
new_pre_checkout_queries.append(update.pre_checkout_query)
if update.poll: if update.poll:
if new_polls is None: new_polls = []
new_polls.append(update.poll) new_polls.append(update.poll)
if update.poll_answer: if update.poll_answer:
if new_poll_answers is None: new_poll_answers = []
new_poll_answers.append(update.poll_answer) new_poll_answers.append(update.poll_answer)
logger.debug('Received {0} new updates'.format(len(updates))) if new_messages:
if len(new_messages) > 0:
self.process_new_messages(new_messages) self.process_new_messages(new_messages)
if len(new_edited_messages) > 0: if new_edited_messages:
self.process_new_edited_messages(new_edited_messages) self.process_new_edited_messages(new_edited_messages)
if len(new_channel_posts) > 0: if new_channel_posts:
self.process_new_channel_posts(new_channel_posts) self.process_new_channel_posts(new_channel_posts)
if len(new_edited_channel_posts) > 0: if new_edited_channel_posts:
self.process_new_edited_channel_posts(new_edited_channel_posts) self.process_new_edited_channel_posts(new_edited_channel_posts)
if len(new_inline_querys) > 0: if new_inline_queries:
self.process_new_inline_query(new_inline_querys) self.process_new_inline_query(new_inline_queries)
if len(new_chosen_inline_results) > 0: if new_chosen_inline_results:
self.process_new_chosen_inline_query(new_chosen_inline_results) self.process_new_chosen_inline_query(new_chosen_inline_results)
if len(new_callback_querys) > 0: if new_callback_queries:
self.process_new_callback_query(new_callback_querys) self.process_new_callback_query(new_callback_queries)
if len(new_shipping_querys) > 0: if new_shipping_queries:
self.process_new_shipping_query(new_shipping_querys) self.process_new_shipping_query(new_shipping_queries)
if len(new_pre_checkout_querys) > 0: if new_pre_checkout_queries:
self.process_new_pre_checkout_query(new_pre_checkout_querys) self.process_new_pre_checkout_query(new_pre_checkout_queries)
if len(new_polls) > 0: if new_polls:
self.process_new_poll(new_polls) self.process_new_poll(new_polls)
if len(new_poll_answers) > 0: if new_poll_answers:
self.process_new_poll_answer(new_poll_answers) self.process_new_poll_answer(new_poll_answers)
def process_new_messages(self, new_messages): def process_new_messages(self, new_messages):
@@ -398,6 +422,8 @@ class TeleBot:
default_middleware_handler(self, update) default_middleware_handler(self, update)
def __notify_update(self, new_messages): def __notify_update(self, new_messages):
if len(self.update_listener) == 0:
return
for listener in self.update_listener: for listener in self.update_listener:
self._exec_task(listener, new_messages) self._exec_task(listener, new_messages)
@@ -452,20 +478,41 @@ class TeleBot:
error_interval = 0.25 error_interval = 0.25
except apihelper.ApiException as e: except apihelper.ApiException as e:
logger.error(e) if self.exception_handler is not None:
if not none_stop: handled = self.exception_handler.handle(e)
self.__stop_polling.set() else:
logger.info("Exception occurred. Stopping.") handled = False
if not handled:
logger.error(e)
if not none_stop:
self.__stop_polling.set()
logger.info("Exception occurred. Stopping.")
else:
polling_thread.clear_exceptions()
self.worker_pool.clear_exceptions()
logger.info("Waiting for {0} seconds until retry".format(error_interval))
time.sleep(error_interval)
error_interval *= 2
else: else:
polling_thread.clear_exceptions() polling_thread.clear_exceptions()
self.worker_pool.clear_exceptions() self.worker_pool.clear_exceptions()
logger.info("Waiting for {0} seconds until retry".format(error_interval))
time.sleep(error_interval) time.sleep(error_interval)
error_interval *= 2
except KeyboardInterrupt: except KeyboardInterrupt:
logger.info("KeyboardInterrupt received.") logger.info("KeyboardInterrupt received.")
self.__stop_polling.set() self.__stop_polling.set()
break break
except Exception as e:
if self.exception_handler is not None:
handled = self.exception_handler.handle(e)
else:
handled = False
if not handled:
raise e
else:
polling_thread.clear_exceptions()
self.worker_pool.clear_exceptions()
time.sleep(error_interval)
polling_thread.stop() polling_thread.stop()
logger.info('Stopped polling.') logger.info('Stopped polling.')
@@ -480,18 +527,35 @@ class TeleBot:
self.__retrieve_updates(timeout) self.__retrieve_updates(timeout)
error_interval = 0.25 error_interval = 0.25
except apihelper.ApiException as e: except apihelper.ApiException as e:
logger.error(e) if self.exception_handler is not None:
if not none_stop: handled = self.exception_handler.handle(e)
self.__stop_polling.set() else:
logger.info("Exception occurred. Stopping.") handled = False
if not handled:
logger.error(e)
if not none_stop:
self.__stop_polling.set()
logger.info("Exception occurred. Stopping.")
else:
logger.info("Waiting for {0} seconds until retry".format(error_interval))
time.sleep(error_interval)
error_interval *= 2
else: else:
logger.info("Waiting for {0} seconds until retry".format(error_interval))
time.sleep(error_interval) time.sleep(error_interval)
error_interval *= 2
except KeyboardInterrupt: except KeyboardInterrupt:
logger.info("KeyboardInterrupt received.") logger.info("KeyboardInterrupt received.")
self.__stop_polling.set() self.__stop_polling.set()
break break
except Exception as e:
if self.exception_handler is not None:
handled = self.exception_handler.handle(e)
else:
handled = False
if not handled:
raise e
else:
time.sleep(error_interval)
logger.info('Stopped polling.') logger.info('Stopped polling.')
@@ -1063,7 +1127,6 @@ class TeleBot:
""" """
return apihelper.set_chat_administrator_custom_title(self.token, chat_id, user_id, custom_title) return apihelper.set_chat_administrator_custom_title(self.token, chat_id, user_id, custom_title)
def set_chat_permissions(self, chat_id, permissions): def set_chat_permissions(self, chat_id, permissions):
""" """
Use this method to set default chat permissions for all members. Use this method to set default chat permissions for all members.
@@ -1278,7 +1341,7 @@ class TeleBot:
def send_invoice(self, chat_id, title, description, invoice_payload, provider_token, currency, prices, def send_invoice(self, chat_id, title, description, invoice_payload, provider_token, currency, prices,
start_parameter, photo_url=None, photo_size=None, photo_width=None, photo_height=None, start_parameter, photo_url=None, photo_size=None, photo_width=None, photo_height=None,
need_name=None, need_phone_number=None, need_email=None, need_shipping_address=None, need_name=None, need_phone_number=None, need_email=None, need_shipping_address=None,
send_phone_number_to_provider = None, send_email_to_provider = None, is_flexible=None, send_phone_number_to_provider=None, send_email_to_provider=None, is_flexible=None,
disable_notification=None, reply_to_message_id=None, reply_markup=None, provider_data=None, timeout=None): disable_notification=None, reply_to_message_id=None, reply_markup=None, provider_data=None, timeout=None):
""" """
Sends invoice Sends invoice
@@ -1542,8 +1605,9 @@ class TeleBot:
for message in new_messages: for message in new_messages:
if hasattr(message, "reply_to_message") and message.reply_to_message is not None: if hasattr(message, "reply_to_message") and message.reply_to_message is not None:
handlers = self.reply_backend.get_handlers(message.reply_to_message.message_id) handlers = self.reply_backend.get_handlers(message.reply_to_message.message_id)
for handler in handlers: if handlers:
self._exec_task(handler["callback"], message, *handler["args"], **handler["kwargs"]) for handler in handlers:
self._exec_task(handler["callback"], message, *handler["args"], **handler["kwargs"])
def register_next_step_handler(self, message, callback, *args, **kwargs): def register_next_step_handler(self, message, callback, *args, **kwargs):
""" """
@@ -1615,11 +1679,12 @@ class TeleBot:
for i, message in enumerate(new_messages): for i, message in enumerate(new_messages):
need_pop = False need_pop = False
handlers = self.next_step_backend.get_handlers(message.chat.id) handlers = self.next_step_backend.get_handlers(message.chat.id)
for handler in handlers: if handlers:
need_pop = True for handler in handlers:
self._exec_task(handler["callback"], message, *handler["args"], **handler["kwargs"]) need_pop = True
self._exec_task(handler["callback"], message, *handler["args"], **handler["kwargs"])
if need_pop: if need_pop:
new_messages.pop(i) # removing message that detects with next_step_handler new_messages.pop(i) # removing message that was detected with next_step_handler
@staticmethod @staticmethod
def _build_handler_dict(handler, **filters): def _build_handler_dict(handler, **filters):
@@ -1721,9 +1786,7 @@ class TeleBot:
func=func, func=func,
content_types=content_types, content_types=content_types,
**kwargs) **kwargs)
self.add_message_handler(handler_dict) self.add_message_handler(handler_dict)
return handler return handler
return decorator return decorator
@@ -1845,6 +1908,7 @@ class TeleBot:
:param kwargs: :param kwargs:
:return: :return:
""" """
def decorator(handler): def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs) handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_inline_handler(handler_dict) self.add_inline_handler(handler_dict)
@@ -1867,6 +1931,7 @@ class TeleBot:
:param kwargs: :param kwargs:
:return: :return:
""" """
def decorator(handler): def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs) handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_chosen_inline_handler(handler_dict) self.add_chosen_inline_handler(handler_dict)
@@ -1889,6 +1954,7 @@ class TeleBot:
:param kwargs: :param kwargs:
:return: :return:
""" """
def decorator(handler): def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs) handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_callback_query_handler(handler_dict) self.add_callback_query_handler(handler_dict)
@@ -1911,6 +1977,7 @@ class TeleBot:
:param kwargs: :param kwargs:
:return: :return:
""" """
def decorator(handler): def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs) handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_shipping_query_handler(handler_dict) self.add_shipping_query_handler(handler_dict)
@@ -1933,6 +2000,7 @@ class TeleBot:
:param kwargs: :param kwargs:
:return: :return:
""" """
def decorator(handler): def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs) handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_pre_checkout_query_handler(handler_dict) self.add_pre_checkout_query_handler(handler_dict)
@@ -1955,6 +2023,7 @@ class TeleBot:
:param kwargs: :param kwargs:
:return: :return:
""" """
def decorator(handler): def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs) handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_poll_handler(handler_dict) self.add_poll_handler(handler_dict)
@@ -1977,6 +2046,7 @@ class TeleBot:
:param kwargs: :param kwargs:
:return: :return:
""" """
def decorator(handler): def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs) handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_poll_answer_handler(handler_dict) self.add_poll_answer_handler(handler_dict)
@@ -1999,7 +2069,7 @@ class TeleBot:
:param message: :param message:
:return: :return:
""" """
for message_filter, filter_value in six.iteritems(message_handler['filters']): for message_filter, filter_value in message_handler['filters'].items():
if filter_value is None: if filter_value is None:
continue continue
@@ -2033,6 +2103,8 @@ class TeleBot:
:param new_messages: :param new_messages:
:return: :return:
""" """
if len(handlers) == 0:
return
for message in new_messages: for message in new_messages:
for message_handler in handlers: for message_handler in handlers:
if self._test_message_handler(message_handler, message): if self._test_message_handler(message_handler, message):

View File

@@ -1005,6 +1005,7 @@ def send_invoice(
:param reply_to_message_id: If the message is a reply, ID of the original message :param reply_to_message_id: If the message is a reply, ID of the original message
:param reply_markup: A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button :param reply_markup: A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button
:param provider_data: A JSON-serialized data about the invoice, which will be shared with the payment provider. A detailed description of required fields should be provided by the payment provider. :param provider_data: A JSON-serialized data about the invoice, which will be shared with the payment provider. A detailed description of required fields should be provided by the payment provider.
:param timeout:
:return: :return:
""" """
method_url = r'sendInvoice' method_url = r'sendInvoice'
@@ -1318,7 +1319,7 @@ class ApiTelegramException(ApiException):
""" """
def __init__(self, function_name, result, result_json): def __init__(self, function_name, result, result_json):
super(ApiTelegramException, self).__init__( super(ApiTelegramException, self).__init__(
"Error code: {0} Description: {1}" \ "Error code: {0}. Description: {1}" \
.format(result_json['error_code'], result_json['description']), .format(result_json['error_code'], result_json['description']),
function_name, function_name,
result) result)

View File

@@ -32,10 +32,13 @@ class MemoryHandlerBackend(HandlerBackend):
self.handlers[handler_group_id] = [handler] self.handlers[handler_group_id] = [handler]
def clear_handlers(self, handler_group_id): def clear_handlers(self, handler_group_id):
self.handlers.pop(handler_group_id, []) self.handlers.pop(handler_group_id, None)
def get_handlers(self, handler_group_id): def get_handlers(self, handler_group_id):
return self.handlers.pop(handler_group_id, []) return self.handlers.pop(handler_group_id, None)
def load_handlers(self, filename, del_file_after_loading):
raise NotImplementedError()
class FileHandlerBackend(HandlerBackend): class FileHandlerBackend(HandlerBackend):
@@ -50,19 +53,15 @@ class FileHandlerBackend(HandlerBackend):
self.handlers[handler_group_id].append(handler) self.handlers[handler_group_id].append(handler)
else: else:
self.handlers[handler_group_id] = [handler] self.handlers[handler_group_id] = [handler]
self.start_save_timer() self.start_save_timer()
def clear_handlers(self, handler_group_id): def clear_handlers(self, handler_group_id):
self.handlers.pop(handler_group_id, []) self.handlers.pop(handler_group_id, None)
self.start_save_timer() self.start_save_timer()
def get_handlers(self, handler_group_id): def get_handlers(self, handler_group_id):
handlers = self.handlers.pop(handler_group_id, []) handlers = self.handlers.pop(handler_group_id, None)
self.start_save_timer() self.start_save_timer()
return handlers return handlers
def start_save_timer(self): def start_save_timer(self):
@@ -136,10 +135,9 @@ class RedisHandlerBackend(HandlerBackend):
self.redis.delete(self._key(handler_group_id)) self.redis.delete(self._key(handler_group_id))
def get_handlers(self, handler_group_id): def get_handlers(self, handler_group_id):
handlers = [] handlers = None
value = self.redis.get(self._key(handler_group_id)) value = self.redis.get(self._key(handler_group_id))
if value: if value:
handlers = pickle.loads(value) handlers = pickle.loads(value)
self.clear_handlers(handler_group_id) self.clear_handlers(handler_group_id)
return handlers return handlers

View File

@@ -7,8 +7,6 @@ try:
except ImportError: except ImportError:
import json import json
import six
from telebot import util from telebot import util
DISABLE_KEYLEN_ERROR = False DISABLE_KEYLEN_ERROR = False
@@ -81,13 +79,13 @@ class JsonDeserializable(object):
def __str__(self): def __str__(self):
d = {} d = {}
for x, y in six.iteritems(self.__dict__): for x, y in self.__dict__.items():
if hasattr(y, '__dict__'): if hasattr(y, '__dict__'):
d[x] = y.__dict__ d[x] = y.__dict__
else: else:
d[x] = y d[x] = y
return six.text_type(d) return str(d)
class Update(JsonDeserializable): class Update(JsonDeserializable):

View File

@@ -2,21 +2,12 @@
import random import random
import re import re
import string import string
import sys
import threading import threading
import traceback import traceback
import warnings import warnings
import functools import functools
import six import queue as Queue
from six import string_types
# Python3 queue support.
try:
import Queue
except ImportError:
import queue as Queue
import logging import logging
try: try:
@@ -51,7 +42,7 @@ class WorkerThread(threading.Thread):
self.continue_event = threading.Event() self.continue_event = threading.Event()
self.exception_callback = exception_callback self.exception_callback = exception_callback
self.exc_info = None self.exception_info = None
self._running = True self._running = True
self.start() self.start()
@@ -73,11 +64,11 @@ class WorkerThread(threading.Thread):
pass pass
except Exception as e: except Exception as e:
logger.error(type(e).__name__ + " occurred, args=" + str(e.args) + "\n" + traceback.format_exc()) logger.error(type(e).__name__ + " occurred, args=" + str(e.args) + "\n" + traceback.format_exc())
self.exc_info = sys.exc_info() self.exception_info = e
self.exception_event.set() self.exception_event.set()
if self.exception_callback: if self.exception_callback:
self.exception_callback(self, self.exc_info) self.exception_callback(self, self.exception_info)
self.continue_event.wait() self.continue_event.wait()
def put(self, task, *args, **kwargs): def put(self, task, *args, **kwargs):
@@ -85,7 +76,7 @@ class WorkerThread(threading.Thread):
def raise_exceptions(self): def raise_exceptions(self):
if self.exception_event.is_set(): if self.exception_event.is_set():
six.reraise(self.exc_info[0], self.exc_info[1], self.exc_info[2]) raise self.exception_info
def clear_exceptions(self): def clear_exceptions(self):
self.exception_event.clear() self.exception_event.clear()
@@ -103,19 +94,19 @@ class ThreadPool:
self.num_threads = num_threads self.num_threads = num_threads
self.exception_event = threading.Event() self.exception_event = threading.Event()
self.exc_info = None self.exception_info = None
def put(self, func, *args, **kwargs): def put(self, func, *args, **kwargs):
self.tasks.put((func, args, kwargs)) self.tasks.put((func, args, kwargs))
def on_exception(self, worker_thread, exc_info): def on_exception(self, worker_thread, exc_info):
self.exc_info = exc_info self.exception_info = exc_info
self.exception_event.set() self.exception_event.set()
worker_thread.continue_event.set() worker_thread.continue_event.set()
def raise_exceptions(self): def raise_exceptions(self):
if self.exception_event.is_set(): if self.exception_event.is_set():
six.reraise(self.exc_info[0], self.exc_info[1], self.exc_info[2]) raise self.exception_info
def clear_exceptions(self): def clear_exceptions(self):
self.exception_event.clear() self.exception_event.clear()
@@ -140,15 +131,15 @@ class AsyncTask:
def _run(self): def _run(self):
try: try:
self.result = self.target(*self.args, **self.kwargs) self.result = self.target(*self.args, **self.kwargs)
except: except Exception as e:
self.result = sys.exc_info() self.result = e
self.done = True self.done = True
def wait(self): def wait(self):
if not self.done: if not self.done:
self.thread.join() self.thread.join()
if isinstance(self.result, BaseException): if isinstance(self.result, BaseException):
six.reraise(self.result[0], self.result[1], self.result[2]) raise self.result
else: else:
return self.result return self.result
@@ -164,7 +155,7 @@ def async_dec():
def is_string(var): def is_string(var):
return isinstance(var, string_types) return isinstance(var, str)
def is_dict(var): def is_dict(var):
return isinstance(var, dict) return isinstance(var, dict)