ruff: Enable lots of rules.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
e942cceba0
commit
aeb89bcae5
20 changed files with 81 additions and 35 deletions
|
@ -94,14 +94,60 @@ pythonpath = [
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
select = [
|
select = [
|
||||||
|
"B", # bugbear
|
||||||
|
"C4", # comprehensions
|
||||||
|
"COM", # trailing comma
|
||||||
|
"DTZ", # naive datetime
|
||||||
"E", # style errors
|
"E", # style errors
|
||||||
|
"EXE", # shebang
|
||||||
"F", # flakes
|
"F", # flakes
|
||||||
|
"FLY", # string formatting
|
||||||
|
"G", # logging format
|
||||||
"I", # import sorting
|
"I", # import sorting
|
||||||
|
"ICN", # import conventions
|
||||||
|
"INT", # gettext
|
||||||
|
"ISC", # string concatenation
|
||||||
|
"N", # naming
|
||||||
|
"PERF", # performance
|
||||||
|
"PGH", # pygrep-hooks
|
||||||
|
"PIE", # miscellaneous
|
||||||
|
"PL", # pylint
|
||||||
|
"PYI", # typing stubs
|
||||||
|
"Q", # quotes
|
||||||
|
"RSE", # raise
|
||||||
|
"RUF", # Ruff
|
||||||
|
"S", # security
|
||||||
|
"SLF", # self
|
||||||
|
"SLOT", # slots
|
||||||
|
"SIM", # simplify
|
||||||
|
"T10", # debugger
|
||||||
|
"TID", # tidy imports
|
||||||
|
"TRY", # try
|
||||||
|
"UP", # upgrade
|
||||||
|
"W", # style warnings
|
||||||
|
"YTT", # sys.version
|
||||||
]
|
]
|
||||||
ignore = [
|
ignore = [
|
||||||
|
"C408", # Unnecessary `dict` call (rewrite as a literal)
|
||||||
|
"COM812", # Trailing comma missing
|
||||||
"E402", # Module level import not at top of file
|
"E402", # Module level import not at top of file
|
||||||
"E501", # Line too long
|
"E501", # Line too long
|
||||||
"E731", # Do not assign a `lambda` expression, use a `def`
|
"E731", # Do not assign a `lambda` expression, use a `def`
|
||||||
|
"PERF203", # `try`-`except` within a loop incurs performance overhead
|
||||||
|
"PLR0911", # Too many return statements
|
||||||
|
"PLR0912", # Too many branches
|
||||||
|
"PLR0913", # Too many arguments in function definition
|
||||||
|
"PLR0915", # Too many statements
|
||||||
|
"PLR2004", # Magic value used in comparison, consider replacing with a constant variable
|
||||||
|
"RUF001", # String contains ambiguous character
|
||||||
|
"S101", # Use of `assert` detected
|
||||||
|
"S113", # Probable use of requests call without timeout
|
||||||
|
"S603", # `subprocess` call: check for execution of untrusted input
|
||||||
|
"S606", # Starting a process without a shell
|
||||||
|
"S607", # Starting a process with a partial executable path
|
||||||
|
"SIM117", # Use a single `with` statement with multiple contexts instead of nested `with` statements
|
||||||
|
"TRY003", # Avoid specifying long messages outside the exception class
|
||||||
|
"TRY400", # Use `logging.exception` instead of `logging.error`
|
||||||
]
|
]
|
||||||
src = [
|
src = [
|
||||||
"tools",
|
"tools",
|
||||||
|
|
|
@ -112,7 +112,7 @@ def upload(options: argparse.Namespace) -> None:
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(file_path):
|
||||||
print(f"upload: Could not find bot package at {file_path}.")
|
print(f"upload: Could not find bot package at {file_path}.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
files = {"file": open(file_path, "rb")}
|
files = {"file": open(file_path, "rb")} # noqa: SIM115
|
||||||
headers = {"key": options.token}
|
headers = {"key": options.token}
|
||||||
url = urllib.parse.urljoin(options.server, "bots/upload")
|
url = urllib.parse.urljoin(options.server, "bots/upload")
|
||||||
response = requests.post(url, files=files, headers=headers)
|
response = requests.post(url, files=files, headers=headers)
|
||||||
|
|
|
@ -353,7 +353,7 @@ class ZulipToMatrix:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with urllib.request.urlopen(self.server_url + result["url"]) as response:
|
with urllib.request.urlopen(self.server_url + result["url"]) as response: # noqa: S310
|
||||||
file_content: bytes = response.read()
|
file_content: bytes = response.read()
|
||||||
mimetype: str = response.headers.get_content_type()
|
mimetype: str = response.headers.get_content_type()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
@ -14,7 +14,7 @@ flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
|
||||||
SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
|
SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
|
||||||
# This file contains the information that google uses to figure out which application is requesting
|
# This file contains the information that google uses to figure out which application is requesting
|
||||||
# this client's data.
|
# this client's data.
|
||||||
CLIENT_SECRET_FILE = "client_secret.json"
|
CLIENT_SECRET_FILE = "client_secret.json" # noqa: S105
|
||||||
APPLICATION_NAME = "Zulip Calendar Bot"
|
APPLICATION_NAME = "Zulip Calendar Bot"
|
||||||
HOME_DIR = os.path.expanduser("~")
|
HOME_DIR = os.path.expanduser("~")
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ sys.path.append(os.path.join(os.path.dirname(__file__), "../../"))
|
||||||
import zulip
|
import zulip
|
||||||
|
|
||||||
SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
|
SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
|
||||||
CLIENT_SECRET_FILE = "client_secret.json"
|
CLIENT_SECRET_FILE = "client_secret.json" # noqa: S105
|
||||||
APPLICATION_NAME = "Zulip"
|
APPLICATION_NAME = "Zulip"
|
||||||
HOME_DIR = os.path.expanduser("~")
|
HOME_DIR = os.path.expanduser("~")
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ def strip_tags(html: str) -> str:
|
||||||
def compute_entry_hash(entry: Dict[str, Any]) -> str:
|
def compute_entry_hash(entry: Dict[str, Any]) -> str:
|
||||||
entry_time = entry.get("published", entry.get("updated"))
|
entry_time = entry.get("published", entry.get("updated"))
|
||||||
entry_id = entry.get("id", entry.get("link"))
|
entry_id = entry.get("id", entry.get("link"))
|
||||||
return hashlib.md5((entry_id + str(entry_time)).encode()).hexdigest()
|
return hashlib.md5((entry_id + str(entry_time)).encode()).hexdigest() # noqa: S324
|
||||||
|
|
||||||
|
|
||||||
def unwrap_text(body: str) -> str:
|
def unwrap_text(body: str) -> str:
|
||||||
|
|
|
@ -64,7 +64,7 @@ if options.sharded:
|
||||||
for stream, test in test_streams:
|
for stream, test in test_streams:
|
||||||
if stream == "message":
|
if stream == "message":
|
||||||
continue
|
continue
|
||||||
assert hashlib.sha1(stream.encode("utf-8")).hexdigest().startswith(test)
|
assert hashlib.sha1(stream.encode("utf-8")).hexdigest().startswith(test) # noqa: S324
|
||||||
else:
|
else:
|
||||||
test_streams = [
|
test_streams = [
|
||||||
("message", "p"),
|
("message", "p"),
|
||||||
|
|
|
@ -31,7 +31,7 @@ sa_family_t = c_ushort
|
||||||
# --- glibc/sysdeps/unix/sysv/linux/bits/socket.h ---
|
# --- glibc/sysdeps/unix/sysv/linux/bits/socket.h ---
|
||||||
|
|
||||||
|
|
||||||
class sockaddr(Structure):
|
class sockaddr(Structure): # noqa: N801
|
||||||
_fields_ = (
|
_fields_ = (
|
||||||
("sa_family", sa_family_t),
|
("sa_family", sa_family_t),
|
||||||
("sa_data", c_char * 14),
|
("sa_data", c_char * 14),
|
||||||
|
@ -44,11 +44,11 @@ in_port_t = c_uint16
|
||||||
in_addr_t = c_uint32
|
in_addr_t = c_uint32
|
||||||
|
|
||||||
|
|
||||||
class in_addr(Structure):
|
class in_addr(Structure): # noqa: N801
|
||||||
_fields_ = (("s_addr", in_addr_t),)
|
_fields_ = (("s_addr", in_addr_t),)
|
||||||
|
|
||||||
|
|
||||||
class sockaddr_in(Structure):
|
class sockaddr_in(Structure): # noqa: N801
|
||||||
_fields_ = (
|
_fields_ = (
|
||||||
("sin_family", sa_family_t),
|
("sin_family", sa_family_t),
|
||||||
("sin_port", in_port_t),
|
("sin_port", in_port_t),
|
||||||
|
@ -57,11 +57,11 @@ class sockaddr_in(Structure):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class in6_addr(Structure):
|
class in6_addr(Structure): # noqa: N801
|
||||||
_fields_ = (("s6_addr", c_uint8 * 16),)
|
_fields_ = (("s6_addr", c_uint8 * 16),)
|
||||||
|
|
||||||
|
|
||||||
class sockaddr_in6(Structure):
|
class sockaddr_in6(Structure): # noqa: N801
|
||||||
_fields_ = (
|
_fields_ = (
|
||||||
("sin6_family", sa_family_t),
|
("sin6_family", sa_family_t),
|
||||||
("sin6_port", in_port_t),
|
("sin6_port", in_port_t),
|
||||||
|
@ -95,7 +95,7 @@ class _ZTimeval(Structure):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ZUnique_Id_t(Structure):
|
class ZUnique_Id_t(Structure): # noqa: N801
|
||||||
_fields_ = (
|
_fields_ = (
|
||||||
("zuid_addr", in_addr),
|
("zuid_addr", in_addr),
|
||||||
("tv", _ZTimeval),
|
("tv", _ZTimeval),
|
||||||
|
@ -113,7 +113,7 @@ class _ZSenderSockaddr(Union):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ZNotice_t(Structure):
|
class ZNotice_t(Structure): # noqa: N801
|
||||||
_fields_ = (
|
_fields_ = (
|
||||||
("z_packet", c_char_p),
|
("z_packet", c_char_p),
|
||||||
("z_version", c_char_p),
|
("z_version", c_char_p),
|
||||||
|
@ -146,7 +146,7 @@ class ZNotice_t(Structure):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ZSubscription_t(Structure):
|
class ZSubscription_t(Structure): # noqa: N801
|
||||||
_fields_ = (
|
_fields_ = (
|
||||||
("zsub_recipient", c_char_p),
|
("zsub_recipient", c_char_p),
|
||||||
("zsub_class", c_char_p),
|
("zsub_class", c_char_p),
|
||||||
|
|
|
@ -259,7 +259,7 @@ def update_subscriptions() -> None:
|
||||||
classes_to_subscribe = set()
|
classes_to_subscribe = set()
|
||||||
for stream in public_streams:
|
for stream in public_streams:
|
||||||
zephyr_class = stream
|
zephyr_class = stream
|
||||||
if options.shard is not None and not hashlib.sha1(
|
if options.shard is not None and not hashlib.sha1( # noqa: S324
|
||||||
zephyr_class.encode("utf-8")
|
zephyr_class.encode("utf-8")
|
||||||
).hexdigest().startswith(options.shard):
|
).hexdigest().startswith(options.shard):
|
||||||
# This stream is being handled by a different zephyr_mirror job.
|
# This stream is being handled by a different zephyr_mirror job.
|
||||||
|
|
|
@ -128,7 +128,7 @@ class RandomExponentialBackoff(CountingBackoff):
|
||||||
# Exponential growth with ratio sqrt(2); compute random delay
|
# Exponential growth with ratio sqrt(2); compute random delay
|
||||||
# between x and 2x where x is growing exponentially
|
# between x and 2x where x is growing exponentially
|
||||||
delay_scale = int(2 ** (self.number_of_retries / 2.0 - 1)) + 1
|
delay_scale = int(2 ** (self.number_of_retries / 2.0 - 1)) + 1
|
||||||
delay = min(delay_scale + random.randint(1, delay_scale), self.delay_cap)
|
delay = min(delay_scale + random.randint(1, delay_scale), self.delay_cap) # noqa: S311
|
||||||
message = f"Sleeping for {delay}s [max {delay_scale * 2}] before retrying."
|
message = f"Sleeping for {delay}s [max {delay_scale * 2}] before retrying."
|
||||||
try:
|
try:
|
||||||
logger.warning(message)
|
logger.warning(message)
|
||||||
|
|
|
@ -23,7 +23,7 @@ options = parser.parse_args()
|
||||||
client = zulip.init_from_options(options)
|
client = zulip.init_from_options(options)
|
||||||
|
|
||||||
if options.file_path:
|
if options.file_path:
|
||||||
file: IO[Any] = open(options.file_path, "rb")
|
file: IO[Any] = open(options.file_path, "rb") # noqa: SIM115
|
||||||
else:
|
else:
|
||||||
file = StringIO("This is a test file.")
|
file = StringIO("This is a test file.")
|
||||||
file.name = "test.txt"
|
file.name = "test.txt"
|
||||||
|
|
|
@ -148,7 +148,7 @@ More information in my help"""
|
||||||
|
|
||||||
class IDoneThisHandler:
|
class IDoneThisHandler:
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: BotHandler) -> None:
|
||||||
global api_key, default_team
|
global api_key, default_team # noqa: PLW0603
|
||||||
self.config_info = bot_handler.get_config_info("idonethis")
|
self.config_info = bot_handler.get_config_info("idonethis")
|
||||||
if "api_key" in self.config_info:
|
if "api_key" in self.config_info:
|
||||||
api_key = self.config_info["api_key"]
|
api_key = self.config_info["api_key"]
|
||||||
|
|
|
@ -27,14 +27,14 @@ class TestMentionBot(BotTestCase, DefaultTests):
|
||||||
|
|
||||||
def test_get_account_id(self) -> None:
|
def test_get_account_id(self) -> None:
|
||||||
bot_test_instance = MentionHandler()
|
bot_test_instance = MentionHandler()
|
||||||
bot_test_instance.access_token = "TEST"
|
bot_test_instance.access_token = "TEST" # noqa: S105
|
||||||
|
|
||||||
with self.mock_http_conversation("get_account_id"):
|
with self.mock_http_conversation("get_account_id"):
|
||||||
self.assertEqual(bot_test_instance.get_account_id(), "TEST")
|
self.assertEqual(bot_test_instance.get_account_id(), "TEST")
|
||||||
|
|
||||||
def test_get_alert_id(self) -> None:
|
def test_get_alert_id(self) -> None:
|
||||||
bot_test_instance = MentionHandler()
|
bot_test_instance = MentionHandler()
|
||||||
bot_test_instance.access_token = "TEST"
|
bot_test_instance.access_token = "TEST" # noqa: S105
|
||||||
bot_test_instance.account_id = "TEST"
|
bot_test_instance.account_id = "TEST"
|
||||||
|
|
||||||
with self.mock_http_conversation("get_alert_id"):
|
with self.mock_http_conversation("get_alert_id"):
|
||||||
|
@ -42,7 +42,7 @@ class TestMentionBot(BotTestCase, DefaultTests):
|
||||||
|
|
||||||
def test_get_mentions(self) -> None:
|
def test_get_mentions(self) -> None:
|
||||||
bot_test_instance = MentionHandler()
|
bot_test_instance = MentionHandler()
|
||||||
bot_test_instance.access_token = "TEST"
|
bot_test_instance.access_token = "TEST" # noqa: S105
|
||||||
bot_test_instance.account_id = "TEST"
|
bot_test_instance.account_id = "TEST"
|
||||||
|
|
||||||
with self.mock_http_conversation("get_mentions"):
|
with self.mock_http_conversation("get_mentions"):
|
||||||
|
|
|
@ -104,7 +104,7 @@ class TicTacToeModel:
|
||||||
board[1][1] = 2
|
board[1][1] = 2
|
||||||
# If user played first in the center, the computer should move in the corner. It doesn't matter which corner.
|
# If user played first in the center, the computer should move in the corner. It doesn't matter which corner.
|
||||||
else:
|
else:
|
||||||
location = random.choice(corner_locations)
|
location = random.choice(corner_locations) # noqa: S311
|
||||||
row = location[0]
|
row = location[0]
|
||||||
col = location[1]
|
col = location[1]
|
||||||
board[row][col] = 2
|
board[row][col] = 2
|
||||||
|
@ -156,16 +156,16 @@ class TicTacToeModel:
|
||||||
blank_set = set(blanks)
|
blank_set = set(blanks)
|
||||||
blank_list = list(blank_set)
|
blank_list = list(blank_set)
|
||||||
if blank_list == []:
|
if blank_list == []:
|
||||||
location = random.choice(blank_locations)
|
location = random.choice(blank_locations) # noqa: S311
|
||||||
else:
|
else:
|
||||||
location = random.choice(blank_list)
|
location = random.choice(blank_list) # noqa: S311
|
||||||
row = location[0]
|
row = location[0]
|
||||||
col = location[1]
|
col = location[1]
|
||||||
board[row][col] = 2
|
board[row][col] = 2
|
||||||
return board
|
return board
|
||||||
|
|
||||||
else:
|
else:
|
||||||
location = random.choice(blank_locations)
|
location = random.choice(blank_locations) # noqa: S311
|
||||||
row = location[0]
|
row = location[0]
|
||||||
col = location[1]
|
col = location[1]
|
||||||
board[row][col] = 2
|
board[row][col] = 2
|
||||||
|
|
|
@ -109,7 +109,7 @@ def fetch_xkcd_query(mode: int, comic_id: Optional[str] = None) -> Dict[str, str
|
||||||
raise XkcdServerError
|
raise XkcdServerError
|
||||||
|
|
||||||
latest_id = latest.json()["num"]
|
latest_id = latest.json()["num"]
|
||||||
random_id = random.randint(1, latest_id)
|
random_id = random.randint(1, latest_id) # noqa: S311
|
||||||
url = XKCD_TEMPLATE_URL % (str(random_id),)
|
url = XKCD_TEMPLATE_URL % (str(random_id),)
|
||||||
|
|
||||||
elif mode == XkcdBotCommand.COMIC_ID: # Fetch specific comic strip by id number.
|
elif mode == XkcdBotCommand.COMIC_ID: # Fetch specific comic strip by id number.
|
||||||
|
|
|
@ -839,7 +839,7 @@ class GameInstance:
|
||||||
self.stream = stream
|
self.stream = stream
|
||||||
self.model = deepcopy(self.game_adapter.model())
|
self.model = deepcopy(self.game_adapter.model())
|
||||||
self.board = self.model.current_board
|
self.board = self.model.current_board
|
||||||
self.turn = random.randrange(0, len(players)) - 1
|
self.turn = random.randrange(0, len(players)) - 1 # noqa: S311
|
||||||
self.current_draw: Dict[str, bool] = {}
|
self.current_draw: Dict[str, bool] = {}
|
||||||
self.current_messages: List[str] = []
|
self.current_messages: List[str] = []
|
||||||
self.is_changing_subject = False
|
self.is_changing_subject = False
|
||||||
|
|
|
@ -366,7 +366,7 @@ class ExternalBotHandler:
|
||||||
filepath = os.path.normpath(filepath)
|
filepath = os.path.normpath(filepath)
|
||||||
abs_filepath = os.path.join(self._root_dir, filepath)
|
abs_filepath = os.path.join(self._root_dir, filepath)
|
||||||
if abs_filepath.startswith(self._root_dir):
|
if abs_filepath.startswith(self._root_dir):
|
||||||
return open(abs_filepath)
|
return open(abs_filepath) # noqa: SIM115
|
||||||
else:
|
else:
|
||||||
raise PermissionError(
|
raise PermissionError(
|
||||||
f'Cannot open file "{abs_filepath}". Bots may only access '
|
f'Cannot open file "{abs_filepath}". Bots may only access '
|
||||||
|
|
|
@ -30,9 +30,9 @@ def mock_http_conversation(http_data: Dict[str, Any]) -> Any:
|
||||||
mock_result.headers.update(http_headers)
|
mock_result.headers.update(http_headers)
|
||||||
mock_result.encoding = get_encoding_from_headers(mock_result.headers)
|
mock_result.encoding = get_encoding_from_headers(mock_result.headers)
|
||||||
if is_raw_response:
|
if is_raw_response:
|
||||||
mock_result._content = http_response.encode() # type: ignore[attr-defined] # This modifies a "hidden" attribute.
|
mock_result._content = http_response.encode() # type: ignore[attr-defined] # This modifies a "hidden" attribute. # noqa: SLF001
|
||||||
else:
|
else:
|
||||||
mock_result._content = json.dumps(http_response).encode()
|
mock_result._content = json.dumps(http_response).encode() # noqa: SLF001
|
||||||
return mock_result
|
return mock_result
|
||||||
|
|
||||||
def assert_called_with_fields(
|
def assert_called_with_fields(
|
||||||
|
|
|
@ -51,7 +51,7 @@ class BotServerTests(BotServerTestCase):
|
||||||
message={"content": "@**test** test message"},
|
message={"content": "@**test** test message"},
|
||||||
bot_email="helloworld-bot@zulip.com",
|
bot_email="helloworld-bot@zulip.com",
|
||||||
trigger="mention",
|
trigger="mention",
|
||||||
token="abcd1234",
|
token="abcd1234", # noqa: S106
|
||||||
),
|
),
|
||||||
expected_response="beep boop",
|
expected_response="beep boop",
|
||||||
check_success=True,
|
check_success=True,
|
||||||
|
@ -79,7 +79,7 @@ class BotServerTests(BotServerTestCase):
|
||||||
message={"content": "@**test** test message"},
|
message={"content": "@**test** test message"},
|
||||||
bot_email="helloworld-bot@zulip.com",
|
bot_email="helloworld-bot@zulip.com",
|
||||||
trigger="mention",
|
trigger="mention",
|
||||||
token="abcd1234",
|
token="abcd1234", # noqa: S106
|
||||||
),
|
),
|
||||||
expected_response="beep boop",
|
expected_response="beep boop",
|
||||||
bots_config=bots_config,
|
bots_config=bots_config,
|
||||||
|
@ -119,7 +119,7 @@ class BotServerTests(BotServerTestCase):
|
||||||
message={"content": "@**test** test message"},
|
message={"content": "@**test** test message"},
|
||||||
bot_email="helloworld-bot@zulip.com",
|
bot_email="helloworld-bot@zulip.com",
|
||||||
trigger="mention",
|
trigger="mention",
|
||||||
token="wrongtoken",
|
token="wrongtoken", # noqa: S106
|
||||||
),
|
),
|
||||||
check_success=False,
|
check_success=False,
|
||||||
)
|
)
|
||||||
|
@ -149,7 +149,7 @@ class BotServerTests(BotServerTestCase):
|
||||||
message={"content": "@**test** test message"},
|
message={"content": "@**test** test message"},
|
||||||
bot_email="helloworld-bot@zulip.com",
|
bot_email="helloworld-bot@zulip.com",
|
||||||
trigger="mention",
|
trigger="mention",
|
||||||
token="abcd1234",
|
token="abcd1234", # noqa: S106
|
||||||
),
|
),
|
||||||
bots_config=bots_config,
|
bots_config=bots_config,
|
||||||
)
|
)
|
||||||
|
|
|
@ -221,7 +221,7 @@ def handle_bot() -> str:
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
options = parse_args()
|
options = parse_args()
|
||||||
global bots_config
|
global bots_config # noqa: PLW0603
|
||||||
|
|
||||||
if options.use_env_vars:
|
if options.use_env_vars:
|
||||||
bots_config = read_config_from_env_vars(options.bot_name)
|
bots_config = read_config_from_env_vars(options.bot_name)
|
||||||
|
|
Loading…
Add table
Reference in a new issue