Skip to content

Commit

Permalink
Small fixes (#95)
Browse files Browse the repository at this point in the history
* Stop using `Any` type annotation

* Fix string formatting

* Fix `MessageSenderComponent` return values

* Improve file opening context managers
Reduce indentation level by joining successive file opening context managers onto a single line
  • Loading branch information
CarrotManMatt committed Nov 30, 2023
1 parent 1086238 commit 66bf997
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 72 deletions.
75 changes: 37 additions & 38 deletions .github/workflows/scripts/remove_invalid_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,49 +58,48 @@ def _remove_any_invalid_tables(original_file_path: Path) -> None:
original_file_path = temp_file_path
del temp_file_path

with original_file_path.open("r") as original_file:
new_file: TextIO
with new_file_path.open("w") as new_file:
def write_table_if_not_custom_formatted(write_table_line_number: int, *, is_newline: bool = False) -> None: # noqa: E501
write_table_lines: MutableSequence[str] = []
while write_table_line_number in table_lines or is_newline:
is_newline = False

if write_table_line_number in custom_formatted_table_lines:
return

write_table_lines.append(original_file.readline())
write_table_line_number += 1

write_table_line: str
for write_table_line in write_table_lines:
new_file.write(write_table_line)

line_number = 1
at_end_of_original_file: bool = False
while not at_end_of_original_file:
current_position: int = original_file.tell()
line = original_file.readline()
at_end_of_original_file = not line

if line:
if line_number not in table_lines and line != "\n":
new_file: TextIO
with original_file_path.open("r") as original_file, new_file_path.open("w") as new_file:
def write_table_if_not_custom_formatted(write_table_line_number: int, *, is_newline: bool = False) -> None: # noqa: E501
write_table_lines: MutableSequence[str] = []
while write_table_line_number in table_lines or is_newline:
is_newline = False

if write_table_line_number in custom_formatted_table_lines:
return

write_table_lines.append(original_file.readline())
write_table_line_number += 1

write_table_line: str
for write_table_line in write_table_lines:
new_file.write(write_table_line)

line_number = 1
at_end_of_original_file: bool = False
while not at_end_of_original_file:
current_position: int = original_file.tell()
line = original_file.readline()
at_end_of_original_file = not line

if line:
if line_number not in table_lines and line != "\n":
new_file.write(line)
elif line == "\n":
if line_number + 1 not in table_lines:
new_file.write(line)
elif line == "\n":
if line_number + 1 not in table_lines:
new_file.write(line)
else:
original_file.seek(current_position)
_ = original_file.readline()
original_file.seek(current_position)
write_table_if_not_custom_formatted(line_number, is_newline=True)
else:
original_file.seek(current_position)
_ = original_file.readline()
original_file.seek(current_position)
write_table_if_not_custom_formatted(line_number, is_newline=False)

line_number += 1
write_table_if_not_custom_formatted(line_number, is_newline=True)
else:
original_file.seek(current_position)
_ = original_file.readline()
original_file.seek(current_position)
write_table_if_not_custom_formatted(line_number, is_newline=False)

line_number += 1


def remove_invalid_tables() -> None:
Expand Down
4 changes: 2 additions & 2 deletions cogs/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,12 @@ async def send(self, content: str, *, view: View | None = None) -> Any:
if view:
send_kwargs["view"] = view

await self.channel.send(**send_kwargs)
return await self.channel.send(**send_kwargs)


class ResponseMessageSender(MessageSenderComponent):
def __init__(self, ctx: TeXBotApplicationContext) -> None:
self.ctx: TeXBotApplicationContext = ctx

async def send(self, content: str, *, view: View | None = None) -> Any:
await self.ctx.respond(content=content, view=view, ephemeral=True)
return await self.ctx.respond(content=content, view=view, ephemeral=True)
4 changes: 2 additions & 2 deletions cogs/archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) ->
if not re.match(r"\A\d{17,20}\Z", str_category_id):
await self.send_error(
ctx,
message=f"\"{str_category_id}\" is not a valid category ID."
message=f"{str_category_id!r} is not a valid category ID."
)
return

Expand All @@ -87,7 +87,7 @@ async def archive(self, ctx: TeXBotApplicationContext, str_category_id: str) ->
if not category:
await self.send_error(
ctx,
message=f"Category with ID \"{category_id}\" does not exist."
message=f"Category with ID {str(category_id)!r} does not exist."
)
return

Expand Down
8 changes: 4 additions & 4 deletions cogs/edit_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str,
if not re.match(r"\A\d{17,20}\Z", str_channel_id):
await self.send_error(
ctx,
message=f"\"{str_channel_id}\" is not a valid channel ID."
message=f"{str_channel_id!r} is not a valid channel ID."
)
return

Expand All @@ -87,7 +87,7 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str,
if not re.match(r"\A\d{17,20}\Z", str_message_id):
await self.send_error(
ctx,
message=f"\"{str_message_id}\" is not a valid message ID."
message=f"{str_message_id!r} is not a valid message ID."
)
return

Expand Down Expand Up @@ -119,8 +119,8 @@ async def edit_message(self, ctx: TeXBotApplicationContext, str_channel_id: str,
await self.send_error(
ctx,
message=(
f"Message with ID \"{message_id}\" cannot be edited because it belongs to "
"another user."
f"Message with ID {str(message_id)!r} cannot be edited "
"because it belongs to another user."
)
)
return
Expand Down
5 changes: 3 additions & 2 deletions cogs/kick_no_introduction_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ async def kick_no_introduction_users(self) -> None:
logging.error(
(
"Member with ID: %s could not be checked whether to kick, "
"because their \"joined_at\" attribute was None."
"because their %s attribute was None."
),
member.id
member.id,
repr("joined_at")
)
continue

Expand Down
2 changes: 1 addition & 1 deletion cogs/make_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ async def make_member(self, ctx: TeXBotApplicationContext, uob_id: str) -> None:
if not re.match(r"\A\d{7}\Z", uob_id):
await self.send_error(
ctx,
message=f"\"{uob_id}\" is not a valid UoB Student ID."
message=f"{uob_id!r} is not a valid UoB Student ID."
)
return

Expand Down
4 changes: 3 additions & 1 deletion cogs/remind_me.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ async def remind_me(self, ctx: TeXBotApplicationContext, delay: str, message: st
if parsed_time[1] == 0:
await self.send_error(
ctx,
message="The value provided in the \"delay\" argument was not a time/date."
message=(
f"""The value provided in the {"delay"!r} argument was not a time/date."""
)
)
return

Expand Down
5 changes: 3 additions & 2 deletions cogs/send_get_roles_reminders.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,11 @@ async def send_get_roles_reminders(self) -> None:
logging.error(
(
"Member with ID: %s could not be checked whether to send "
"role_reminder, because their \"guest_role_received_time\" "
"role_reminder, because their %s "
"could not be found."
),
member.id
member.id,
repr("guest_role_received_time")
)
continue

Expand Down
5 changes: 3 additions & 2 deletions cogs/send_introduction_reminders.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,11 @@ async def send_introduction_reminders(self) -> None:
logging.error(
(
"Member with ID: %s could not be checked whether to send "
"introduction_reminder, because their \"joined_at\" attribute "
"introduction_reminder, because their %s attribute "
"was None."
),
member.id
member.id,
repr("joined_at")
)
continue

Expand Down
4 changes: 2 additions & 2 deletions cogs/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ async def channel_stats(self, ctx: TeXBotApplicationContext, str_channel_id: str
if not re.match(r"\A\d{17,20}\Z", str_channel_id):
await self.send_error(
ctx,
message=f"\"{str_channel_id}\" is not a valid channel ID."
message=f"{str_channel_id!r} is not a valid channel ID."
)
return

Expand All @@ -164,7 +164,7 @@ async def channel_stats(self, ctx: TeXBotApplicationContext, str_channel_id: str
if not channel:
await self.send_error(
ctx,
message=f"Text channel with ID \"{channel_id}\" does not exist."
message=f"Text channel with ID {str(channel_id)!r} does not exist."
)
return

Expand Down
2 changes: 1 addition & 1 deletion config.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ def _setup_env_variables(self) -> None: # noqa: C901, PLR0912
",".join(f"{log_level_choice!r}"
for log_level_choice
in LOG_LEVEL_CHOICES[:-1])
} or \"{LOG_LEVEL_CHOICES[-1]}\"."""
} or {LOG_LEVEL_CHOICES[-1]!r}."""
raise ImproperlyConfigured(INVALID_LOG_LEVEL_MESSAGE)
# noinspection SpellCheckingInspection
logging.basicConfig(
Expand Down
20 changes: 14 additions & 6 deletions db/core/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,20 @@ class Meta:

def __repr__(self) -> str:
"""Generate a developer-focused representation of the member's hashed UoB ID."""
return f"<{self._meta.verbose_name}: \"{self.hashed_uob_id}\">"
return f"<{self._meta.verbose_name}: {self.hashed_uob_id!r}>"

def __setattr__(self, name: str, value: Any) -> None:
"""Set the attribute name to the given value, with special cases for proxy fields."""
if name == "uob_id":
if not isinstance(value, str | int):
UOB_ID_INVALID_TYPE_MESSAGE: Final[str] = (
"uob_id must be an instance of str or int."
)

raise TypeError(UOB_ID_INVALID_TYPE_MESSAGE)

self.hashed_uob_id = self.hash_uob_id(value)

else:
super().__setattr__(name, value)

Expand All @@ -125,15 +133,15 @@ def __str__(self) -> str:
return f"{self.hashed_uob_id}"

@staticmethod
def hash_uob_id(uob_id: Any) -> str:
def hash_uob_id(uob_id: str | int) -> str:
"""
Hash the provided uob_id.
The uob_id value is hashed into the format that hashed_uob_ids are stored in the
database when new UoBMadeMember objects are created.
"""
if not isinstance(uob_id, str | int) or not re.match(r"\A\d{7}\Z", str(uob_id)):
INVALID_UOB_ID_MESSAGE: Final[str] = f"\"{uob_id}\" is not a valid UoB Student ID."
if not re.match(r"\A\d{7}\Z", str(uob_id)):
INVALID_UOB_ID_MESSAGE: Final[str] = f"{uob_id!r} is not a valid UoB Student ID."
raise ValueError(INVALID_UOB_ID_MESSAGE)

return hashlib.sha256(str(uob_id).encode()).hexdigest()
Expand Down Expand Up @@ -243,8 +251,8 @@ class Meta:
def __repr__(self) -> str:
"""Generate a developer-focused representation of this DiscordReminder's attributes."""
return (
f"<{self._meta.verbose_name}: \"{self.hashed_member_id}\", "
f"\"{self.channel_id}\", \"{self.send_datetime}\">"
f"<{self._meta.verbose_name}: {self.hashed_member_id!r}, "
f"{str(self.channel_id)!r}, {str(self.send_datetime)!r}>"
)

def __str__(self) -> str:
Expand Down
19 changes: 11 additions & 8 deletions db/core/models/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,19 @@ class Meta:

def __repr__(self) -> str:
"""Generate a developer-focused representation of the hashed discord member's ID."""
return f"<{self._meta.verbose_name}: \"{self.hashed_member_id}\">"
return f"<{self._meta.verbose_name}: {self.hashed_member_id!r}>"

def __setattr__(self, name: str, value: Any) -> None:
"""Set the attribute name to the given value, with special cases for proxy fields."""
if name == "member_id":
if not isinstance(value, str | int):
MEMBER_ID_INVALID_TYPE_MESSAGE: Final[str] = (
"member_id must be an instance of str or int."
)
raise TypeError(MEMBER_ID_INVALID_TYPE_MESSAGE)

self.hashed_member_id = self.hash_member_id(value)

else:
super().__setattr__(name, value)

Expand All @@ -153,20 +160,16 @@ def __str__(self) -> str:
return f"{self.hashed_member_id}"

@staticmethod
def hash_member_id(member_id: Any) -> str:
def hash_member_id(member_id: str | int) -> str:
"""
Hash the provided member_id.
The member_id value is hashed into the format that hashed_member_ids are stored in the
database when new objects of this class are created.
"""
def is_valid_member_id(value: str | int) -> bool:
"""Validate whether the provided value is a valid Discord member ID."""
return bool(re.match(r"\A\d{17,20}\Z", str(value)))

if not isinstance(member_id, str | int) or not is_valid_member_id(member_id):
if not re.match(r"\A\d{17,20}\Z", str(member_id)):
INVALID_MEMBER_ID_MESSAGE: Final[str] = (
f"\"{member_id}\" is not a valid Discord member ID "
f"{member_id!r} is not a valid Discord member ID "
"(see https://docs.pycord.dev/en/stable/api/abcs.html#discord.abc.Snowflake.id)"
)
raise ValueError(INVALID_MEMBER_ID_MESSAGE)
Expand Down
2 changes: 1 addition & 1 deletion utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ async def get_member_from_str_id(self, str_member_id: str) -> discord.Member:

if not re.match(r"\A\d{17,20}\Z", str_member_id):
INVALID_USER_ID_MESSAGE: Final[str] = (
f"\"{str_member_id}\" is not a valid user ID."
f"{str_member_id!r} is not a valid user ID."
)
raise ValueError(INVALID_USER_ID_MESSAGE)

Expand Down

0 comments on commit 66bf997

Please sign in to comment.