diff --git a/tests/push/test_email.py b/tests/push/test_email.py
index c927a73fa6..e0aab1c046 100644
--- a/tests/push/test_email.py
+++ b/tests/push/test_email.py
@@ -205,8 +205,24 @@ class EmailPusherTests(HomeserverTestCase):
# Multipart: plain text, base 64 encoded; html, base 64 encoded
multipart_msg = email.message_from_bytes(msg)
- txt = multipart_msg.get_payload()[0].get_payload(decode=True).decode()
- html = multipart_msg.get_payload()[1].get_payload(decode=True).decode()
+
+ # Extract the text (non-HTML) portion of the multipart Message,
+ # as a Message.
+ txt_message = multipart_msg.get_payload(i=0)
+ assert isinstance(txt_message, email.message.Message)
+
+ # Extract the actual bytes from the Message object, and decode them to a `str`.
+ txt_bytes = txt_message.get_payload(decode=True)
+ assert isinstance(txt_bytes, bytes)
+ txt = txt_bytes.decode()
+
+ # Do the same for the HTML portion of the multipart Message.
+ html_message = multipart_msg.get_payload(i=1)
+ assert isinstance(html_message, email.message.Message)
+ html_bytes = html_message.get_payload(decode=True)
+ assert isinstance(html_bytes, bytes)
+ html = html_bytes.decode()
+
self.assertIn("/_synapse/client/unsubscribe", txt)
self.assertIn("/_synapse/client/unsubscribe", html)
@@ -347,12 +363,17 @@ class EmailPusherTests(HomeserverTestCase):
# That email should contain the room's avatar
msg: bytes = args[5]
# Multipart: plain text, base 64 encoded; html, base 64 encoded
- html = (
- email.message_from_bytes(msg)
- .get_payload()[1]
- .get_payload(decode=True)
- .decode()
- )
+
+ # Extract the html Message object from the Multipart Message.
+ # We need the asserts to convince mypy that this is OK.
+ html_message = email.message_from_bytes(msg).get_payload(i=1)
+ assert isinstance(html_message, email.message.Message)
+
+ # Extract the `bytes` from the html Message object, and decode to a `str`.
+ html = html_message.get_payload(decode=True)
+ assert isinstance(html, bytes)
+ html = html.decode()
+
self.assertIn("_matrix/media/v1/thumbnail/DUMMY_MEDIA_ID", html)
def test_empty_room(self) -> None:
diff --git a/tests/rest/client/test_account.py b/tests/rest/client/test_account.py
index 992421ffe2..a85ea994de 100644
--- a/tests/rest/client/test_account.py
+++ b/tests/rest/client/test_account.py
@@ -427,13 +427,23 @@ class PasswordResetTestCase(unittest.HomeserverTestCase):
text = None
for part in mail.walk():
if part.get_content_type() == "text/plain":
- text = part.get_payload(decode=True).decode("UTF-8")
+ text = part.get_payload(decode=True)
+ if text is not None:
+ # According to the logic table in `get_payload`, we know that
+ # the result of `get_payload` will be `bytes`, but mypy doesn't
+ # know this and complains. Thus, we assert the type.
+ assert isinstance(text, bytes)
+ text = text.decode("UTF-8")
+
break
if not text:
self.fail("Could not find text portion of email to parse")
- assert text is not None
+ # `text` must be a `str`, after being decoded and determined just above
+ # to not be `None` or an empty `str`.
+ assert isinstance(text, str)
+
match = re.search(r"https://example.com\S+", text)
assert match, "Could not find link in email"
@@ -1209,13 +1219,23 @@ class ThreepidEmailRestTestCase(unittest.HomeserverTestCase):
text = None
for part in mail.walk():
if part.get_content_type() == "text/plain":
- text = part.get_payload(decode=True).decode("UTF-8")
+ text = part.get_payload(decode=True)
+ if text is not None:
+ # According to the logic table in `get_payload`, we know that
+ # the result of `get_payload` will be `bytes`, but mypy doesn't
+ # know this and complains. Thus, we assert the type.
+ assert isinstance(text, bytes)
+ text = text.decode("UTF-8")
+
break
if not text:
self.fail("Could not find text portion of email to parse")
- assert text is not None
+ # `text` must be a `str`, after being decoded and determined just above
+ # to not be `None` or an empty `str`.
+ assert isinstance(text, str)
+
match = re.search(r"https://example.com\S+", text)
assert match, "Could not find link in email"
|