ruff: Fix RUF012 Mutable class attributes should be annotated with typing.ClassVar
.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
b37708b96e
commit
f26b861f51
25 changed files with 83 additions and 76 deletions
|
@ -12,7 +12,7 @@ import urllib.request
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Any, Dict, List, Match, Optional, Set, Tuple, Type, Union
|
from typing import Any, ClassVar, Dict, List, Match, Optional, Set, Tuple, Type, Union
|
||||||
|
|
||||||
import nio
|
import nio
|
||||||
from nio.responses import (
|
from nio.responses import (
|
||||||
|
@ -52,7 +52,7 @@ class MatrixToZulip:
|
||||||
Matrix -> Zulip
|
Matrix -> Zulip
|
||||||
"""
|
"""
|
||||||
|
|
||||||
non_formatted_messages: Dict[Type[nio.Event], str] = {
|
non_formatted_messages: ClassVar[Dict[Type[nio.Event], str]] = {
|
||||||
nio.StickerEvent: "sticker",
|
nio.StickerEvent: "sticker",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import sys
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from subprocess import PIPE, Popen
|
from subprocess import PIPE, Popen
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
from typing import Any, Awaitable, Callable, Iterator, List
|
from typing import Any, Awaitable, Callable, Final, Iterator, List
|
||||||
from unittest import TestCase, mock
|
from unittest import TestCase, mock
|
||||||
|
|
||||||
import nio
|
import nio
|
||||||
|
@ -209,13 +209,13 @@ class MatrixBridgeMatrixToZulipTests(TestCase):
|
||||||
|
|
||||||
class MatrixBridgeZulipToMatrixTests(TestCase):
|
class MatrixBridgeZulipToMatrixTests(TestCase):
|
||||||
room = mock.MagicMock()
|
room = mock.MagicMock()
|
||||||
valid_zulip_config = dict(
|
valid_zulip_config: Final = dict(
|
||||||
stream="some stream",
|
stream="some stream",
|
||||||
topic="some topic",
|
topic="some topic",
|
||||||
email="some@email",
|
email="some@email",
|
||||||
bridges={("some stream", "some topic"): room},
|
bridges={("some stream", "some topic"): room},
|
||||||
)
|
)
|
||||||
valid_msg = dict(
|
valid_msg: Final = dict(
|
||||||
sender_email="John@Smith.smith", # must not be equal to config:email
|
sender_email="John@Smith.smith", # must not be equal to config:email
|
||||||
sender_id=42,
|
sender_id=42,
|
||||||
type="stream", # Can only mirror Zulip streams
|
type="stream", # Can only mirror Zulip streams
|
||||||
|
|
|
@ -32,10 +32,10 @@ sa_family_t = c_ushort
|
||||||
|
|
||||||
|
|
||||||
class sockaddr(Structure):
|
class sockaddr(Structure):
|
||||||
_fields_ = [
|
_fields_ = (
|
||||||
("sa_family", sa_family_t),
|
("sa_family", sa_family_t),
|
||||||
("sa_data", c_char * 14),
|
("sa_data", c_char * 14),
|
||||||
]
|
)
|
||||||
|
|
||||||
|
|
||||||
# --- glibc/inet/netinet/in.h ---
|
# --- glibc/inet/netinet/in.h ---
|
||||||
|
@ -45,34 +45,30 @@ in_addr_t = c_uint32
|
||||||
|
|
||||||
|
|
||||||
class in_addr(Structure):
|
class in_addr(Structure):
|
||||||
_fields_ = [
|
_fields_ = (("s_addr", in_addr_t),)
|
||||||
("s_addr", in_addr_t),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class sockaddr_in(Structure):
|
class sockaddr_in(Structure):
|
||||||
_fields_ = [
|
_fields_ = (
|
||||||
("sin_family", sa_family_t),
|
("sin_family", sa_family_t),
|
||||||
("sin_port", in_port_t),
|
("sin_port", in_port_t),
|
||||||
("sin_addr", in_addr),
|
("sin_addr", in_addr),
|
||||||
("sin_zero", c_uint8 * 8),
|
("sin_zero", c_uint8 * 8),
|
||||||
]
|
)
|
||||||
|
|
||||||
|
|
||||||
class in6_addr(Structure):
|
class in6_addr(Structure):
|
||||||
_fields_ = [
|
_fields_ = (("s6_addr", c_uint8 * 16),)
|
||||||
("s6_addr", c_uint8 * 16),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class sockaddr_in6(Structure):
|
class sockaddr_in6(Structure):
|
||||||
_fields_ = [
|
_fields_ = (
|
||||||
("sin6_family", sa_family_t),
|
("sin6_family", sa_family_t),
|
||||||
("sin6_port", in_port_t),
|
("sin6_port", in_port_t),
|
||||||
("sin6_flowinfo", c_uint32),
|
("sin6_flowinfo", c_uint32),
|
||||||
("sin6_addr", in6_addr),
|
("sin6_addr", in6_addr),
|
||||||
("sin6_scope_id", c_uint32),
|
("sin6_scope_id", c_uint32),
|
||||||
]
|
)
|
||||||
|
|
||||||
|
|
||||||
# --- glibc/stdlib/stdlib.h ---
|
# --- glibc/stdlib/stdlib.h ---
|
||||||
|
@ -93,32 +89,32 @@ ZNotice_Kind_t = c_int
|
||||||
|
|
||||||
|
|
||||||
class _ZTimeval(Structure):
|
class _ZTimeval(Structure):
|
||||||
_fields_ = [
|
_fields_ = (
|
||||||
("tv_sec", c_int),
|
("tv_sec", c_int),
|
||||||
("tv_usec", c_int),
|
("tv_usec", c_int),
|
||||||
]
|
)
|
||||||
|
|
||||||
|
|
||||||
class ZUnique_Id_t(Structure):
|
class ZUnique_Id_t(Structure):
|
||||||
_fields_ = [
|
_fields_ = (
|
||||||
("zuid_addr", in_addr),
|
("zuid_addr", in_addr),
|
||||||
("tv", _ZTimeval),
|
("tv", _ZTimeval),
|
||||||
]
|
)
|
||||||
|
|
||||||
|
|
||||||
ZChecksum_t = c_uint
|
ZChecksum_t = c_uint
|
||||||
|
|
||||||
|
|
||||||
class _ZSenderSockaddr(Union):
|
class _ZSenderSockaddr(Union):
|
||||||
_fields_ = [
|
_fields_ = (
|
||||||
("sa", sockaddr),
|
("sa", sockaddr),
|
||||||
("ip4", sockaddr_in),
|
("ip4", sockaddr_in),
|
||||||
("ip6", sockaddr_in6),
|
("ip6", sockaddr_in6),
|
||||||
]
|
)
|
||||||
|
|
||||||
|
|
||||||
class ZNotice_t(Structure):
|
class ZNotice_t(Structure):
|
||||||
_fields_ = [
|
_fields_ = (
|
||||||
("z_packet", c_char_p),
|
("z_packet", c_char_p),
|
||||||
("z_version", c_char_p),
|
("z_version", c_char_p),
|
||||||
("z_kind", ZNotice_Kind_t),
|
("z_kind", ZNotice_Kind_t),
|
||||||
|
@ -147,15 +143,15 @@ class ZNotice_t(Structure):
|
||||||
("z_message_len", c_int),
|
("z_message_len", c_int),
|
||||||
("z_num_hdr_fields", c_uint),
|
("z_num_hdr_fields", c_uint),
|
||||||
("z_hdr_fields", POINTER(c_char_p)),
|
("z_hdr_fields", POINTER(c_char_p)),
|
||||||
]
|
)
|
||||||
|
|
||||||
|
|
||||||
class ZSubscription_t(Structure):
|
class ZSubscription_t(Structure):
|
||||||
_fields_ = [
|
_fields_ = (
|
||||||
("zsub_recipient", c_char_p),
|
("zsub_recipient", c_char_p),
|
||||||
("zsub_class", c_char_p),
|
("zsub_class", c_char_p),
|
||||||
("zsub_classinst", c_char_p),
|
("zsub_classinst", c_char_p),
|
||||||
]
|
)
|
||||||
|
|
||||||
|
|
||||||
Code_t = c_int
|
Code_t = c_int
|
||||||
|
|
|
@ -14,6 +14,7 @@ import tempfile
|
||||||
import textwrap
|
import textwrap
|
||||||
import time
|
import time
|
||||||
from ctypes import POINTER, byref, c_char, c_int, c_ushort
|
from ctypes import POINTER, byref, c_char, c_int, c_ushort
|
||||||
|
from enum import Enum, auto
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
@ -29,8 +30,10 @@ from zulip import RandomExponentialBackoff
|
||||||
DEFAULT_SITE = "https://api.zulip.com"
|
DEFAULT_SITE = "https://api.zulip.com"
|
||||||
|
|
||||||
|
|
||||||
class States:
|
class States(Enum):
|
||||||
Startup, ZulipToZephyr, ZephyrToZulip = list(range(3))
|
Startup = auto()
|
||||||
|
ZulipToZephyr = auto()
|
||||||
|
ZephyrToZulip = auto()
|
||||||
|
|
||||||
|
|
||||||
CURRENT_STATE = States.Startup
|
CURRENT_STATE = States.Startup
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import Final
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from requests.exceptions import ConnectionError
|
from requests.exceptions import ConnectionError
|
||||||
|
@ -8,7 +9,7 @@ from zulip_bots.test_lib import BotTestCase, DefaultTests, StubBotHandler
|
||||||
|
|
||||||
class TestBeeminderBot(BotTestCase, DefaultTests):
|
class TestBeeminderBot(BotTestCase, DefaultTests):
|
||||||
bot_name = "beeminder"
|
bot_name = "beeminder"
|
||||||
normal_config = {"auth_token": "XXXXXX", "username": "aaron", "goalname": "goal"}
|
normal_config: Final = {"auth_token": "XXXXXX", "username": "aaron", "goalname": "goal"}
|
||||||
|
|
||||||
help_message = """
|
help_message = """
|
||||||
You can add datapoints towards your beeminder goals \
|
You can add datapoints towards your beeminder goals \
|
||||||
|
|
|
@ -5,7 +5,7 @@ from zulip_bots.game_handler import GameAdapter
|
||||||
|
|
||||||
|
|
||||||
class ConnectFourMessageHandler:
|
class ConnectFourMessageHandler:
|
||||||
tokens = [":blue_circle:", ":red_circle:"]
|
tokens = (":blue_circle:", ":red_circle:")
|
||||||
|
|
||||||
def parse_board(self, board: Any) -> str:
|
def parse_board(self, board: Any) -> str:
|
||||||
# Header for the top of the board
|
# Header for the top of the board
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Dict, List
|
from typing import Dict, Final, List
|
||||||
|
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ class TestConnectFourBot(BotTestCase, DefaultTests):
|
||||||
The first player to get 4 in a row wins!\n Good Luck!",
|
The first player to get 4 in a row wins!\n Good Luck!",
|
||||||
)
|
)
|
||||||
|
|
||||||
blank_board = [
|
blank_board: Final = [
|
||||||
[0, 0, 0, 0, 0, 0, 0],
|
[0, 0, 0, 0, 0, 0, 0],
|
||||||
[0, 0, 0, 0, 0, 0, 0],
|
[0, 0, 0, 0, 0, 0, 0],
|
||||||
[0, 0, 0, 0, 0, 0, 0],
|
[0, 0, 0, 0, 0, 0, 0],
|
||||||
|
@ -108,7 +108,7 @@ The first player to get 4 in a row wins!\n Good Luck!",
|
||||||
[0, 0, 0, 0, 0, 0, 0],
|
[0, 0, 0, 0, 0, 0, 0],
|
||||||
]
|
]
|
||||||
|
|
||||||
almost_win_board = [
|
almost_win_board: Final = [
|
||||||
[0, 0, 0, 0, 0, 0, 0],
|
[0, 0, 0, 0, 0, 0, 0],
|
||||||
[0, 0, 0, 0, 0, 0, 0],
|
[0, 0, 0, 0, 0, 0, 0],
|
||||||
[0, 0, 0, 0, 0, 0, 0],
|
[0, 0, 0, 0, 0, 0, 0],
|
||||||
|
@ -117,7 +117,7 @@ The first player to get 4 in a row wins!\n Good Luck!",
|
||||||
[1, -1, 0, 0, 0, 0, 0],
|
[1, -1, 0, 0, 0, 0, 0],
|
||||||
]
|
]
|
||||||
|
|
||||||
almost_draw_board = [
|
almost_draw_board: Final = [
|
||||||
[1, -1, 1, -1, 1, -1, 0],
|
[1, -1, 1, -1, 1, -1, 0],
|
||||||
[0, 0, 0, 0, 0, 0, 1],
|
[0, 0, 0, 0, 0, 0, 1],
|
||||||
[0, 0, 0, 0, 0, 0, -1],
|
[0, 0, 0, 0, 0, 0, -1],
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import Final
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from zulip_bots.bots.dropbox_share.test_util import (
|
from zulip_bots.bots.dropbox_share.test_util import (
|
||||||
|
@ -75,7 +76,7 @@ def get_help() -> str:
|
||||||
|
|
||||||
class TestDropboxBot(BotTestCase, DefaultTests):
|
class TestDropboxBot(BotTestCase, DefaultTests):
|
||||||
bot_name = "dropbox_share"
|
bot_name = "dropbox_share"
|
||||||
config_info = {"access_token": "1234567890"}
|
config_info: Final = {"access_token": "1234567890"}
|
||||||
|
|
||||||
def test_bot_responds_to_empty_message(self):
|
def test_bot_responds_to_empty_message(self):
|
||||||
with self.mock_config_info(self.config_info):
|
with self.mock_config_info(self.config_info):
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import Final
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from requests.exceptions import ConnectionError
|
from requests.exceptions import ConnectionError
|
||||||
|
@ -7,9 +8,9 @@ from zulip_bots.test_lib import BotTestCase, DefaultTests
|
||||||
|
|
||||||
class TestFlockBot(BotTestCase, DefaultTests):
|
class TestFlockBot(BotTestCase, DefaultTests):
|
||||||
bot_name = "flock"
|
bot_name = "flock"
|
||||||
normal_config = {"token": "12345"}
|
normal_config: Final = {"token": "12345"}
|
||||||
|
|
||||||
message_config = {"token": "12345", "text": "Ricky: test message", "to": "u:somekey"}
|
message_config: Final = {"token": "12345", "text": "Ricky: test message", "to": "u:somekey"}
|
||||||
|
|
||||||
help_message = """
|
help_message = """
|
||||||
You can send messages to any Flock user associated with your account from Zulip.
|
You can send messages to any Flock user associated with your account from Zulip.
|
||||||
|
|
|
@ -8,13 +8,13 @@ from zulip_bots.lib import BotHandler
|
||||||
|
|
||||||
class FrontHandler:
|
class FrontHandler:
|
||||||
FRONT_API = "https://api2.frontapp.com/conversations/{}"
|
FRONT_API = "https://api2.frontapp.com/conversations/{}"
|
||||||
COMMANDS = [
|
COMMANDS = (
|
||||||
("archive", "Archive a conversation."),
|
("archive", "Archive a conversation."),
|
||||||
("delete", "Delete a conversation."),
|
("delete", "Delete a conversation."),
|
||||||
("spam", "Mark a conversation as spam."),
|
("spam", "Mark a conversation as spam."),
|
||||||
("open", "Restore a conversation."),
|
("open", "Restore a conversation."),
|
||||||
("comment <text>", "Leave a comment."),
|
("comment <text>", "Leave a comment."),
|
||||||
]
|
)
|
||||||
CNV_ID_REGEXP = "cnv_(?P<id>[0-9a-z]+)"
|
CNV_ID_REGEXP = "cnv_(?P<id>[0-9a-z]+)"
|
||||||
COMMENT_PREFIX = "comment "
|
COMMENT_PREFIX = "comment "
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from zulip_bots.game_handler import BadMoveError, GameAdapter
|
||||||
|
|
||||||
|
|
||||||
class GameHandlerBotMessageHandler:
|
class GameHandlerBotMessageHandler:
|
||||||
tokens = [":blue_circle:", ":red_circle:"]
|
tokens = (":blue_circle:", ":red_circle:")
|
||||||
|
|
||||||
def parse_board(self, board: Any) -> str:
|
def parse_board(self, board: Any) -> str:
|
||||||
return "foo"
|
return "foo"
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import copy
|
import copy
|
||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, Final, List, Tuple
|
||||||
|
|
||||||
from zulip_bots.game_handler import BadMoveError, GameAdapter
|
from zulip_bots.game_handler import BadMoveError, GameAdapter
|
||||||
|
|
||||||
|
|
||||||
class GameOfFifteenModel:
|
class GameOfFifteenModel:
|
||||||
final_board = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
|
final_board: Final = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
|
||||||
|
|
||||||
initial_board = [[8, 7, 6], [5, 4, 3], [2, 1, 0]]
|
initial_board: Final = [[8, 7, 6], [5, 4, 3], [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:
|
||||||
|
@ -81,7 +81,7 @@ class GameOfFifteenModel:
|
||||||
|
|
||||||
|
|
||||||
class GameOfFifteenMessageHandler:
|
class GameOfFifteenMessageHandler:
|
||||||
tiles = {
|
tiles: Final = {
|
||||||
"0": ":grey_question:",
|
"0": ":grey_question:",
|
||||||
"1": ":one:",
|
"1": ":one:",
|
||||||
"2": ":two:",
|
"2": ":two:",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Dict, List, Tuple
|
from typing import Dict, Final, List, Tuple
|
||||||
|
|
||||||
from zulip_bots.bots.game_of_fifteen.game_of_fifteen import GameOfFifteenModel
|
from zulip_bots.bots.game_of_fifteen.game_of_fifteen import GameOfFifteenModel
|
||||||
from zulip_bots.game_handler import BadMoveError
|
from zulip_bots.game_handler import BadMoveError
|
||||||
|
@ -68,7 +68,7 @@ class TestGameOfFifteenBot(BotTestCase, DefaultTests):
|
||||||
"To make a move, type @-mention `move <tile1> <tile2> ...`",
|
"To make a move, type @-mention `move <tile1> <tile2> ...`",
|
||||||
)
|
)
|
||||||
|
|
||||||
winning_board = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
|
winning_board: Final = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
|
||||||
|
|
||||||
def test_game_of_fifteen_logic(self) -> None:
|
def test_game_of_fifteen_logic(self) -> None:
|
||||||
def confirm_available_moves(
|
def confirm_available_moves(
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from typing import Final
|
||||||
|
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
|
||||||
from zulip_bots.test_file_utils import get_bot_message_handler
|
from zulip_bots.test_file_utils import get_bot_message_handler
|
||||||
|
@ -6,8 +8,8 @@ from zulip_bots.test_lib import BotTestCase, DefaultTests, StubBotHandler
|
||||||
|
|
||||||
class TestGithubDetailBot(BotTestCase, DefaultTests):
|
class TestGithubDetailBot(BotTestCase, DefaultTests):
|
||||||
bot_name = "github_detail"
|
bot_name = "github_detail"
|
||||||
mock_config = {"owner": "zulip", "repo": "zulip"}
|
mock_config: Final = {"owner": "zulip", "repo": "zulip"}
|
||||||
empty_config = {"owner": "", "repo": ""}
|
empty_config: Final = {"owner": "", "repo": ""}
|
||||||
|
|
||||||
# Overrides default test_bot_usage().
|
# Overrides default test_bot_usage().
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# See readme.md for instructions on running this code.
|
# See readme.md for instructions on running this code.
|
||||||
|
|
||||||
from typing import Dict
|
from typing import Dict, Final
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler, use_storage
|
from zulip_bots.lib import BotHandler, use_storage
|
||||||
|
|
||||||
|
|
||||||
class IncrementorHandler:
|
class IncrementorHandler:
|
||||||
META = {
|
META: Final = {
|
||||||
"name": "Incrementor",
|
"name": "Incrementor",
|
||||||
"description": "Example bot to test the update_message() function.",
|
"description": "Example bot to test the update_message() function.",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
|
from typing import Final
|
||||||
|
|
||||||
from zulip_bots.test_lib import BotTestCase, DefaultTests
|
from zulip_bots.test_lib import BotTestCase, DefaultTests
|
||||||
|
|
||||||
|
|
||||||
class TestJiraBot(BotTestCase, DefaultTests):
|
class TestJiraBot(BotTestCase, DefaultTests):
|
||||||
bot_name = "jira"
|
bot_name = "jira"
|
||||||
|
|
||||||
MOCK_CONFIG_INFO = {
|
MOCK_CONFIG_INFO: Final = {
|
||||||
"username": "example@example.com",
|
"username": "example@example.com",
|
||||||
"password": "qwerty!123",
|
"password": "qwerty!123",
|
||||||
"domain": "example.atlassian.net",
|
"domain": "example.atlassian.net",
|
||||||
}
|
}
|
||||||
|
|
||||||
MOCK_SCHEME_CONFIG_INFO = {
|
MOCK_SCHEME_CONFIG_INFO: Final = {
|
||||||
"username": "example@example.com",
|
"username": "example@example.com",
|
||||||
"password": "qwerty!123",
|
"password": "qwerty!123",
|
||||||
"domain": "http://example.atlassian.net",
|
"domain": "http://example.atlassian.net",
|
||||||
}
|
}
|
||||||
|
|
||||||
MOCK_DISPLAY_CONFIG_INFO = {
|
MOCK_DISPLAY_CONFIG_INFO: Final = {
|
||||||
"username": "example@example.com",
|
"username": "example@example.com",
|
||||||
"password": "qwerty!123",
|
"password": "qwerty!123",
|
||||||
"domain": "example.atlassian.net",
|
"domain": "example.atlassian.net",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, List
|
from typing import Any, Final, List
|
||||||
|
|
||||||
from zulip_bots.game_handler import GameAdapter, SamePlayerMoveError
|
from zulip_bots.game_handler import GameAdapter, SamePlayerMoveError
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class MerelsModel:
|
||||||
|
|
||||||
|
|
||||||
class MerelsMessageHandler:
|
class MerelsMessageHandler:
|
||||||
tokens = [":o_button:", ":cross_mark_button:"]
|
tokens = (":o_button:", ":cross_mark_button:")
|
||||||
|
|
||||||
def parse_board(self, board: Any) -> str:
|
def parse_board(self, board: Any) -> str:
|
||||||
return board
|
return board
|
||||||
|
@ -73,7 +73,7 @@ class MerelsHandler(GameAdapter):
|
||||||
"@mention-bot".
|
"@mention-bot".
|
||||||
"""
|
"""
|
||||||
|
|
||||||
META = {
|
META: Final = {
|
||||||
"name": "merels",
|
"name": "merels",
|
||||||
"description": "Lets you play merels against any player.",
|
"description": "Lets you play merels against any player.",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Final, Optional
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class StackOverflowHandler:
|
||||||
the same stream that it was called from.
|
the same stream that it was called from.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
META = {
|
META: Final = {
|
||||||
"name": "StackOverflow",
|
"name": "StackOverflow",
|
||||||
"description": "Searches Stack Overflow for a query and returns the top 3 articles.",
|
"description": "Searches Stack Overflow for a query and returns the top 3 articles.",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import copy
|
import copy
|
||||||
import random
|
import random
|
||||||
from typing import Any, List, Tuple
|
from typing import Any, Final, List, Tuple
|
||||||
|
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ class TicTacToeModel:
|
||||||
smarter = True
|
smarter = True
|
||||||
# If smarter is True, the computer will do some extra thinking - it'll be harder for the user.
|
# If smarter is True, the computer will do some extra thinking - it'll be harder for the user.
|
||||||
|
|
||||||
triplets = [
|
triplets: Final = [
|
||||||
[(0, 0), (0, 1), (0, 2)], # Row 1
|
[(0, 0), (0, 1), (0, 2)], # Row 1
|
||||||
[(1, 0), (1, 1), (1, 2)], # Row 2
|
[(1, 0), (1, 1), (1, 2)], # Row 2
|
||||||
[(2, 0), (2, 1), (2, 2)], # Row 3
|
[(2, 0), (2, 1), (2, 2)], # Row 3
|
||||||
|
@ -26,7 +26,7 @@ class TicTacToeModel:
|
||||||
[(0, 2), (1, 1), (2, 0)], # Diagonal 2
|
[(0, 2), (1, 1), (2, 0)], # Diagonal 2
|
||||||
]
|
]
|
||||||
|
|
||||||
initial_board = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
|
initial_board: Final = [[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:
|
||||||
|
@ -203,7 +203,7 @@ class TicTacToeModel:
|
||||||
|
|
||||||
|
|
||||||
class TicTacToeMessageHandler:
|
class TicTacToeMessageHandler:
|
||||||
tokens = [":x:", ":o:"]
|
tokens = (":x:", ":o:")
|
||||||
|
|
||||||
def parse_row(self, row: Tuple[int, int], row_num: int) -> str:
|
def parse_row(self, row: Tuple[int, int], row_num: int) -> str:
|
||||||
"""Takes the row passed in as a list and returns it as a string."""
|
"""Takes the row passed in as a list and returns it as a string."""
|
||||||
|
@ -248,7 +248,7 @@ class TicTacToeHandler(GameAdapter):
|
||||||
"@mention-bot".
|
"@mention-bot".
|
||||||
"""
|
"""
|
||||||
|
|
||||||
META = {
|
META: Final = {
|
||||||
"name": "TicTacToe",
|
"name": "TicTacToe",
|
||||||
"description": "Lets you play Tic-tac-toe against a computer.",
|
"description": "Lets you play Tic-tac-toe against a computer.",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import Final
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from zulip_bots.test_file_utils import get_bot_message_handler, read_bot_fixture_data
|
from zulip_bots.test_file_utils import get_bot_message_handler, read_bot_fixture_data
|
||||||
|
@ -6,7 +7,7 @@ from zulip_bots.test_lib import BotTestCase, DefaultTests, StubBotHandler
|
||||||
|
|
||||||
class TestTwitpostBot(BotTestCase, DefaultTests):
|
class TestTwitpostBot(BotTestCase, DefaultTests):
|
||||||
bot_name = "twitpost"
|
bot_name = "twitpost"
|
||||||
mock_config = {
|
mock_config: Final = {
|
||||||
"consumer_key": "abcdefghijklmnopqrstuvwxy",
|
"consumer_key": "abcdefghijklmnopqrstuvwxy",
|
||||||
"consumer_secret": "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyy",
|
"consumer_secret": "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyy",
|
||||||
"access_token": "123456789012345678-ABCDefgh1234afdsa678lKj6gHhslsi",
|
"access_token": "123456789012345678-ABCDefgh1234afdsa678lKj6gHhslsi",
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from typing import Any, Dict, List, Set, Tuple, Union
|
from typing import Any, Dict, Final, List, Set, Tuple, Union
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import BotHandler
|
||||||
|
|
||||||
|
|
||||||
class VirtualFsHandler:
|
class VirtualFsHandler:
|
||||||
META = {
|
META: Final = {
|
||||||
"name": "VirtualFs",
|
"name": "VirtualFs",
|
||||||
"description": "Provides a simple, permanent file system to store and retrieve strings.",
|
"description": "Provides a simple, permanent file system to store and retrieve strings.",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict
|
from typing import Dict, Final
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ class WikipediaHandler:
|
||||||
kind of external issue tracker as well.
|
kind of external issue tracker as well.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
META = {
|
META: Final = {
|
||||||
"name": "Wikipedia",
|
"name": "Wikipedia",
|
||||||
"description": "Searches Wikipedia for a term and returns the top 3 articles.",
|
"description": "Searches Wikipedia for a term and returns the top 3 articles.",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Final, Optional
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
@ -10,13 +10,13 @@ from zulip_bots.test_lib import BotTestCase, DefaultTests, StubBotHandler
|
||||||
class TestWitaiBot(BotTestCase, DefaultTests):
|
class TestWitaiBot(BotTestCase, DefaultTests):
|
||||||
bot_name = "witai"
|
bot_name = "witai"
|
||||||
|
|
||||||
MOCK_CONFIG_INFO = {
|
MOCK_CONFIG_INFO: Final = {
|
||||||
"token": "12345678",
|
"token": "12345678",
|
||||||
"handler_location": "/Users/abcd/efgh",
|
"handler_location": "/Users/abcd/efgh",
|
||||||
"help_message": "Qwertyuiop!",
|
"help_message": "Qwertyuiop!",
|
||||||
}
|
}
|
||||||
|
|
||||||
MOCK_WITAI_RESPONSE = {
|
MOCK_WITAI_RESPONSE: Final = {
|
||||||
"_text": "What is your favorite food?",
|
"_text": "What is your favorite food?",
|
||||||
"entities": {"intent": [{"confidence": 1.0, "value": "favorite_food"}]},
|
"entities": {"intent": [{"confidence": 1.0, "value": "favorite_food"}]},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Final, Optional
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class XkcdHandler:
|
||||||
commands.
|
commands.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
META = {
|
META: Final = {
|
||||||
"name": "XKCD",
|
"name": "XKCD",
|
||||||
"description": "Fetches comic strips from https://xkcd.com.",
|
"description": "Fetches comic strips from https://xkcd.com.",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Dict
|
from typing import Dict, Final
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from requests.exceptions import ConnectionError, HTTPError
|
from requests.exceptions import ConnectionError, HTTPError
|
||||||
|
@ -10,7 +10,7 @@ from zulip_bots.test_lib import BotTestCase, DefaultTests, StubBotHandler
|
||||||
|
|
||||||
class TestYoutubeBot(BotTestCase, DefaultTests):
|
class TestYoutubeBot(BotTestCase, DefaultTests):
|
||||||
bot_name = "youtube"
|
bot_name = "youtube"
|
||||||
normal_config: Dict[str, str] = {
|
normal_config: Final[Dict[str, str]] = {
|
||||||
"key": "12345678",
|
"key": "12345678",
|
||||||
"number_of_results": "5",
|
"number_of_results": "5",
|
||||||
"video_region": "US",
|
"video_region": "US",
|
||||||
|
|
Loading…
Add table
Reference in a new issue