Modernize legacy Python 2 syntax with pyupgrade.

Generated by `pyupgrade --py3-plus --keep-percent-format` followed by
manual indentation fixes.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
This commit is contained in:
Anders Kaseorg 2020-04-09 17:14:01 -07:00 committed by Tim Abbott
parent 543eb396b9
commit e30b3b094b
107 changed files with 192 additions and 244 deletions

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
@ -23,7 +22,7 @@ if not IS_PYPA_PACKAGE:
package_data[''].append('fixtures/*.json')
package_data[''].append('logo.*')
with open("README.md", "r") as fh:
with open("README.md") as fh:
long_description = fh.read()
# We should be installable with either setuptools or distutils.

View file

@ -3,7 +3,7 @@
from typing import Any, List, Dict
import requests
class BaremetricsHandler(object):
class BaremetricsHandler:
def initialize(self, bot_handler: Any) -> None:
self.config_info = bot_handler.get_config_info('baremetrics')
self.api_key = self.config_info['api_key']

View file

@ -74,7 +74,7 @@ at syntax by: @mention-botname help"
right now.\nPlease try again later"
class BeeminderHandler(object):
class BeeminderHandler:
'''
This plugin allows users to easily add datapoints
towards their beeminder goals via zulip

View file

@ -11,7 +11,7 @@ START_COMPUTER_REGEX = re.compile(
MOVE_REGEX = re.compile('do (?P<move_san>.+)$')
RESIGN_REGEX = re.compile('resign$')
class ChessHandler(object):
class ChessHandler:
def usage(self) -> str:
return (
'Chess Bot is a bot that allows you to play chess against either '
@ -742,4 +742,4 @@ def trim_whitespace_before_newline(str_to_trim: str) -> str:
Returns: The trimmed string.
"""
return re.sub('\s+$', '', str_to_trim, flags=re.M)
return re.sub(r'\s+$', '', str_to_trim, flags=re.M)

View file

@ -3,7 +3,7 @@ from zulip_bots.bots.connect_four.controller import ConnectFourModel
from typing import Any
class ConnectFourMessageHandler(object):
class ConnectFourMessageHandler:
tokens = [':blue_circle:', ':red_circle:']
def parse_board(self, board: Any) -> str:
@ -52,7 +52,7 @@ class ConnectFourBotHandler(GameAdapter):
gameMessageHandler = ConnectFourMessageHandler
rules = '''Try to get four pieces in row, Diagonals count too!'''
super(ConnectFourBotHandler, self).__init__(
super().__init__(
game_name,
bot_name,
move_help_message,

View file

@ -4,7 +4,7 @@ from functools import reduce
from zulip_bots.game_handler import BadMoveException
class ConnectFourModel(object):
class ConnectFourModel:
'''
Object that manages running the Connect
Four logic for the Connect Four Bot

View file

@ -25,7 +25,7 @@ def is_float(value: Any) -> bool:
def round_to(x: float, digits: int) -> float:
return round(x, digits-int(floor(log10(abs(x)))))
class ConverterHandler(object):
class ConverterHandler:
'''
This plugin allows users to make conversions between various units,
e.g. Celsius to Fahrenheit, or kilobytes to gigabytes.

View file

@ -7,7 +7,7 @@ import string
from typing import Any, Dict
class DefineHandler(object):
class DefineHandler:
'''
This plugin define a word that the user inputs. It
looks for messages starting with '@mention-bot'.

View file

@ -35,7 +35,7 @@ def get_bot_result(message_content: str, config: Dict[str, str], sender_id: str)
logging.exception(str(e))
return 'Error. {}.'.format(str(e))
class DialogFlowHandler(object):
class DialogFlowHandler:
'''
This plugin allows users to easily add their own
DialogFlow bots to zulip

View file

@ -4,7 +4,7 @@ import re
URL = "[{name}](https://www.dropbox.com/home{path})"
class DropboxHandler(object):
class DropboxHandler:
'''
This bot allows you to easily share, search and upload files
between zulip and your dropbox account.
@ -60,11 +60,11 @@ def get_usage_examples() -> str:
REGEXES = dict(
command='(ls|mkdir|read|rm|write|search|usage|help)',
path='(\S+)',
optional_path='(\S*)',
path=r'(\S+)',
optional_path=r'(\S*)',
some_text='(.+?)',
folder='?(?:--fd (\S+))?',
max_results='?(?:--mr (\d+))?'
folder=r'?(?:--fd (\S+))?',
max_results=r'?(?:--mr (\d+))?'
)
def get_commands() -> Dict[str, Tuple[Any, List[str]]]:
@ -137,7 +137,7 @@ def dbx_ls(client: Any, fn: str) -> str:
files_list += [" - " + URL.format(name=meta.name, path=meta.path_lower)]
msg = '\n'.join(files_list)
if msg is '':
if msg == '':
msg = '`No files available`'
except Exception:

View file

@ -17,7 +17,7 @@ def encrypt(text: str) -> str:
return newtext
class EncryptHandler(object):
class EncryptHandler:
'''
This bot allows users to quickly encrypt messages using ROT13 encryption.
It encrypts/decrypts messages starting with @mention-bot.

View file

@ -3,7 +3,7 @@ from typing import Any, Dict
import os
from pathlib import Path
class FileUploaderHandler(object):
class FileUploaderHandler:
def usage(self) -> str:
return (
'This interactive bot is used to upload files (such as images) to the Zulip server:'

View file

@ -86,7 +86,7 @@ def get_flock_bot_response(content: str, config: Dict[str, str]) -> None:
result = get_flock_response(content, config)
return result
class FlockHandler(object):
class FlockHandler:
'''
This is flock bot. Now you can send messages to any of your
flock user without having to leave Zulip.

View file

@ -1,7 +1,7 @@
# See readme.md for instructions on running this code.
from typing import Dict, Any
class FollowupHandler(object):
class FollowupHandler:
'''
This plugin facilitates creating follow-up tasks when
you are using Zulip to conduct a virtual meeting. It

View file

@ -2,7 +2,7 @@ import requests
import re
from typing import Any, Dict, Optional
class FrontHandler(object):
class FrontHandler:
FRONT_API = "https://api2.frontapp.com/conversations/{}"
COMMANDS = [
('archive', "Archive a conversation."),

View file

@ -2,7 +2,7 @@ from zulip_bots.game_handler import GameAdapter, BadMoveException
from typing import List, Any
class GameHandlerBotMessageHandler(object):
class GameHandlerBotMessageHandler:
tokens = [':blue_circle:', ':red_circle:']
def parse_board(self, board: Any) -> str:
@ -21,7 +21,7 @@ The first player to get 4 in a row wins!\n \
Good Luck!'
class MockModel(object):
class MockModel:
def __init__(self) -> None:
self.current_board = 'mock board'
@ -53,12 +53,12 @@ class GameHandlerBotHandler(GameAdapter):
bot_name = 'game_handler_bot'
move_help_message = '* To make your move during a game, type\n' \
'```move <column-number>```'
move_regex = 'move (\d)$'
move_regex = r'move (\d)$'
model = MockModel
gameMessageHandler = GameHandlerBotMessageHandler
rules = ''
super(GameHandlerBotHandler, self).__init__(
super().__init__(
game_name,
bot_name,
move_help_message,

View file

@ -4,7 +4,7 @@ import random
from typing import List, Any, Tuple, Dict
from zulip_bots.game_handler import GameAdapter, BadMoveException
class GameOfFifteenModel(object):
class GameOfFifteenModel:
final_board = [[0, 1, 2],
[3, 4, 5],
@ -84,7 +84,7 @@ class GameOfFifteenModel(object):
if m == moves - 1:
return board
class GameOfFifteenMessageHandler(object):
class GameOfFifteenMessageHandler:
tiles = {
'0': ':grey_question:',
@ -127,14 +127,14 @@ class GameOfFifteenBotHandler(GameAdapter):
bot_name = 'Game of Fifteen'
move_help_message = '* To make your move during a game, type\n' \
'```move <tile1> <tile2> ...```'
move_regex = 'move [\d{1}\s]+$'
move_regex = r'move [\d{1}\s]+$'
model = GameOfFifteenModel
gameMessageHandler = GameOfFifteenMessageHandler
rules = '''Arrange the boards tiles from smallest to largest, left to right,
top to bottom, and tiles adjacent to :grey_question: can only be moved.
Final configuration will have :grey_question: in top left.'''
super(GameOfFifteenBotHandler, self).__init__(
super().__init__(
game_name,
bot_name,
move_help_message,

View file

@ -9,7 +9,7 @@ GIPHY_TRANSLATE_API = 'http://api.giphy.com/v1/gifs/translate'
GIPHY_RANDOM_API = 'http://api.giphy.com/v1/gifs/random'
class GiphyHandler(object):
class GiphyHandler:
"""
This plugin posts a GIF in response to the keywords provided by the user.
Images are provided by Giphy, through the public API.

View file

@ -8,14 +8,14 @@ import requests
from typing import Dict, Any, Tuple, Union
class GithubHandler(object):
class GithubHandler:
'''
This bot provides details on github issues and pull requests when they're
referenced in the chat.
'''
GITHUB_ISSUE_URL_TEMPLATE = 'https://api.github.com/repos/{owner}/{repo}/issues/{id}'
HANDLE_MESSAGE_REGEX = re.compile("(?:([\w-]+)\/)?([\w-]+)?#(\d+)")
HANDLE_MESSAGE_REGEX = re.compile(r"(?:([\w-]+)\/)?([\w-]+)?#(\d+)")
def initialize(self, bot_handler: Any) -> None:
self.config_info = bot_handler.get_config_info('github_detail', optional=True)

View file

@ -63,7 +63,7 @@ def get_google_result(search_keywords: str) -> str:
logging.exception(str(e))
return 'Error: Search failed. {}.'.format(e)
class GoogleSearchHandler(object):
class GoogleSearchHandler:
'''
This plugin allows users to enter a search
term in Zulip and get the top URL sent back

View file

@ -4,7 +4,7 @@
import requests
from requests.exceptions import HTTPError, ConnectionError
class GoogleTranslateHandler(object):
class GoogleTranslateHandler:
'''
This bot will translate any messages sent to it using google translate.
Before using it, make sure you set up google api keys, and enable google

View file

@ -2,7 +2,7 @@
from typing import Any, Dict
class HelloWorldHandler(object):
class HelloWorldHandler:
def usage(self) -> str:
return '''
This is a boilerplate bot that responds to a user query with

View file

@ -1,7 +1,7 @@
# See readme.md for instructions on running this code.
from typing import Any, Dict
class HelpHandler(object):
class HelpHandler:
def usage(self) -> str:
return '''
This plugin will give info about Zulip to

View file

@ -128,7 +128,7 @@ More information in my help""")
data = api_create_entry(new_message, team_id)
return "Great work :thumbs_up:. New entry `{}` created!".format(data['body_formatted'])
class IDoneThisHandler(object):
class IDoneThisHandler:
def initialize(self, bot_handler: Any) -> None:
global api_key, default_team
self.config_info = bot_handler.get_config_info('idonethis')

View file

@ -59,7 +59,7 @@ def start_new_incident(query: str, message: Dict[str, Any], bot_handler: Any) ->
bot_handler.send_reply(message, bot_response, widget_content)
def parse_answer(query: str) -> Tuple[str, str]:
m = re.match('answer\s+(TICKET....)\s+(.)', query)
m = re.match(r'answer\s+(TICKET....)\s+(.)', query)
if not m:
raise InvalidAnswerException()

View file

@ -2,7 +2,7 @@
from typing import Dict, Any
class IncrementorHandler(object):
class IncrementorHandler:
META = {
'name': 'Incrementor',
'description': 'Example bot to test the update_message() function.',

View file

@ -106,7 +106,7 @@ Jira Bot:
> Issue *BOTS-16* was edited! https://example.atlassian.net/browse/BOTS-16
'''
class JiraHandler(object):
class JiraHandler:
def usage(self) -> str:
return '''
Jira Bot uses the Jira REST API to interact with Jira. In order to use
@ -164,14 +164,14 @@ class JiraHandler(object):
response = 'Oh no! Jira raised an error:\n > ' + ', '.join(errors)
else:
response = (
'**Issue *[{0}]({1})*: {2}**\n\n'
' - Type: *{3}*\n'
'**Issue *[{}]({})*: {}**\n\n'
' - Type: *{}*\n'
' - Description:\n'
' > {4}\n'
' - Creator: *{5}*\n'
' - Project: *{6}*\n'
' - Priority: *{7}*\n'
' - Status: *{8}*\n'
' > {}\n'
' - Creator: *{}*\n'
' - Project: *{}*\n'
' - Priority: *{}*\n'
' - Status: *{}*\n'
).format(key, url, summary, type_name, description, creator_name, project_name,
priority_name, status_name)
elif create_match:

View file

@ -4,7 +4,7 @@ import logging
from typing import Any, Dict
class LinkShortenerHandler(object):
class LinkShortenerHandler:
'''A Zulip bot that will shorten URLs ("links") in a conversation using the
goo.gl URL shortener.
'''
@ -33,10 +33,10 @@ class LinkShortenerHandler(object):
def handle_message(self, message: Dict[str, str], bot_handler: Any) -> None:
REGEX_STR = (
'('
'(?:http|https):\/\/' # This allows for the HTTP or HTTPS
# protocol.
'[^"<>\{\}|\\^~[\]` ]+' # This allows for any character except
# for certain non-URL-safe ones.
r'(?:http|https):\/\/' # This allows for the HTTP or HTTPS
# protocol.
'[^"<>\\{\\}|\\^~[\\]` ]+' # This allows for any character except
# for certain non-URL-safe ones.
')'
)

View file

@ -4,7 +4,7 @@ import requests
from typing import Any, List, Dict
import logging
class MentionHandler(object):
class MentionHandler:
def initialize(self, bot_handler: Any) -> None:
self.config_info = bot_handler.get_config_info('mention')
self.access_token = self.config_info['access_token']

View file

@ -199,5 +199,5 @@ def check_win(topic_name, merels_storage):
win = mechanics.who_won(topic_name, merels_storage)
if win != "None":
merels.remove_game(topic_name)
return "{0} wins the game!".format(win)
return "{} wins the game!".format(win)
return ""

View file

@ -285,7 +285,7 @@ def create_room(topic_name, merels_storage):
return response
else:
return "Failed: Cannot create an already existing game in {0}. " \
return "Failed: Cannot create an already existing game in {}. " \
"Please finish the game first.".format(topic_name)
@ -358,7 +358,7 @@ def move_man(topic_name, p1, p2, merels_storage):
merels.update_game(data.topic_name, data.turn, data.x_taken,
data.o_taken, data.board, data.hill_uid,
data.take_mode)
return "Moved a man from ({0}, {1}) -> ({2}, {3}) for {4}.".format(
return "Moved a man from ({}, {}) -> ({}, {}) for {}.".format(
p1[0], p1[1], p2[0], p2[1], data.turn)
else:
raise BadMoveException("Failed: That's not a legal move. Please try again.")
@ -390,7 +390,7 @@ def put_man(topic_name, v, h, merels_storage):
merels.update_game(data.topic_name, data.turn, data.x_taken,
data.o_taken, data.board, data.hill_uid,
data.take_mode)
return "Put a man to ({0}, {1}) for {2}.".format(v, h, data.turn)
return "Put a man to ({}, {}) for {}.".format(v, h, data.turn)
else:
raise BadMoveException("Failed: That's not a legal put. Please try again.")
@ -428,7 +428,7 @@ def take_man(topic_name, v, h, merels_storage):
merels.update_game(data.topic_name, data.turn, data.x_taken,
data.o_taken, data.board, data.hill_uid,
data.take_mode)
return "Taken a man from ({0}, {1}) for {2}.".format(v, h, data.turn)
return "Taken a man from ({}, {}) for {}.".format(v, h, data.turn)
else:
raise BadMoveException("Failed: That's not a legal take. Please try again.")

View file

@ -7,7 +7,7 @@ from zulip_bots.bots.merels.libraries import (
)
from zulip_bots.game_handler import GameAdapter, SamePlayerMove, GameInstance
class Storage(object):
class Storage:
data = {}
def __init__(self, topic_name):
@ -19,7 +19,7 @@ class Storage(object):
def get(self, topic_name):
return self.data[topic_name]
class MerelsModel(object):
class MerelsModel:
def __init__(self, board: Any=None) -> None:
self.topic = "merels"
@ -54,7 +54,7 @@ class MerelsModel(object):
raise SamePlayerMove(same_player_move)
return self.current_board
class MerelsMessageHandler(object):
class MerelsMessageHandler:
tokens = [':o_button:', ':cross_mark_button:']
def parse_board(self, board: Any) -> str:
@ -90,7 +90,7 @@ class MerelsHandler(GameAdapter):
model = MerelsModel
rules = game.getInfo()
gameMessageHandler = MerelsMessageHandler
super(MerelsHandler, self).__init__(
super().__init__(
game_name,
bot_name,
move_help_message,

View file

@ -5,7 +5,7 @@ from zulip_bots.bots.monkeytestit.lib import parse
from zulip_bots.lib import NoBotConfigException
class MonkeyTestitBot(object):
class MonkeyTestitBot:
def __init__(self):
self.api_key = "None"
self.config = None

View file

@ -82,7 +82,7 @@ def query_salesforce(arg: str, salesforce: simple_salesforce.Salesforce, command
raw_arg = ' -' + arg.split(' -', 1)[1]
split_args = raw_arg.split(' -')
limit_num = 5
re_limit = re.compile('-limit \d+')
re_limit = re.compile(r'-limit \d+')
limit = re_limit.search(raw_arg)
if limit:
limit_num = int(limit.group().rsplit(' ', 1)[1])
@ -122,7 +122,7 @@ def get_salesforce_link_details(link: str, sf: Any) -> str:
return 'No object found. Make sure it is of the supported types. Type `help` for more info.'
class SalesforceHandler(object):
class SalesforceHandler:
def usage(self) -> str:
return '''
This is a Salesforce bot, which can search for Contacts,
@ -136,7 +136,7 @@ class SalesforceHandler(object):
def get_salesforce_response(self, content: str) -> str:
content = content.strip()
if content is '' or content == 'help':
if content == '' or content == 'help':
return get_help_text()
if content.startswith('http') and 'force' in content:
return get_salesforce_link_details(content, self.sf)

View file

@ -7,7 +7,7 @@ from typing import Optional, Any, Dict
# See readme.md for instructions on running this code.
class StackOverflowHandler(object):
class StackOverflowHandler:
'''
This plugin facilitates searching Stack Overflow for a
specific query and returns the top 3 questions from the

View file

@ -1,7 +1,7 @@
import requests
from typing import Dict, Any, Tuple, Union
class SusiHandler(object):
class SusiHandler:
'''
Susi AI Bot
To create and know more of SUSI skills go to `https://skills.susi.ai/`

View file

@ -9,7 +9,7 @@ from zulip_bots.game_handler import GameAdapter, BadMoveException
State = List[List[str]]
class TicTacToeModel(object):
class TicTacToeModel:
smarter = True
# If smarter is True, the computer will do some extra thinking - it'll be harder for the user.
@ -208,7 +208,7 @@ class TicTacToeModel(object):
return board
class TicTacToeMessageHandler(object):
class TicTacToeMessageHandler:
tokens = [':x:', ':o:']
def parse_row(self, row: Tuple[int, int], row_num: int) -> str:
@ -259,11 +259,11 @@ class ticTacToeHandler(GameAdapter):
game_name = 'Tic Tac Toe'
bot_name = 'tictactoe'
move_help_message = '* To move during a game, type\n`move <number>` or `<number>`'
move_regex = '(move (\d)$)|((\d)$)'
move_regex = r'(move (\d)$)|((\d)$)'
model = TicTacToeModel
gameMessageHandler = TicTacToeMessageHandler
rules = '''Try to get three in horizontal or vertical or diagonal row to win the game.'''
super(ticTacToeHandler, self).__init__(
super().__init__(
game_name,
bot_name,
move_help_message,

View file

@ -14,7 +14,7 @@ supported_commands = [
INVALID_ARGUMENTS_ERROR_MESSAGE = 'Invalid Arguments.'
RESPONSE_ERROR_MESSAGE = 'Invalid Response. Please check configuration and parameters.'
class TrelloHandler(object):
class TrelloHandler:
def initialize(self, bot_handler: Any) -> None:
self.config_info = bot_handler.get_config_info('trello')
self.api_key = self.config_info['api_key']

View file

@ -65,7 +65,7 @@ def start_new_quiz(message: Dict[str, Any], bot_handler: Any) -> None:
bot_handler.send_reply(message, bot_response, widget_content)
def parse_answer(query: str) -> Tuple[str, str]:
m = re.match('answer\s+(Q...)\s+(.)', query)
m = re.match(r'answer\s+(Q...)\s+(.)', query)
if not m:
raise InvalidAnswerException()

View file

@ -3,7 +3,7 @@ import tweepy
from typing import Dict, Any, Union, List, Tuple, Optional
class TwitpostBot(object):
class TwitpostBot:
def usage(self) -> str:
return ''' This bot posts on twitter from zulip chat itself.

View file

@ -5,7 +5,7 @@ import os
from typing import Any, Dict, List, Tuple, Callable, Set, Union
class VirtualFsHandler(object):
class VirtualFsHandler:
META = {
'name': 'VirtualFs',
'description': 'Provides a simple, permanent file system to store and retrieve strings.',
@ -112,8 +112,8 @@ def sample_conversation() -> List[Tuple[str, str]]:
REGEXES = dict(
command='(cd|ls|mkdir|read|rmdir|rm|write|pwd)',
path='(\S+)',
optional_path='(\S*)',
path=r'(\S+)',
optional_path=r'(\S*)',
some_text='(.+)',
)

View file

@ -7,7 +7,7 @@ from typing import Any, Dict
api_url = 'http://api.openweathermap.org/data/2.5/weather'
class WeatherHandler(object):
class WeatherHandler:
def initialize(self, bot_handler: Any) -> None:
self.api_key = bot_handler.get_config_info('weather')['key']
self.response_pattern = 'Weather in {}, {}:\n{:.2f} F / {:.2f} C\n{}'

View file

@ -8,7 +8,7 @@ from typing import Optional, Any, Dict
# See readme.md for instructions on running this code.
class WikipediaHandler(object):
class WikipediaHandler:
'''
This plugin facilitates searching Wikipedia for a
specific key term and returns the top 3 articles from the

View file

@ -5,7 +5,7 @@ import wit
import sys
import importlib.util
class WitaiHandler(object):
class WitaiHandler:
def usage(self) -> str:
return '''
Wit.ai bot uses pywit API to interact with Wit.ai. In order to use

View file

@ -8,7 +8,7 @@ from typing import Any, Dict, Optional
XKCD_TEMPLATE_URL = 'https://xkcd.com/%s/info.0.json'
LATEST_XKCD_URL = 'https://xkcd.com/info.0.json'
class XkcdHandler(object):
class XkcdHandler:
'''
This plugin provides several commands that can be used for fetch a comic
strip from https://xkcd.com. The bot looks for messages starting with
@ -39,7 +39,7 @@ class XkcdHandler(object):
xkcd_bot_response = get_xkcd_bot_response(message, quoted_name)
bot_handler.send_reply(message, xkcd_bot_response)
class XkcdBotCommand(object):
class XkcdBotCommand:
LATEST = 0
RANDOM = 1
COMIC_ID = 2

View file

@ -28,7 +28,7 @@ class ServiceUnavailableError(Exception):
'''raise this when the service is unavailable.'''
class YodaSpeakHandler(object):
class YodaSpeakHandler:
'''
This bot will allow users to translate a sentence into 'Yoda speak'.
It looks for messages starting with '@mention-bot'.

View file

@ -7,7 +7,7 @@ from typing import Dict, Any, Union, List, Tuple, Optional
commands_list = ('list', 'top', 'help')
class YoutubeHandler(object):
class YoutubeHandler:
def usage(self) -> str:
return '''

View file

@ -23,7 +23,7 @@ class SamePlayerMove(Exception):
def __str__(self) -> str:
return self.message
class GameAdapter(object):
class GameAdapter:
'''
Class that serves as a template to easily
create multiplayer games.
@ -248,7 +248,7 @@ class GameAdapter(object):
elif content.lower() == 'join':
self.command_join(message, sender, content)
elif self.is_user_in_game(sender) is not '':
elif self.is_user_in_game(sender) != '':
self.parse_message(message)
elif self.move_regex.match(content) is not None or content.lower() == 'draw' or content.lower() == 'forfeit':
@ -299,7 +299,7 @@ class GameAdapter(object):
message, self.already_in_game_message())
return
game_id = self.set_invite_by_user(sender, True, message)
if game_id is '':
if game_id == '':
self.send_reply(
message, 'No active invites. Type `help` for commands.')
return
@ -366,7 +366,7 @@ class GameAdapter(object):
message, self.already_in_game_message())
return
game_id = self.set_invite_by_user(sender, False, message)
if game_id is '':
if game_id == '':
self.send_reply(
message, 'No active invites. Type `help` for commands.')
return
@ -381,7 +381,7 @@ class GameAdapter(object):
if message['type'] == 'private' and self.is_single_player:
self.send_reply(message, 'You are not allowed to play games in private messages.')
return
if game_id is '':
if game_id == '':
self.send_reply(
message, 'You are not in a game. Type `help` for all commands.')
sender_avatar = "!avatar({})".format(sender)
@ -399,7 +399,7 @@ class GameAdapter(object):
return
game_id = self.get_invite_in_subject(
message['subject'], message['display_recipient'])
if game_id is '':
if game_id == '':
self.send_reply(
message, 'There is not a game in this subject. Type `help` for all commands.')
return
@ -408,7 +408,7 @@ class GameAdapter(object):
def command_play(self, message: Dict[str, Any], sender: str, content: str) -> None:
game_id = self.get_invite_in_subject(
message['subject'], message['display_recipient'])
if game_id is '':
if game_id == '':
self.send_reply(
message, 'There is not a game in this subject. Type `help` for all commands.')
return
@ -683,7 +683,7 @@ To move subjects, send your message again, otherwise join the game using the lin
return ''
def is_game_in_subject(self, subject_name: str, stream_name: str) -> bool:
return self.get_invite_in_subject(subject_name, stream_name) is not '' or \
return self.get_invite_in_subject(subject_name, stream_name) != '' or \
self.get_game_instance_by_subject(
subject_name, stream_name) is not None
@ -752,7 +752,7 @@ To move subjects, send your message again, otherwise join the game using the lin
return self.bot_handler.full_name
class GameInstance(object):
class GameInstance:
'''
The GameInstance class handles the game logic for a certain game,
and is associated with a certain stream.

View file

@ -47,7 +47,7 @@ def zulip_env_vars_are_present() -> bool:
# missing, we can proceed without a config file.
return True
class RateLimit(object):
class RateLimit:
def __init__(self, message_limit: int, interval_limit: int) -> None:
self.message_limit = message_limit
self.interval_limit = interval_limit
@ -69,7 +69,7 @@ class RateLimit(object):
sys.exit(1)
class StateHandler(object):
class StateHandler:
def __init__(self, client: Client) -> None:
self._client = client
self.marshal = lambda obj: json.dumps(obj)
@ -97,13 +97,13 @@ class StateHandler(object):
def contains(self, key: Text) -> bool:
return key in self.state_
class BotIdentity(object):
class BotIdentity:
def __init__(self, name: str, email: str) -> None:
self.name = name
self.email = email
self.mention = '@**' + name + '**'
class ExternalBotHandler(object):
class ExternalBotHandler:
def __init__(
self,
client: Client,

View file

@ -38,8 +38,8 @@ def main():
try:
lib_module = import_module_from_source(bot_path, bot_name)
if lib_module is None:
raise IOError
except IOError:
raise OSError
except OSError:
print("Could not find and import bot '{}'".format(bot_name))
sys.exit(1)

View file

@ -95,7 +95,7 @@ class TestBotLib(TestCase):
test_message("brokenmention", "@**brokenmention* foo", None)
test_message("nomention", "foo", None)
test_message("Max Mustermann", "@**Max Mustermann** foo", "foo")
test_message("Max (Mustermann)#(*$&12]\]", "@**Max (Mustermann)#(*$&12]\]** foo", "foo")
test_message(r"Max (Mustermann)#(*$&12]\]", r"@**Max (Mustermann)#(*$&12]\]** foo", "foo")
if __name__ == '__main__':
unittest.main()