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 concurrent.futures import ThreadPoolExecutor
|
||||
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
|
||||
from nio.responses import (
|
||||
|
@ -52,7 +52,7 @@ class MatrixToZulip:
|
|||
Matrix -> Zulip
|
||||
"""
|
||||
|
||||
non_formatted_messages: Dict[Type[nio.Event], str] = {
|
||||
non_formatted_messages: ClassVar[Dict[Type[nio.Event], str]] = {
|
||||
nio.StickerEvent: "sticker",
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import sys
|
|||
from contextlib import contextmanager
|
||||
from subprocess import PIPE, Popen
|
||||
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
|
||||
|
||||
import nio
|
||||
|
@ -209,13 +209,13 @@ class MatrixBridgeMatrixToZulipTests(TestCase):
|
|||
|
||||
class MatrixBridgeZulipToMatrixTests(TestCase):
|
||||
room = mock.MagicMock()
|
||||
valid_zulip_config = dict(
|
||||
valid_zulip_config: Final = dict(
|
||||
stream="some stream",
|
||||
topic="some topic",
|
||||
email="some@email",
|
||||
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_id=42,
|
||||
type="stream", # Can only mirror Zulip streams
|
||||
|
|
|
@ -32,10 +32,10 @@ sa_family_t = c_ushort
|
|||
|
||||
|
||||
class sockaddr(Structure):
|
||||
_fields_ = [
|
||||
_fields_ = (
|
||||
("sa_family", sa_family_t),
|
||||
("sa_data", c_char * 14),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# --- glibc/inet/netinet/in.h ---
|
||||
|
@ -45,34 +45,30 @@ in_addr_t = c_uint32
|
|||
|
||||
|
||||
class in_addr(Structure):
|
||||
_fields_ = [
|
||||
("s_addr", in_addr_t),
|
||||
]
|
||||
_fields_ = (("s_addr", in_addr_t),)
|
||||
|
||||
|
||||
class sockaddr_in(Structure):
|
||||
_fields_ = [
|
||||
_fields_ = (
|
||||
("sin_family", sa_family_t),
|
||||
("sin_port", in_port_t),
|
||||
("sin_addr", in_addr),
|
||||
("sin_zero", c_uint8 * 8),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class in6_addr(Structure):
|
||||
_fields_ = [
|
||||
("s6_addr", c_uint8 * 16),
|
||||
]
|
||||
_fields_ = (("s6_addr", c_uint8 * 16),)
|
||||
|
||||
|
||||
class sockaddr_in6(Structure):
|
||||
_fields_ = [
|
||||
_fields_ = (
|
||||
("sin6_family", sa_family_t),
|
||||
("sin6_port", in_port_t),
|
||||
("sin6_flowinfo", c_uint32),
|
||||
("sin6_addr", in6_addr),
|
||||
("sin6_scope_id", c_uint32),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# --- glibc/stdlib/stdlib.h ---
|
||||
|
@ -93,32 +89,32 @@ ZNotice_Kind_t = c_int
|
|||
|
||||
|
||||
class _ZTimeval(Structure):
|
||||
_fields_ = [
|
||||
_fields_ = (
|
||||
("tv_sec", c_int),
|
||||
("tv_usec", c_int),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class ZUnique_Id_t(Structure):
|
||||
_fields_ = [
|
||||
_fields_ = (
|
||||
("zuid_addr", in_addr),
|
||||
("tv", _ZTimeval),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
ZChecksum_t = c_uint
|
||||
|
||||
|
||||
class _ZSenderSockaddr(Union):
|
||||
_fields_ = [
|
||||
_fields_ = (
|
||||
("sa", sockaddr),
|
||||
("ip4", sockaddr_in),
|
||||
("ip6", sockaddr_in6),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class ZNotice_t(Structure):
|
||||
_fields_ = [
|
||||
_fields_ = (
|
||||
("z_packet", c_char_p),
|
||||
("z_version", c_char_p),
|
||||
("z_kind", ZNotice_Kind_t),
|
||||
|
@ -147,15 +143,15 @@ class ZNotice_t(Structure):
|
|||
("z_message_len", c_int),
|
||||
("z_num_hdr_fields", c_uint),
|
||||
("z_hdr_fields", POINTER(c_char_p)),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class ZSubscription_t(Structure):
|
||||
_fields_ = [
|
||||
_fields_ = (
|
||||
("zsub_recipient", c_char_p),
|
||||
("zsub_class", c_char_p),
|
||||
("zsub_classinst", c_char_p),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
Code_t = c_int
|
||||
|
|
|
@ -14,6 +14,7 @@ import tempfile
|
|||
import textwrap
|
||||
import time
|
||||
from ctypes import POINTER, byref, c_char, c_int, c_ushort
|
||||
from enum import Enum, auto
|
||||
from pathlib import Path
|
||||
from queue import Queue
|
||||
from threading import Thread
|
||||
|
@ -29,8 +30,10 @@ from zulip import RandomExponentialBackoff
|
|||
DEFAULT_SITE = "https://api.zulip.com"
|
||||
|
||||
|
||||
class States:
|
||||
Startup, ZulipToZephyr, ZephyrToZulip = list(range(3))
|
||||
class States(Enum):
|
||||
Startup = auto()
|
||||
ZulipToZephyr = auto()
|
||||
ZephyrToZulip = auto()
|
||||
|
||||
|
||||
CURRENT_STATE = States.Startup
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from typing import Final
|
||||
from unittest.mock import patch
|
||||
|
||||
from requests.exceptions import ConnectionError
|
||||
|
@ -8,7 +9,7 @@ from zulip_bots.test_lib import BotTestCase, DefaultTests, StubBotHandler
|
|||
|
||||
class TestBeeminderBot(BotTestCase, DefaultTests):
|
||||
bot_name = "beeminder"
|
||||
normal_config = {"auth_token": "XXXXXX", "username": "aaron", "goalname": "goal"}
|
||||
normal_config: Final = {"auth_token": "XXXXXX", "username": "aaron", "goalname": "goal"}
|
||||
|
||||
help_message = """
|
||||
You can add datapoints towards your beeminder goals \
|
||||
|
|
|
@ -5,7 +5,7 @@ from zulip_bots.game_handler import GameAdapter
|
|||
|
||||
|
||||
class ConnectFourMessageHandler:
|
||||
tokens = [":blue_circle:", ":red_circle:"]
|
||||
tokens = (":blue_circle:", ":red_circle:")
|
||||
|
||||
def parse_board(self, board: Any) -> str:
|
||||
# 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
|
||||
|
||||
|
@ -99,7 +99,7 @@ class TestConnectFourBot(BotTestCase, DefaultTests):
|
|||
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],
|
||||
|
@ -108,7 +108,7 @@ The first player to get 4 in a row wins!\n Good Luck!",
|
|||
[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],
|
||||
|
@ -117,7 +117,7 @@ The first player to get 4 in a row wins!\n Good Luck!",
|
|||
[1, -1, 0, 0, 0, 0, 0],
|
||||
]
|
||||
|
||||
almost_draw_board = [
|
||||
almost_draw_board: Final = [
|
||||
[1, -1, 1, -1, 1, -1, 0],
|
||||
[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 zulip_bots.bots.dropbox_share.test_util import (
|
||||
|
@ -75,7 +76,7 @@ def get_help() -> str:
|
|||
|
||||
class TestDropboxBot(BotTestCase, DefaultTests):
|
||||
bot_name = "dropbox_share"
|
||||
config_info = {"access_token": "1234567890"}
|
||||
config_info: Final = {"access_token": "1234567890"}
|
||||
|
||||
def test_bot_responds_to_empty_message(self):
|
||||
with self.mock_config_info(self.config_info):
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from typing import Final
|
||||
from unittest.mock import patch
|
||||
|
||||
from requests.exceptions import ConnectionError
|
||||
|
@ -7,9 +8,9 @@ from zulip_bots.test_lib import BotTestCase, DefaultTests
|
|||
|
||||
class TestFlockBot(BotTestCase, DefaultTests):
|
||||
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 = """
|
||||
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:
|
||||
FRONT_API = "https://api2.frontapp.com/conversations/{}"
|
||||
COMMANDS = [
|
||||
COMMANDS = (
|
||||
("archive", "Archive a conversation."),
|
||||
("delete", "Delete a conversation."),
|
||||
("spam", "Mark a conversation as spam."),
|
||||
("open", "Restore a conversation."),
|
||||
("comment <text>", "Leave a comment."),
|
||||
]
|
||||
)
|
||||
CNV_ID_REGEXP = "cnv_(?P<id>[0-9a-z]+)"
|
||||
COMMENT_PREFIX = "comment "
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ from zulip_bots.game_handler import BadMoveError, GameAdapter
|
|||
|
||||
|
||||
class GameHandlerBotMessageHandler:
|
||||
tokens = [":blue_circle:", ":red_circle:"]
|
||||
tokens = (":blue_circle:", ":red_circle:")
|
||||
|
||||
def parse_board(self, board: Any) -> str:
|
||||
return "foo"
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
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
|
||||
|
||||
|
||||
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:
|
||||
if board is not None:
|
||||
|
@ -81,7 +81,7 @@ class GameOfFifteenModel:
|
|||
|
||||
|
||||
class GameOfFifteenMessageHandler:
|
||||
tiles = {
|
||||
tiles: Final = {
|
||||
"0": ":grey_question:",
|
||||
"1": ":one:",
|
||||
"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.game_handler import BadMoveError
|
||||
|
@ -68,7 +68,7 @@ class TestGameOfFifteenBot(BotTestCase, DefaultTests):
|
|||
"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 confirm_available_moves(
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from typing import Final
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
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):
|
||||
bot_name = "github_detail"
|
||||
mock_config = {"owner": "zulip", "repo": "zulip"}
|
||||
empty_config = {"owner": "", "repo": ""}
|
||||
mock_config: Final = {"owner": "zulip", "repo": "zulip"}
|
||||
empty_config: Final = {"owner": "", "repo": ""}
|
||||
|
||||
# Overrides default test_bot_usage().
|
||||
@override
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# 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
|
||||
|
||||
|
||||
class IncrementorHandler:
|
||||
META = {
|
||||
META: Final = {
|
||||
"name": "Incrementor",
|
||||
"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
|
||||
|
||||
|
||||
class TestJiraBot(BotTestCase, DefaultTests):
|
||||
bot_name = "jira"
|
||||
|
||||
MOCK_CONFIG_INFO = {
|
||||
MOCK_CONFIG_INFO: Final = {
|
||||
"username": "example@example.com",
|
||||
"password": "qwerty!123",
|
||||
"domain": "example.atlassian.net",
|
||||
}
|
||||
|
||||
MOCK_SCHEME_CONFIG_INFO = {
|
||||
MOCK_SCHEME_CONFIG_INFO: Final = {
|
||||
"username": "example@example.com",
|
||||
"password": "qwerty!123",
|
||||
"domain": "http://example.atlassian.net",
|
||||
}
|
||||
|
||||
MOCK_DISPLAY_CONFIG_INFO = {
|
||||
MOCK_DISPLAY_CONFIG_INFO: Final = {
|
||||
"username": "example@example.com",
|
||||
"password": "qwerty!123",
|
||||
"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
|
||||
|
||||
|
@ -52,7 +52,7 @@ class MerelsModel:
|
|||
|
||||
|
||||
class MerelsMessageHandler:
|
||||
tokens = [":o_button:", ":cross_mark_button:"]
|
||||
tokens = (":o_button:", ":cross_mark_button:")
|
||||
|
||||
def parse_board(self, board: Any) -> str:
|
||||
return board
|
||||
|
@ -73,7 +73,7 @@ class MerelsHandler(GameAdapter):
|
|||
"@mention-bot".
|
||||
"""
|
||||
|
||||
META = {
|
||||
META: Final = {
|
||||
"name": "merels",
|
||||
"description": "Lets you play merels against any player.",
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import logging
|
||||
from typing import Dict, Optional
|
||||
from typing import Dict, Final, Optional
|
||||
|
||||
import requests
|
||||
|
||||
|
@ -18,7 +18,7 @@ class StackOverflowHandler:
|
|||
the same stream that it was called from.
|
||||
"""
|
||||
|
||||
META = {
|
||||
META: Final = {
|
||||
"name": "StackOverflow",
|
||||
"description": "Searches Stack Overflow for a query and returns the top 3 articles.",
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import copy
|
||||
import random
|
||||
from typing import Any, List, Tuple
|
||||
from typing import Any, Final, List, Tuple
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
|
@ -15,7 +15,7 @@ class TicTacToeModel:
|
|||
smarter = True
|
||||
# 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
|
||||
[(1, 0), (1, 1), (1, 2)], # Row 2
|
||||
[(2, 0), (2, 1), (2, 2)], # Row 3
|
||||
|
@ -26,7 +26,7 @@ class TicTacToeModel:
|
|||
[(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:
|
||||
if board is not None:
|
||||
|
@ -203,7 +203,7 @@ class TicTacToeModel:
|
|||
|
||||
|
||||
class TicTacToeMessageHandler:
|
||||
tokens = [":x:", ":o:"]
|
||||
tokens = (":x:", ":o:")
|
||||
|
||||
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."""
|
||||
|
@ -248,7 +248,7 @@ class TicTacToeHandler(GameAdapter):
|
|||
"@mention-bot".
|
||||
"""
|
||||
|
||||
META = {
|
||||
META: Final = {
|
||||
"name": "TicTacToe",
|
||||
"description": "Lets you play Tic-tac-toe against a computer.",
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from typing import Final
|
||||
from unittest.mock import patch
|
||||
|
||||
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):
|
||||
bot_name = "twitpost"
|
||||
mock_config = {
|
||||
mock_config: Final = {
|
||||
"consumer_key": "abcdefghijklmnopqrstuvwxy",
|
||||
"consumer_secret": "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyy",
|
||||
"access_token": "123456789012345678-ABCDefgh1234afdsa678lKj6gHhslsi",
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
import os
|
||||
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
|
||||
|
||||
|
||||
class VirtualFsHandler:
|
||||
META = {
|
||||
META: Final = {
|
||||
"name": "VirtualFs",
|
||||
"description": "Provides a simple, permanent file system to store and retrieve strings.",
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import logging
|
||||
from typing import Dict
|
||||
from typing import Dict, Final
|
||||
|
||||
import requests
|
||||
|
||||
|
@ -20,7 +20,7 @@ class WikipediaHandler:
|
|||
kind of external issue tracker as well.
|
||||
"""
|
||||
|
||||
META = {
|
||||
META: Final = {
|
||||
"name": "Wikipedia",
|
||||
"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 typing_extensions import override
|
||||
|
@ -10,13 +10,13 @@ from zulip_bots.test_lib import BotTestCase, DefaultTests, StubBotHandler
|
|||
class TestWitaiBot(BotTestCase, DefaultTests):
|
||||
bot_name = "witai"
|
||||
|
||||
MOCK_CONFIG_INFO = {
|
||||
MOCK_CONFIG_INFO: Final = {
|
||||
"token": "12345678",
|
||||
"handler_location": "/Users/abcd/efgh",
|
||||
"help_message": "Qwertyuiop!",
|
||||
}
|
||||
|
||||
MOCK_WITAI_RESPONSE = {
|
||||
MOCK_WITAI_RESPONSE: Final = {
|
||||
"_text": "What is your favorite food?",
|
||||
"entities": {"intent": [{"confidence": 1.0, "value": "favorite_food"}]},
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import logging
|
||||
import random
|
||||
from typing import Dict, Optional
|
||||
from typing import Dict, Final, Optional
|
||||
|
||||
import requests
|
||||
|
||||
|
@ -18,7 +18,7 @@ class XkcdHandler:
|
|||
commands.
|
||||
"""
|
||||
|
||||
META = {
|
||||
META: Final = {
|
||||
"name": "XKCD",
|
||||
"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 requests.exceptions import ConnectionError, HTTPError
|
||||
|
@ -10,7 +10,7 @@ from zulip_bots.test_lib import BotTestCase, DefaultTests, StubBotHandler
|
|||
|
||||
class TestYoutubeBot(BotTestCase, DefaultTests):
|
||||
bot_name = "youtube"
|
||||
normal_config: Dict[str, str] = {
|
||||
normal_config: Final[Dict[str, str]] = {
|
||||
"key": "12345678",
|
||||
"number_of_results": "5",
|
||||
"video_region": "US",
|
||||
|
|
Loading…
Add table
Reference in a new issue