"""The mail interface the outbox uses (AD-1, AD-11).""" from __future__ import annotations from dataclasses import dataclass from typing import Protocol class MailError(Exception): """Base class. Messages never contain the recipient or the text of the e-mail.""" class MailUnavailable(MailError): """The server could not take the message right now; trying again later may work.""" class MailRejected(MailError): """The server refused the message for good (for example an unknown recipient).""" @dataclass(frozen=True) class MailMessage: sender: str recipient: str subject: str body_text: str class Mailer(Protocol): def send(self, message: MailMessage) -> None: """Hand the message to the mail server, or raise MailUnavailable or MailRejected.""" ...