From 039c6bcdb1306d3b5cab2b0d463e113bee302cf1 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 29 Aug 2024 16:48:32 +0200 Subject: [PATCH] Use `Self` for email.message attachments (#12530) --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Avasam --- stdlib/@tests/test_cases/email/check_message.py | 4 ++++ stdlib/email/message.pyi | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/stdlib/@tests/test_cases/email/check_message.py b/stdlib/@tests/test_cases/email/check_message.py index a9b43e23f..1bf3c3a2e 100644 --- a/stdlib/@tests/test_cases/email/check_message.py +++ b/stdlib/@tests/test_cases/email/check_message.py @@ -1,6 +1,10 @@ from email.headerregistry import Address from email.message import EmailMessage +from typing_extensions import assert_type msg = EmailMessage() msg["To"] = "receiver@example.com" msg["From"] = Address("Sender Name", "sender", "example.com") + +for a in msg.iter_attachments(): + assert_type(a, EmailMessage) diff --git a/stdlib/email/message.pyi b/stdlib/email/message.pyi index e5b46fbf8..7e80f13ad 100644 --- a/stdlib/email/message.pyi +++ b/stdlib/email/message.pyi @@ -147,7 +147,11 @@ class Message(Generic[_HeaderT, _HeaderParamT]): class MIMEPart(Message[_HeaderRegistryT, _HeaderRegistryParamT]): def __init__(self, policy: Policy | None = None) -> None: ... def get_body(self, preferencelist: Sequence[str] = ("related", "html", "plain")) -> MIMEPart[_HeaderRegistryT] | None: ... - def iter_attachments(self) -> Iterator[MIMEPart[_HeaderRegistryT]]: ... + def attach(self, payload: Self) -> None: ... # type: ignore[override] + # The attachments are created via type(self) in the attach method. It's theoretically + # possible to sneak other attachment types into a MIMEPart instance, but could cause + # cause unforseen consequences. + def iter_attachments(self) -> Iterator[Self]: ... def iter_parts(self) -> Iterator[MIMEPart[_HeaderRegistryT]]: ... def get_content(self, *args: Any, content_manager: ContentManager | None = None, **kw: Any) -> Any: ... def set_content(self, *args: Any, content_manager: ContentManager | None = None, **kw: Any) -> None: ...