11import email .message
22import io
33import sys
4- from _typeshed import StrPath , SupportsNoArgReadline , SupportsRead
4+ from _typeshed import StrPath , SupportsItems , SupportsNoArgReadline , SupportsRead , SupportsWrite , Unused
55from abc import ABCMeta , abstractmethod
66from collections .abc import Callable , Iterable , Iterator , Mapping , Sequence
7- from email ._policybase import _MessageT
87from types import GenericAlias , TracebackType
9- from typing import IO , Any , AnyStr , Generic , Literal , Protocol , TypeVar , overload , type_check_only
8+ from typing import Any , Generic , Literal , Protocol , TypeVar , overload , type_check_only
109from typing_extensions import Self , TypeAlias
1110
1211__all__ = [
@@ -34,23 +33,45 @@ _T = TypeVar("_T")
3433@type_check_only
3534class _SupportsReadAndReadline (SupportsRead [bytes ], SupportsNoArgReadline [bytes ], Protocol ): ...
3635
36+ # As opposed to _MessageT_co in email._policybase, this type is bound to
37+ # mailbox.Message instead of email.message.Message.
38+ _MessageT_co = TypeVar ("_MessageT_co" , bound = Message , default = Message , covariant = True )
39+
3740_MessageData : TypeAlias = email .message .Message | bytes | str | io .StringIO | _SupportsReadAndReadline
3841
3942@type_check_only
4043class _HasIteritems (Protocol ):
4144 def iteritems (self ) -> Iterator [tuple [str , _MessageData ]]: ...
4245
43- @type_check_only
44- class _HasItems (Protocol ):
45- def items (self ) -> Iterator [tuple [str , _MessageData ]]: ...
46-
4746linesep : bytes
4847
49- class Mailbox (Generic [_MessageT ]):
48+ # Common interface for get_file() return types.
49+ @type_check_only
50+ class _GetFileReturn (Protocol ):
51+ def __iter__ (self ) -> Iterator [bytes ]: ...
52+ def __enter__ (self ) -> Self : ...
53+ def __exit__ (
54+ self , exc_type : type [BaseException ] | None , exc : BaseException | None , tb : TracebackType | None , /
55+ ) -> bool | None : ...
56+ def read (self , size : int | None = None , / ) -> bytes : ...
57+ def read1 (self , size : int | None = None , / ) -> bytes : ...
58+ def readline (self , size : int | None = None , / ) -> bytes : ...
59+ def readlines (self , sizehint : int | None = None , / ) -> list [bytes ]: ...
60+ def tell (self ) -> int : ...
61+ def seek (self , offset : int , whence : int = 0 , / ) -> object : ...
62+ def close (self ) -> object : ...
63+ def readable (self ) -> bool : ...
64+ def writable (self ) -> bool : ...
65+ def seekable (self ) -> bool : ...
66+ def flush (self ) -> object : ...
67+ @property
68+ def closed (self ) -> bool : ...
69+
70+ class Mailbox (Generic [_MessageT_co ]):
5071 _path : str # undocumented
51- _factory : Callable [[IO [ Any ]], _MessageT ] | None # undocumented
72+ _factory : Callable [[_GetFileReturn ], _MessageT_co ] | None # undocumented
5273 @overload
53- def __init__ (self , path : StrPath , factory : Callable [[IO [ Any ]], _MessageT ], create : bool = True ) -> None : ...
74+ def __init__ (self , path : StrPath , factory : Callable [[_GetFileReturn ], _MessageT_co ], create : bool = True ) -> None : ...
5475 @overload
5576 def __init__ (self , path : StrPath , factory : None = None , create : bool = True ) -> None : ...
5677 @abstractmethod
@@ -62,37 +83,38 @@ class Mailbox(Generic[_MessageT]):
6283 @abstractmethod
6384 def __setitem__ (self , key : str , message : _MessageData ) -> None : ...
6485 @overload
65- def get (self , key : str , default : None = None ) -> _MessageT | None : ...
86+ def get (self , key : str , default : None = None ) -> _MessageT_co | None : ...
6687 @overload
67- def get (self , key : str , default : _T ) -> _MessageT | _T : ...
68- def __getitem__ (self , key : str ) -> _MessageT : ...
88+ def get (self , key : str , default : _T ) -> _MessageT_co | _T : ...
89+ def __getitem__ (self , key : str ) -> _MessageT_co : ...
6990 @abstractmethod
70- def get_message (self , key : str ) -> _MessageT : ...
91+ def get_message (self , key : str ) -> _MessageT_co : ...
7192 def get_string (self , key : str ) -> str : ...
7293 @abstractmethod
7394 def get_bytes (self , key : str ) -> bytes : ...
74- # As '_ProxyFile' doesn't implement the full IO spec, and BytesIO is incompatible with it, get_file return is Any here
7595 @abstractmethod
76- def get_file (self , key : str ) -> Any : ...
96+ def get_file (self , key : str ) -> _GetFileReturn : ...
7797 @abstractmethod
7898 def iterkeys (self ) -> Iterator [str ]: ...
7999 def keys (self ) -> list [str ]: ...
80- def itervalues (self ) -> Iterator [_MessageT ]: ...
81- def __iter__ (self ) -> Iterator [_MessageT ]: ...
82- def values (self ) -> list [_MessageT ]: ...
83- def iteritems (self ) -> Iterator [tuple [str , _MessageT ]]: ...
84- def items (self ) -> list [tuple [str , _MessageT ]]: ...
100+ def itervalues (self ) -> Iterator [_MessageT_co ]: ...
101+ def __iter__ (self ) -> Iterator [_MessageT_co ]: ...
102+ def values (self ) -> list [_MessageT_co ]: ...
103+ def iteritems (self ) -> Iterator [tuple [str , _MessageT_co ]]: ...
104+ def items (self ) -> list [tuple [str , _MessageT_co ]]: ...
85105 @abstractmethod
86106 def __contains__ (self , key : str ) -> bool : ...
87107 @abstractmethod
88108 def __len__ (self ) -> int : ...
89109 def clear (self ) -> None : ...
90110 @overload
91- def pop (self , key : str , default : None = None ) -> _MessageT | None : ...
111+ def pop (self , key : str , default : None = None ) -> _MessageT_co | None : ...
92112 @overload
93- def pop (self , key : str , default : _T ) -> _MessageT | _T : ...
94- def popitem (self ) -> tuple [str , _MessageT ]: ...
95- def update (self , arg : _HasIteritems | _HasItems | Iterable [tuple [str , _MessageData ]] | None = None ) -> None : ...
113+ def pop (self , key : str , default : _T ) -> _MessageT_co | _T : ...
114+ def popitem (self ) -> tuple [str , _MessageT_co ]: ...
115+ def update (
116+ self , arg : _HasIteritems | SupportsItems [str , _MessageData ] | Iterable [tuple [str , _MessageData ]] | None = None
117+ ) -> None : ...
96118 @abstractmethod
97119 def flush (self ) -> None : ...
98120 @abstractmethod
@@ -101,19 +123,21 @@ class Mailbox(Generic[_MessageT]):
101123 def unlock (self ) -> None : ...
102124 @abstractmethod
103125 def close (self ) -> None : ...
126+ # Undocumented, called by subclasses to parse added messages.
127+ def _dump_message (self , message : _MessageData , target : SupportsWrite [bytes ], mangle_from_ : bool = False ) -> None : ...
104128 def __class_getitem__ (cls , item : Any , / ) -> GenericAlias : ...
105129
106130class Maildir (Mailbox [MaildirMessage ]):
107131 colon : str
108132 def __init__ (
109- self , dirname : StrPath , factory : Callable [[IO [ Any ] ], MaildirMessage ] | None = None , create : bool = True
133+ self , dirname : StrPath , factory : Callable [[_GetFileReturn ], MaildirMessage ] | None = None , create : bool = True
110134 ) -> None : ...
111- def add (self , message : _MessageData ) -> str : ...
135+ def add (self , message : _MessageData | MaildirMessage ) -> str : ...
112136 def remove (self , key : str ) -> None : ...
113- def __setitem__ (self , key : str , message : _MessageData ) -> None : ...
137+ def __setitem__ (self , key : str , message : _MessageData | MaildirMessage ) -> None : ...
114138 def get_message (self , key : str ) -> MaildirMessage : ...
115139 def get_bytes (self , key : str ) -> bytes : ...
116- def get_file (self , key : str ) -> _ProxyFile [ bytes ] : ...
140+ def get_file (self , key : str ) -> _ProxyFile : ...
117141 if sys .version_info >= (3 , 13 ):
118142 def get_info (self , key : str ) -> str : ...
119143 def set_info (self , key : str , info : str ) -> None : ...
@@ -136,7 +160,7 @@ class Maildir(Mailbox[MaildirMessage]):
136160 def clean (self ) -> None : ...
137161 def next (self ) -> str | None : ...
138162
139- class _singlefileMailbox (Mailbox [_MessageT ], metaclass = ABCMeta ):
163+ class _singlefileMailbox (Mailbox [_MessageT_co ], metaclass = ABCMeta ):
140164 def add (self , message : _MessageData ) -> str : ...
141165 def remove (self , key : str ) -> None : ...
142166 def __setitem__ (self , key : str , message : _MessageData ) -> None : ...
@@ -148,26 +172,32 @@ class _singlefileMailbox(Mailbox[_MessageT], metaclass=ABCMeta):
148172 def flush (self ) -> None : ...
149173 def close (self ) -> None : ...
150174
151- class _mboxMMDF (_singlefileMailbox [_MessageT ]):
152- def get_message (self , key : str ) -> _MessageT : ...
153- def get_file (self , key : str , from_ : bool = False ) -> _PartialFile [ bytes ] : ...
175+ class _mboxMMDF (_singlefileMailbox [_MessageT_co ]):
176+ def get_message (self , key : str ) -> _MessageT_co : ...
177+ def get_file (self , key : str , from_ : bool = False ) -> _PartialFile : ...
154178 def get_bytes (self , key : str , from_ : bool = False ) -> bytes : ...
155179 def get_string (self , key : str , from_ : bool = False ) -> str : ...
156180
157181class mbox (_mboxMMDF [mboxMessage ]):
158- def __init__ (self , path : StrPath , factory : Callable [[IO [Any ]], mboxMessage ] | None = None , create : bool = True ) -> None : ...
182+ def __init__ (
183+ self , path : StrPath , factory : Callable [[_GetFileReturn ], mboxMessage ] | None = None , create : bool = True
184+ ) -> None : ...
159185
160186class MMDF (_mboxMMDF [MMDFMessage ]):
161- def __init__ (self , path : StrPath , factory : Callable [[IO [Any ]], MMDFMessage ] | None = None , create : bool = True ) -> None : ...
187+ def __init__ (
188+ self , path : StrPath , factory : Callable [[_GetFileReturn ], MMDFMessage ] | None = None , create : bool = True
189+ ) -> None : ...
162190
163191class MH (Mailbox [MHMessage ]):
164- def __init__ (self , path : StrPath , factory : Callable [[IO [Any ]], MHMessage ] | None = None , create : bool = True ) -> None : ...
192+ def __init__ (
193+ self , path : StrPath , factory : Callable [[_GetFileReturn ], MHMessage ] | None = None , create : bool = True
194+ ) -> None : ...
165195 def add (self , message : _MessageData ) -> str : ...
166196 def remove (self , key : str ) -> None : ...
167197 def __setitem__ (self , key : str , message : _MessageData ) -> None : ...
168198 def get_message (self , key : str ) -> MHMessage : ...
169199 def get_bytes (self , key : str ) -> bytes : ...
170- def get_file (self , key : str ) -> _ProxyFile [ bytes ] : ...
200+ def get_file (self , key : str ) -> _ProxyFile : ...
171201 def iterkeys (self ) -> Iterator [str ]: ...
172202 def __contains__ (self , key : str ) -> bool : ...
173203 def __len__ (self ) -> int : ...
@@ -184,13 +214,15 @@ class MH(Mailbox[MHMessage]):
184214 def pack (self ) -> None : ...
185215
186216class Babyl (_singlefileMailbox [BabylMessage ]):
187- def __init__ (self , path : StrPath , factory : Callable [[IO [Any ]], BabylMessage ] | None = None , create : bool = True ) -> None : ...
217+ def __init__ (
218+ self , path : StrPath , factory : Callable [[_GetFileReturn ], BabylMessage ] | None = None , create : bool = True
219+ ) -> None : ...
188220 def get_message (self , key : str ) -> BabylMessage : ...
189221 def get_bytes (self , key : str ) -> bytes : ...
190- def get_file (self , key : str ) -> IO [ bytes ] : ...
222+ def get_file (self , key : str ) -> io . BytesIO : ...
191223 def get_labels (self ) -> list [str ]: ...
192224
193- class Message (email .message .Message ):
225+ class Message (email .message .Message [ str , str ] ):
194226 def __init__ (self , message : _MessageData | None = None ) -> None : ...
195227
196228class MaildirMessage (Message ):
@@ -232,18 +264,19 @@ class BabylMessage(Message):
232264
233265class MMDFMessage (_mboxMMDFMessage ): ...
234266
235- class _ProxyFile (Generic [AnyStr ]):
236- def __init__ (self , f : IO [AnyStr ], pos : int | None = None ) -> None : ...
237- def read (self , size : int | None = None ) -> AnyStr : ...
238- def read1 (self , size : int | None = None ) -> AnyStr : ...
239- def readline (self , size : int | None = None ) -> AnyStr : ...
240- def readlines (self , sizehint : int | None = None ) -> list [AnyStr ]: ...
241- def __iter__ (self ) -> Iterator [AnyStr ]: ...
267+ # Until Python 3.14, this class was technically - but unnecessarily - generic at runtime.
268+ class _ProxyFile :
269+ def __init__ (self , f : _GetFileReturn , pos : int | None = None ) -> None : ...
270+ def read (self , size : int | None = None ) -> bytes : ...
271+ def read1 (self , size : int | None = None ) -> bytes : ...
272+ def readline (self , size : int | None = None ) -> bytes : ...
273+ def readlines (self , sizehint : int | None = None ) -> list [bytes ]: ...
274+ def __iter__ (self ) -> Iterator [bytes ]: ...
242275 def tell (self ) -> int : ...
243276 def seek (self , offset : int , whence : int = 0 ) -> None : ...
244277 def close (self ) -> None : ...
245278 def __enter__ (self ) -> Self : ...
246- def __exit__ (self , exc_type : type [ BaseException ] | None , exc : BaseException | None , tb : TracebackType | None ) -> None : ...
279+ def __exit__ (self , * exc : Unused ) -> None : ...
247280 def readable (self ) -> bool : ...
248281 def writable (self ) -> bool : ...
249282 def seekable (self ) -> bool : ...
@@ -252,8 +285,8 @@ class _ProxyFile(Generic[AnyStr]):
252285 def closed (self ) -> bool : ...
253286 def __class_getitem__ (cls , item : Any , / ) -> GenericAlias : ...
254287
255- class _PartialFile (_ProxyFile [ AnyStr ] ):
256- def __init__ (self , f : IO [ AnyStr ] , start : int | None = None , stop : int | None = None ) -> None : ...
288+ class _PartialFile (_ProxyFile ):
289+ def __init__ (self , f : _GetFileReturn , start : int | None = None , stop : int | None = None ) -> None : ...
257290
258291class Error (Exception ): ...
259292class NoSuchMailboxError (Error ): ...
0 commit comments