@@ -3,33 +3,33 @@ from email import _ParamsType, _ParamType
3
3
from email .charset import Charset
4
4
from email .contentmanager import ContentManager
5
5
from email .errors import MessageDefect
6
- from email .header import Header
7
6
from email .policy import Policy
8
- from typing import Any , Literal , Protocol , TypeVar , overload
7
+ from typing import Any , Generic , Literal , Protocol , TypeVar , overload
9
8
from typing_extensions import Self , TypeAlias
10
9
11
10
__all__ = ["Message" , "EmailMessage" ]
12
11
13
12
_T = TypeVar ("_T" )
13
+ # Type returned by Policy.header_fetch_parse, often str or Header.
14
+ _HeaderT = TypeVar ("_HeaderT" , default = str )
15
+ _HeaderParamT = TypeVar ("_HeaderParamT" , default = str )
16
+ # Represents headers constructed by HeaderRegistry. Those are sub-classes
17
+ # of BaseHeader and another header type.
18
+ _HeaderRegistryT = TypeVar ("_HeaderRegistryT" , default = Any )
19
+ _HeaderRegistryParamT = TypeVar ("_HeaderRegistryParamT" , default = Any )
20
+
14
21
_PayloadType : TypeAlias = Message | str
15
22
_EncodedPayloadType : TypeAlias = Message | bytes
16
23
_MultipartPayloadType : TypeAlias = list [_PayloadType ]
17
24
_CharsetType : TypeAlias = Charset | str | None
18
- # Type returned by Policy.header_fetch_parse, often str or Header.
19
- _HeaderType : TypeAlias = Any
20
- # Type accepted by Policy.header_store_parse.
21
- _HeaderTypeParam : TypeAlias = str | Header | Any
22
25
23
26
class _SupportsEncodeToPayload (Protocol ):
24
27
def encode (self , encoding : str , / ) -> _PayloadType | _MultipartPayloadType | _SupportsDecodeToPayload : ...
25
28
26
29
class _SupportsDecodeToPayload (Protocol ):
27
30
def decode (self , encoding : str , errors : str , / ) -> _PayloadType | _MultipartPayloadType : ...
28
31
29
- # TODO: This class should be generic over the header policy and/or the header
30
- # value types allowed by the policy. This depends on PEP 696 support
31
- # (https://github.com/python/typeshed/issues/11422).
32
- class Message :
32
+ class Message (Generic [_HeaderT , _HeaderParamT ]):
33
33
policy : Policy # undocumented
34
34
preamble : str | None
35
35
epilogue : str | None
@@ -70,24 +70,23 @@ class Message:
70
70
# Same as `get` with `failobj=None`, but with the expectation that it won't return None in most scenarios
71
71
# This is important for protocols using __getitem__, like SupportsKeysAndGetItem
72
72
# Morally, the return type should be `AnyOf[_HeaderType, None]`,
73
- # which we could spell as `_HeaderType | Any`,
74
- # *but* `_HeaderType` itself is currently an alias to `Any`...
75
- def __getitem__ (self , name : str ) -> _HeaderType : ...
76
- def __setitem__ (self , name : str , val : _HeaderTypeParam ) -> None : ...
73
+ # so using "the Any trick" instead.
74
+ def __getitem__ (self , name : str ) -> _HeaderT | Any : ...
75
+ def __setitem__ (self , name : str , val : _HeaderParamT ) -> None : ...
77
76
def __delitem__ (self , name : str ) -> None : ...
78
77
def keys (self ) -> list [str ]: ...
79
- def values (self ) -> list [_HeaderType ]: ...
80
- def items (self ) -> list [tuple [str , _HeaderType ]]: ...
78
+ def values (self ) -> list [_HeaderT ]: ...
79
+ def items (self ) -> list [tuple [str , _HeaderT ]]: ...
81
80
@overload
82
- def get (self , name : str , failobj : None = None ) -> _HeaderType | None : ...
81
+ def get (self , name : str , failobj : None = None ) -> _HeaderT | None : ...
83
82
@overload
84
- def get (self , name : str , failobj : _T ) -> _HeaderType | _T : ...
83
+ def get (self , name : str , failobj : _T ) -> _HeaderT | _T : ...
85
84
@overload
86
- def get_all (self , name : str , failobj : None = None ) -> list [_HeaderType ] | None : ...
85
+ def get_all (self , name : str , failobj : None = None ) -> list [_HeaderT ] | None : ...
87
86
@overload
88
- def get_all (self , name : str , failobj : _T ) -> list [_HeaderType ] | _T : ...
87
+ def get_all (self , name : str , failobj : _T ) -> list [_HeaderT ] | _T : ...
89
88
def add_header (self , _name : str , _value : str , ** _params : _ParamsType ) -> None : ...
90
- def replace_header (self , _name : str , _value : _HeaderTypeParam ) -> None : ...
89
+ def replace_header (self , _name : str , _value : _HeaderParamT ) -> None : ...
91
90
def get_content_type (self ) -> str : ...
92
91
def get_content_maintype (self ) -> str : ...
93
92
def get_content_subtype (self ) -> str : ...
@@ -141,14 +140,14 @@ class Message:
141
140
) -> None : ...
142
141
def __init__ (self , policy : Policy = ...) -> None : ...
143
142
# The following two methods are undocumented, but a source code comment states that they are public API
144
- def set_raw (self , name : str , value : _HeaderTypeParam ) -> None : ...
145
- def raw_items (self ) -> Iterator [tuple [str , _HeaderType ]]: ...
143
+ def set_raw (self , name : str , value : _HeaderParamT ) -> None : ...
144
+ def raw_items (self ) -> Iterator [tuple [str , _HeaderT ]]: ...
146
145
147
- class MIMEPart (Message ):
146
+ class MIMEPart (Message [ _HeaderRegistryT , _HeaderRegistryParamT ] ):
148
147
def __init__ (self , policy : Policy | None = None ) -> None : ...
149
- def get_body (self , preferencelist : Sequence [str ] = ("related" , "html" , "plain" )) -> Message | None : ...
150
- def iter_attachments (self ) -> Iterator [Message ]: ...
151
- def iter_parts (self ) -> Iterator [Message ]: ...
148
+ def get_body (self , preferencelist : Sequence [str ] = ("related" , "html" , "plain" )) -> MIMEPart [ _HeaderRegistryT ] | None : ...
149
+ def iter_attachments (self ) -> Iterator [MIMEPart [ _HeaderRegistryT ] ]: ...
150
+ def iter_parts (self ) -> Iterator [MIMEPart [ _HeaderRegistryT ] ]: ...
152
151
def get_content (self , * args : Any , content_manager : ContentManager | None = None , ** kw : Any ) -> Any : ...
153
152
def set_content (self , * args : Any , content_manager : ContentManager | None = None , ** kw : Any ) -> None : ...
154
153
def make_related (self , boundary : str | None = None ) -> None : ...
0 commit comments