From 7d1f91afba9f9f6e6344694835ba00615cb43b8f Mon Sep 17 00:00:00 2001 From: disqualifier Date: Fri, 16 Oct 2026 04:19:15 -0400 Subject: [PATCH] fix: fetch with BODY.PEEK[] so a fetch never sets \Seen RFC822 / BODY[] on a SELECTed mailbox set \Seen as a side effect (RFC 3501). with the UNSEEN query, one flow fetching and rejecting a message hid it from another flow on the same mailbox. only mark_seen() flags a message now; the icloud param is kept and is a no-op. Signed-off-by: disqualifier --- src/aiomail/client.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/aiomail/client.py b/src/aiomail/client.py index c542ecd..c375266 100644 --- a/src/aiomail/client.py +++ b/src/aiomail/client.py @@ -229,10 +229,16 @@ class IMAPClient: return sorted(set(ids), reverse=True) async def fetch(self, email_id: int, *, icloud: bool = False) -> Optional[email.message.Message]: - """fetch and parse a full message by id""" + """fetch and parse a full message by id without setting \\Seen + + uses BODY.PEEK[]: RFC822 / BODY[] on a SELECTed mailbox set \\Seen as a side effect + (RFC 3501), so a fetched-then-rejected message would vanish from every later UNSEEN + search. only mark_seen() flags a message. `icloud` is kept for compatibility and is + now a no-op (BODY.PEEK[] already works there) + """ if not await self.ensure_connection(): return None - part = "(BODY[])" if icloud else "(RFC822)" + part = "(BODY.PEEK[])" try: if self.use_uid: result, data = await self._mail.uid("fetch", str(email_id), part)