cleanup: Fix whitespace around parameter equals.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
This commit is contained in:
Anders Kaseorg 2020-04-18 17:16:37 -07:00 committed by Tim Abbott
parent 562fe610b7
commit 6f40bcf745
20 changed files with 70 additions and 70 deletions

View file

@ -11,8 +11,8 @@ class TestConnectFourBot(BotTestCase, DefaultTests):
def make_request_message( def make_request_message(
self, self,
content: str, content: str,
user: str='foo@example.com', user: str = 'foo@example.com',
user_name: str='foo' user_name: str = 'foo'
) -> Dict[str, str]: ) -> Dict[str, str]:
message = dict( message = dict(
sender_email=user, sender_email=user,
@ -22,7 +22,7 @@ class TestConnectFourBot(BotTestCase, DefaultTests):
return message return message
# Function that serves similar purpose to BotTestCase.verify_dialog, but allows for multiple responses to be handled # Function that serves similar purpose to BotTestCase.verify_dialog, but allows for multiple responses to be handled
def verify_response(self, request: str, expected_response: str, response_number: int, user: str='foo@example.com') -> None: def verify_response(self, request: str, expected_response: str, response_number: int, user: str = 'foo@example.com') -> None:
''' '''
This function serves a similar purpose This function serves a similar purpose
to BotTestCase.verify_dialog, but allows to BotTestCase.verify_dialog, but allows

View file

@ -29,7 +29,7 @@ class MockModel:
self, self,
move: str, move: str,
player: int, player: int,
is_computer: bool=False is_computer: bool = False
) -> Any: ) -> Any:
if not is_computer: if not is_computer:
if int(move.replace('move ', '')) < 9: if int(move.replace('move ', '')) < 9:

View file

@ -12,11 +12,11 @@ class TestGameHandlerBot(BotTestCase, DefaultTests):
def make_request_message( def make_request_message(
self, self,
content: str, content: str,
user: str='foo@example.com', user: str = 'foo@example.com',
user_name: str='foo', user_name: str = 'foo',
type: str='private', type: str = 'private',
stream: str='', stream: str = '',
subject: str='' subject: str = ''
) -> Dict[str, str]: ) -> Dict[str, str]:
message = dict( message = dict(
sender_email=user, sender_email=user,
@ -34,11 +34,11 @@ class TestGameHandlerBot(BotTestCase, DefaultTests):
request: str, request: str,
expected_response: str, expected_response: str,
response_number: int, response_number: int,
bot: Any=None, bot: Any = None,
user_name: str='foo', user_name: str = 'foo',
stream: str='', stream: str = '',
subject: str='', subject: str = '',
max_messages: int=20 max_messages: int = 20
) -> None: ) -> None:
''' '''
This function serves a similar purpose This function serves a similar purpose
@ -65,7 +65,7 @@ class TestGameHandlerBot(BotTestCase, DefaultTests):
self.assertEqual(expected_response, first_response['content']) self.assertEqual(expected_response, first_response['content'])
self.assertLessEqual(len(responses), max_messages) self.assertLessEqual(len(responses), max_messages)
def add_user_to_cache(self, name: str, bot: Any=None) -> Any: def add_user_to_cache(self, name: str, bot: Any = None) -> Any:
if bot is None: if bot is None:
bot, bot_handler = self._get_handlers() bot, bot_handler = self._get_handlers()
message = { message = {
@ -75,7 +75,7 @@ class TestGameHandlerBot(BotTestCase, DefaultTests):
bot.add_user_to_cache(message) bot.add_user_to_cache(message)
return bot return bot
def setup_game(self, id: str='', bot: Any=None, players: List[str]=['foo', 'baz'], subject: str='test game', stream: str='test') -> Any: def setup_game(self, id: str = '', bot: Any = None, players: List[str] = ['foo', 'baz'], subject: str = 'test game', stream: str = 'test') -> Any:
if bot is None: if bot is None:
bot, bot_handler = self._get_handlers() bot, bot_handler = self._get_handlers()
for p in players: for p in players:

View file

@ -13,7 +13,7 @@ class GameOfFifteenModel:
[5, 4, 3], [5, 4, 3],
[2, 1, 0]] [2, 1, 0]]
def __init__(self, board: Any=None) -> None: def __init__(self, board: Any = None) -> None:
if board is not None: if board is not None:
self.current_board = board self.current_board = board
else: else:
@ -52,7 +52,7 @@ class GameOfFifteenModel:
def update_board(self, board): def update_board(self, board):
self.current_board = copy.deepcopy(board) self.current_board = copy.deepcopy(board)
def make_move(self, move: str, player_number: int, computer_move: bool=False) -> Any: def make_move(self, move: str, player_number: int, computer_move: bool = False) -> Any:
board = self.current_board board = self.current_board
move = move.strip() move = move.strip()
move = move.split(' ') move = move.split(' ')

View file

@ -11,8 +11,8 @@ class TestGameOfFifteenBot(BotTestCase, DefaultTests):
def make_request_message( def make_request_message(
self, self,
content: str, content: str,
user: str='foo@example.com', user: str = 'foo@example.com',
user_name: str='foo' user_name: str = 'foo'
) -> Dict[str, str]: ) -> Dict[str, str]:
message = dict( message = dict(
sender_email=user, sender_email=user,
@ -22,7 +22,7 @@ class TestGameOfFifteenBot(BotTestCase, DefaultTests):
return message return message
# Function that serves similar purpose to BotTestCase.verify_dialog, but allows for multiple responses to be handled # Function that serves similar purpose to BotTestCase.verify_dialog, but allows for multiple responses to be handled
def verify_response(self, request: str, expected_response: str, response_number: int, user: str='foo@example.com') -> None: def verify_response(self, request: str, expected_response: str, response_number: int, user: str = 'foo@example.com') -> None:
''' '''
This function serves a similar purpose This function serves a similar purpose
to BotTestCase.verify_dialog, but allows to BotTestCase.verify_dialog, but allows

View file

@ -24,9 +24,9 @@ class UnspecifiedProblemException(Exception):
pass pass
def make_API_request(endpoint: str, def make_API_request(endpoint: str,
method: str="GET", method: str = "GET",
body: Optional[Dict[str, str]]=None, body: Optional[Dict[str, str]] = None,
params: Optional[Dict[str, str]]=None) -> Any: params: Optional[Dict[str, str]] = None) -> Any:
headers = {'Authorization': 'Token ' + api_key} headers = {'Authorization': 'Token ' + api_key}
if method == "GET": if method == "GET":
r = requests.get(API_BASE_URL + endpoint, headers=headers, params=params) r = requests.get(API_BASE_URL + endpoint, headers=headers, params=params)
@ -54,7 +54,7 @@ def api_show_team(hash_id: str) -> Dict[str, str]:
def api_show_users(hash_id: str) -> Any: def api_show_users(hash_id: str) -> Any:
return make_API_request("/teams/{}/members".format(hash_id)) return make_API_request("/teams/{}/members".format(hash_id))
def api_list_entries(team_id: Optional[str]=None) -> List[Dict[str, Any]]: def api_list_entries(team_id: Optional[str] = None) -> List[Dict[str, Any]]:
if team_id: if team_id:
return make_API_request("/entries", params=dict(team_id=team_id)) return make_API_request("/entries", params=dict(team_id=team_id))
else: else:

View file

@ -21,7 +21,7 @@ class Storage:
class MerelsModel: class MerelsModel:
def __init__(self, board: Any=None) -> None: def __init__(self, board: Any = None) -> None:
self.topic = "merels" self.topic = "merels"
self.storage = Storage(self.topic) self.storage = Storage(self.topic)
self.current_board = mechanics.display_game(self.topic, self.storage) self.current_board = mechanics.display_game(self.topic, self.storage)
@ -42,7 +42,7 @@ class MerelsModel:
return True return True
return False return False
def make_move(self, move: str, player_number: int, computer_move: bool=False) -> Any: def make_move(self, move: str, player_number: int, computer_move: bool = False) -> Any:
if self.storage.get(self.topic) == '["X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0]': if self.storage.get(self.topic) == '["X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0]':
self.storage.put( self.storage.put(
self.topic, self.topic,

View file

@ -48,7 +48,7 @@ class TestMerelsBot(BotTestCase, DefaultTests):
def test_setup_game(self): def test_setup_game(self):
self.setup_game() self.setup_game()
def add_user_to_cache(self, name: str, bot: Any=None) -> Any: def add_user_to_cache(self, name: str, bot: Any = None) -> Any:
if bot is None: if bot is None:
bot, bot_handler = self._get_handlers() bot, bot_handler = self._get_handlers()
message = { message = {

View file

@ -39,10 +39,10 @@ def get_help_text() -> str:
def format_result( def format_result(
result: Dict[str, Any], result: Dict[str, Any],
exclude_keys: List[str]=[], exclude_keys: List[str] = [],
force_keys: List[str]=[], force_keys: List[str] = [],
rank_output: bool=False, rank_output: bool = False,
show_all_keys: bool=False show_all_keys: bool = False
) -> str: ) -> str:
exclude_keys += ['Name', 'attributes', 'Id'] exclude_keys += ['Name', 'attributes', 'Id']
output = '' output = ''

View file

@ -108,14 +108,14 @@ mock_object_types = {
class TestSalesforceBot(BotTestCase, DefaultTests): class TestSalesforceBot(BotTestCase, DefaultTests):
bot_name = "salesforce" # type: str bot_name = "salesforce" # type: str
def _test(self, test_name: str, message: str, response: str, auth_success: bool=True) -> None: def _test(self, test_name: str, message: str, response: str, auth_success: bool = True) -> None:
with self.mock_config_info(mock_config), \ with self.mock_config_info(mock_config), \
mock_salesforce_auth(auth_success), \ mock_salesforce_auth(auth_success), \
mock_salesforce_query(test_name, 'salesforce'), \ mock_salesforce_query(test_name, 'salesforce'), \
mock_salesforce_commands_types(): mock_salesforce_commands_types():
self.verify_reply(message, response) self.verify_reply(message, response)
def _test_initialize(self, auth_success: bool=True) -> None: def _test_initialize(self, auth_success: bool = True) -> None:
with self.mock_config_info(mock_config), \ with self.mock_config_info(mock_config), \
mock_salesforce_auth(auth_success), \ mock_salesforce_auth(auth_success), \
mock_salesforce_commands_types(): mock_salesforce_commands_types():

View file

@ -27,7 +27,7 @@ class TicTacToeModel:
[0, 0, 0], [0, 0, 0],
[0, 0, 0]] [0, 0, 0]]
def __init__(self, board: Any=None) -> None: def __init__(self, board: Any = None) -> None:
if board is not None: if board is not None:
self.current_board = board self.current_board = board
else: else:
@ -190,7 +190,7 @@ class TicTacToeModel:
valid = False valid = False
return valid return valid
def make_move(self, move: str, player_number: int, computer_move: bool=False) -> Any: def make_move(self, move: str, player_number: int, computer_move: bool = False) -> Any:
if computer_move: if computer_move:
return self.computer_move(self.current_board, player_number + 1) return self.computer_move(self.current_board, player_number + 1)
move_coords_str = coords_from_command(move) move_coords_str = coords_from_command(move)

View file

@ -40,7 +40,7 @@ class TestTriviaQuizBot(BotTestCase, DefaultTests):
quiz = get_quiz_from_payload(quiz_payload) quiz = get_quiz_from_payload(quiz_payload)
return quiz, bot_handler return quiz, bot_handler
def _test(self, message: str, response: str, fixture: Optional[str]=None) -> None: def _test(self, message: str, response: str, fixture: Optional[str] = None) -> None:
if fixture: if fixture:
with self.mock_http_conversation(fixture): with self.mock_http_conversation(fixture):
self.verify_reply(message, response) self.verify_reply(message, response)

View file

@ -16,7 +16,7 @@ class TestWeatherBot(BotTestCase, DefaultTests):
@**Weather Bot** Portland, Me @**Weather Bot** Portland, Me
'''.strip() '''.strip()
def _test(self, message: str, response: str, fixture: Optional[str]=None) -> None: def _test(self, message: str, response: str, fixture: Optional[str] = None) -> None:
with self.mock_config_info({'key': '123456'}): with self.mock_config_info({'key': '123456'}):
if fixture: if fixture:
with self.mock_http_conversation(fixture): with self.mock_http_conversation(fixture):

View file

@ -85,7 +85,7 @@ def get_xkcd_bot_response(message: Dict[str, str], quoted_name: str) -> str:
fetched['alt'], fetched['alt'],
fetched['img'])) fetched['img']))
def fetch_xkcd_query(mode: int, comic_id: Optional[str]=None) -> Dict[str, str]: def fetch_xkcd_query(mode: int, comic_id: Optional[str] = None) -> Dict[str, str]:
try: try:
if mode == XkcdBotCommand.LATEST: # Fetch the latest comic strip. if mode == XkcdBotCommand.LATEST: # Fetch the latest comic strip.
url = LATEST_XKCD_URL url = LATEST_XKCD_URL

View file

@ -20,7 +20,7 @@ class TestYodaBot(BotTestCase, DefaultTests):
@mention-bot You will learn how to speak like me someday. @mention-bot You will learn how to speak like me someday.
''' '''
def _test(self, message: str, response: str, fixture: Optional[str]=None) -> None: def _test(self, message: str, response: str, fixture: Optional[str] = None) -> None:
with self.mock_config_info({'api_key': '12345678'}): with self.mock_config_info({'api_key': '12345678'}):
if fixture is not None: if fixture is not None:
with self.mock_http_conversation(fixture): with self.mock_http_conversation(fixture):

View file

@ -37,9 +37,9 @@ class GameAdapter:
model: Any, model: Any,
gameMessageHandler: Any, gameMessageHandler: Any,
rules: str, rules: str,
max_players: int=2, max_players: int = 2,
min_players: int=2, min_players: int = 2,
supports_computer: bool=False supports_computer: bool = False
) -> None: ) -> None:
self.game_name = game_name self.game_name = game_name
self.bot_name = bot_name self.bot_name = bot_name
@ -152,7 +152,7 @@ class GameAdapter:
host = self.invites[game_id]['host'] host = self.invites[game_id]['host']
return 'Declined invitation to play **{}** from @**{}**.'.format(self.game_name, self.get_username_by_email(host)) return 'Declined invitation to play **{}** from @**{}**.'.format(self.game_name, self.get_username_by_email(host))
def send_message(self, to: str, content: str, is_private: bool, subject: str='') -> None: def send_message(self, to: str, content: str, is_private: bool, subject: str = '') -> None:
self.bot_handler.send_message(dict( self.bot_handler.send_message(dict(
type='private' if is_private else 'stream', type='private' if is_private else 'stream',
to=to, to=to,
@ -306,7 +306,7 @@ class GameAdapter:
game_id, '@**{}** has accepted the invitation.'.format(self.get_username_by_email(sender))) game_id, '@**{}** has accepted the invitation.'.format(self.get_username_by_email(sender)))
self.start_game_if_ready(game_id) self.start_game_if_ready(game_id)
def create_game_lobby(self, message: Dict[str, Any], users: List[str]=[]) -> None: def create_game_lobby(self, message: Dict[str, Any], users: List[str] = []) -> None:
if self.is_game_in_subject(message['subject'], message['display_recipient']): if self.is_game_in_subject(message['subject'], message['display_recipient']):
self.send_reply(message, 'There is already a game in this stream.') self.send_reply(message, 'There is already a game in this stream.')
return return
@ -448,13 +448,13 @@ class GameAdapter:
reverse=True reverse=True
) )
def send_invite(self, game_id: str, user_email: str, message: Dict[str, Any]={}) -> None: def send_invite(self, game_id: str, user_email: str, message: Dict[str, Any] = {}) -> None:
self.invites[game_id].update({user_email.lower(): 'p'}) self.invites[game_id].update({user_email.lower(): 'p'})
self.send_message(user_email, self.alert_new_invitation(game_id), True) self.send_message(user_email, self.alert_new_invitation(game_id), True)
if message != {}: if message != {}:
self.send_reply(message, self.confirm_new_invitation(user_email)) self.send_reply(message, self.confirm_new_invitation(user_email))
def cancel_game(self, game_id: str, reason: str='') -> None: def cancel_game(self, game_id: str, reason: str = '') -> None:
if game_id in self.invites.keys(): if game_id in self.invites.keys():
self.broadcast(game_id, 'Game cancelled.\n' + reason) self.broadcast(game_id, 'Game cancelled.\n' + reason)
del self.invites[game_id] del self.invites[game_id]
@ -494,7 +494,7 @@ class GameAdapter:
instance.stream, instance.subject) instance.stream, instance.subject)
return object return object
def join_game(self, game_id: str, user_email: str, message: Dict[str, Any]={}) -> None: def join_game(self, game_id: str, user_email: str, message: Dict[str, Any] = {}) -> None:
if len(self.get_players(game_id)) >= self.max_players: if len(self.get_players(game_id)) >= self.max_players:
if message != {}: if message != {}:
self.send_reply(message, 'This game is full.') self.send_reply(message, 'This game is full.')
@ -504,7 +504,7 @@ class GameAdapter:
game_id, '@**{}** has joined the game'.format(self.get_username_by_email(user_email))) game_id, '@**{}** has joined the game'.format(self.get_username_by_email(user_email)))
self.start_game_if_ready(game_id) self.start_game_if_ready(game_id)
def get_players(self, game_id: str, parameter: str='a') -> List[str]: def get_players(self, game_id: str, parameter: str = 'a') -> List[str]:
if game_id in self.invites.keys(): if game_id in self.invites.keys():
players = [] # type: List[str] players = [] # type: List[str]
if (self.invites[game_id]['subject'] == '###private###' and 'p' in parameter) or 'p' not in parameter: if (self.invites[game_id]['subject'] == '###private###' and 'p' in parameter) or 'p' not in parameter:
@ -587,7 +587,7 @@ To move subjects, send your message again, otherwise join the game using the lin
game_id: str, game_id: str,
stream_name: str, stream_name: str,
subject_name: str, subject_name: str,
message: Dict[str, Any]={} message: Dict[str, Any] = {}
) -> None: ) -> None:
if self.get_game_instance_by_subject(stream_name, subject_name) is not None: if self.get_game_instance_by_subject(stream_name, subject_name) is not None:
if message != {}: if message != {}:
@ -642,7 +642,7 @@ To move subjects, send your message again, otherwise join the game using the lin
self.user_cache = json.loads(user_cache_str) self.user_cache = json.loads(user_cache_str)
return self.user_cache return self.user_cache
def verify_users(self, users: List[str], message: Dict[str, Any]={}) -> List[str]: def verify_users(self, users: List[str], message: Dict[str, Any] = {}) -> List[str]:
verified_users = [] verified_users = []
failed = False failed = False
for u in users: for u in users:
@ -684,7 +684,7 @@ To move subjects, send your message again, otherwise join the game using the lin
self.get_game_instance_by_subject( self.get_game_instance_by_subject(
subject_name, stream_name) is not None subject_name, stream_name) is not None
def is_user_not_player(self, user_email: str, message: Dict[str, Any]={}) -> bool: def is_user_not_player(self, user_email: str, message: Dict[str, Any] = {}) -> bool:
user = self.get_user_by_email(user_email) user = self.get_user_by_email(user_email)
if user == {}: if user == {}:
if message != {}: if message != {}:
@ -710,7 +710,7 @@ To move subjects, send your message again, otherwise join the game using the lin
id += valid_characters[random.randrange(0, len(valid_characters))] id += valid_characters[random.randrange(0, len(valid_characters))]
return id return id
def broadcast(self, game_id: str, content: str, include_private: bool=True) -> bool: def broadcast(self, game_id: str, content: str, include_private: bool = True) -> bool:
if include_private: if include_private:
private_recipients = self.get_players(game_id, parameter='p') private_recipients = self.get_players(game_id, parameter='p')
if private_recipients is not None: if private_recipients is not None:

View file

@ -108,8 +108,8 @@ class ExternalBotHandler:
client: Client, client: Client,
root_dir: str, root_dir: str,
bot_details: Dict[str, Any], bot_details: Dict[str, Any],
bot_config_file: Optional[str]=None, bot_config_file: Optional[str] = None,
bot_config_parser: Optional[configparser.ConfigParser]=None, bot_config_parser: Optional[configparser.ConfigParser] = None,
) -> None: ) -> None:
# Only expose a subset of our Client's functionality # Only expose a subset of our Client's functionality
try: try:
@ -161,7 +161,7 @@ class ExternalBotHandler:
print("ERROR!: " + str(resp)) print("ERROR!: " + str(resp))
return resp return resp
def send_reply(self, message: Dict[str, Any], response: str, widget_content: Optional[str]=None) -> Dict[str, Any]: def send_reply(self, message: Dict[str, Any], response: str, widget_content: Optional[str] = None) -> Dict[str, Any]:
if message['type'] == 'private': if message['type'] == 'private':
return self.send_message(dict( return self.send_message(dict(
type='private', type='private',
@ -183,7 +183,7 @@ class ExternalBotHandler:
self._rate_limit.show_error_and_exit() self._rate_limit.show_error_and_exit()
return self._client.update_message(message) return self._client.update_message(message)
def get_config_info(self, bot_name: str, optional: Optional[bool]=False) -> Dict[str, Any]: def get_config_info(self, bot_name: str, optional: Optional[bool] = False) -> Dict[str, Any]:
if self._bot_config_parser is not None: if self._bot_config_parser is not None:
config_parser = self._bot_config_parser config_parser = self._bot_config_parser
else: else:
@ -245,7 +245,7 @@ class ExternalBotHandler:
raise PermissionError("Cannot open file \"{}\". Bots may only access " raise PermissionError("Cannot open file \"{}\". Bots may only access "
"files in their local directory.".format(abs_filepath)) "files in their local directory.".format(abs_filepath))
def quit(self, message: str="") -> None: def quit(self, message: str = "") -> None:
sys.exit(message) sys.exit(message)

View file

@ -42,7 +42,7 @@ class StubBotHandler:
return self.message_server.send(message) return self.message_server.send(message)
def send_reply(self, message: Dict[str, Any], response: str, def send_reply(self, message: Dict[str, Any], response: str,
widget_content: Optional[str]=None) -> Dict[str, Any]: widget_content: Optional[str] = None) -> Dict[str, Any]:
response_message = dict( response_message = dict(
content=response, content=response,
widget_content=widget_content widget_content=widget_content
@ -63,10 +63,10 @@ class StubBotHandler:
class BotQuitException(Exception): class BotQuitException(Exception):
pass pass
def quit(self, message: str="") -> None: def quit(self, message: str = "") -> None:
raise self.BotQuitException() raise self.BotQuitException()
def get_config_info(self, bot_name: str, optional: bool=False) -> Dict[str, Any]: def get_config_info(self, bot_name: str, optional: bool = False) -> Dict[str, Any]:
return {} return {}
def unique_reply(self) -> Dict[str, Any]: def unique_reply(self) -> Dict[str, Any]:

View file

@ -17,13 +17,13 @@ class BotServerTestCase(TestCase):
def assert_bot_server_response( def assert_bot_server_response(
self, self,
mock_ExternalBotHandler: mock.Mock, mock_ExternalBotHandler: mock.Mock,
available_bots: Optional[List[str]]=None, available_bots: Optional[List[str]] = None,
bots_config: Optional[Dict[str, Dict[str, str]]]=None, bots_config: Optional[Dict[str, Dict[str, str]]] = None,
bot_handlers: Optional[Dict[str, Any]]=None, bot_handlers: Optional[Dict[str, Any]] = None,
event: Optional[Dict[str, Any]]=None, event: Optional[Dict[str, Any]] = None,
expected_response: Optional[str]=None, expected_response: Optional[str] = None,
check_success: bool=False, check_success: bool = False,
third_party_bot_conf: Optional[configparser.ConfigParser]=None, third_party_bot_conf: Optional[configparser.ConfigParser] = None,
) -> None: ) -> None:
if available_bots is not None and bots_config is not None: if available_bots is not None and bots_config is not None:
server.bots_config = bots_config server.bots_config = bots_config

View file

@ -29,7 +29,7 @@ def read_config_section(parser: configparser.ConfigParser, section: str) -> Dict
return section_info return section_info
def read_config_file(config_file_path: str, bot_name: Optional[str]=None) -> Dict[str, Dict[str, str]]: def read_config_file(config_file_path: str, bot_name: Optional[str] = None) -> Dict[str, Dict[str, str]]:
parser = parse_config_file(config_file_path) parser = parse_config_file(config_file_path)
bots_config = {} # type: Dict[str, Dict[str, str]] bots_config = {} # type: Dict[str, Dict[str, str]]
@ -102,7 +102,7 @@ def load_lib_modules(available_bots: List[str]) -> Dict[str, Any]:
def load_bot_handlers( def load_bot_handlers(
available_bots: List[str], available_bots: List[str],
bots_config: Dict[str, Dict[str, str]], bots_config: Dict[str, Dict[str, str]],
third_party_bot_conf: Optional[configparser.ConfigParser]=None, third_party_bot_conf: Optional[configparser.ConfigParser] = None,
) -> Dict[str, lib.ExternalBotHandler]: ) -> Dict[str, lib.ExternalBotHandler]:
bot_handlers = {} bot_handlers = {}
for bot in available_bots: for bot in available_bots: