Skip to content
16 changes: 16 additions & 0 deletions stdlib/@tests/test_cases/email/check_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import email.policy
from email.message import EmailMessage, Message
from email.parser import BytesParser, Parser
from typing_extensions import assert_type

p1 = Parser()
p2 = Parser(policy=email.policy.default)

assert_type(p1, Parser[Message[str, str]])
assert_type(p2, Parser[EmailMessage])

bp1 = BytesParser()
bp2 = BytesParser(policy=email.policy.default)

assert_type(bp1, BytesParser[Message[str, str]])
assert_type(bp2, BytesParser[EmailMessage])
3 changes: 2 additions & 1 deletion stdlib/email/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from collections.abc import Callable
from email._policybase import _MessageT
from email.message import Message
from email.policy import Policy, _MessageT
from email.policy import Policy
from typing import IO, overload
from typing_extensions import TypeAlias

Expand Down
6 changes: 3 additions & 3 deletions stdlib/email/_policybase.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ from abc import ABCMeta, abstractmethod
from email.errors import MessageDefect
from email.header import Header
from email.message import Message
from typing import Generic, Protocol, TypeVar, type_check_only
from typing import Any, Generic, Protocol, TypeVar, type_check_only
from typing_extensions import Self

__all__ = ["Policy", "Compat32", "compat32"]

_MessageT = TypeVar("_MessageT", bound=Message, default=Message)
_MessageT = TypeVar("_MessageT", bound=Message[Any, Any], default=Message[str, str])

@type_check_only
class _MessageFactory(Protocol[_MessageT]):
Expand Down Expand Up @@ -74,4 +74,4 @@ class Compat32(Policy[_MessageT]):
def fold(self, name: str, value: str) -> str: ...
def fold_binary(self, name: str, value: str) -> bytes: ...

compat32: Compat32[Message]
compat32: Compat32[Message[str, str]]
5 changes: 2 additions & 3 deletions stdlib/email/feedparser.pyi
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from collections.abc import Callable
from email._policybase import _MessageT
from email.message import Message
from email.policy import Policy
from typing import Generic, TypeVar, overload
from typing import Generic, overload

__all__ = ["FeedParser", "BytesFeedParser"]

_MessageT = TypeVar("_MessageT", bound=Message, default=Message)

class FeedParser(Generic[_MessageT]):
@overload
def __init__(self: FeedParser[Message], _factory: None = None, *, policy: Policy[Message] = ...) -> None: ...
Expand Down
2 changes: 1 addition & 1 deletion stdlib/email/generator.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ from typing_extensions import Self
__all__ = ["Generator", "DecodedGenerator", "BytesGenerator"]

# By default, generators do not have a message policy.
_MessageT = TypeVar("_MessageT", bound=Message, default=Any)
_MessageT = TypeVar("_MessageT", bound=Message[Any, Any], default=Any)

class Generator(Generic[_MessageT]):
maxheaderlen: int | None
Expand Down
3 changes: 2 additions & 1 deletion stdlib/email/mime/message.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from email._policybase import _MessageT
from email.mime.nonmultipart import MIMENonMultipart
from email.policy import Policy, _MessageT
from email.policy import Policy

__all__ = ["MIMEMessage"]

Expand Down
3 changes: 2 additions & 1 deletion stdlib/email/mime/multipart.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from collections.abc import Sequence
from email import _ParamsType
from email._policybase import _MessageT
from email.mime.base import MIMEBase
from email.policy import Policy, _MessageT
from email.policy import Policy

__all__ = ["MIMEMultipart"]

Expand Down
17 changes: 9 additions & 8 deletions stdlib/email/parser.pyi
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
from _typeshed import SupportsRead
from collections.abc import Callable
from email._policybase import _MessageT
from email.feedparser import BytesFeedParser as BytesFeedParser, FeedParser as FeedParser
from email.message import Message
from email.policy import Policy
from io import _WrappedBuffer
from typing import Generic, TypeVar, overload
from typing import Generic, overload

__all__ = ["Parser", "HeaderParser", "BytesParser", "BytesHeaderParser", "FeedParser", "BytesFeedParser"]

_MessageT = TypeVar("_MessageT", bound=Message, default=Message)

class Parser(Generic[_MessageT]):
@overload
def __init__(self: Parser[Message[str, str]], _class: None = None, *, policy: Policy[Message[str, str]] = ...) -> None: ...
def __init__(self: Parser[Message[str, str]], _class: None = None) -> None: ...
@overload
def __init__(self, _class: Callable[[], _MessageT], *, policy: Policy[_MessageT] = ...) -> None: ...
def __init__(self, _class: None = None, *, policy: Policy[_MessageT]) -> None: ...
@overload
def __init__(self, _class: Callable[[], _MessageT] | None, *, policy: Policy[_MessageT] = ...) -> None: ...
def parse(self, fp: SupportsRead[str], headersonly: bool = False) -> _MessageT: ...
def parsestr(self, text: str, headersonly: bool = False) -> _MessageT: ...

Expand All @@ -25,9 +26,9 @@ class HeaderParser(Parser[_MessageT]):
class BytesParser(Generic[_MessageT]):
parser: Parser[_MessageT]
@overload
def __init__(
self: BytesParser[Message[str, str]], _class: None = None, *, policy: Policy[Message[str, str]] = ...
) -> None: ...
def __init__(self: BytesParser[Message[str, str]], _class: None = None) -> None: ...
@overload
def __init__(self, _class: None = None, *, policy: Policy[_MessageT]) -> None: ...
@overload
def __init__(self, _class: Callable[[], _MessageT], *, policy: Policy[_MessageT] = ...) -> None: ...
def parse(self, fp: _WrappedBuffer, headersonly: bool = False) -> _MessageT: ...
Expand Down
8 changes: 3 additions & 5 deletions stdlib/email/policy.pyi
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
from collections.abc import Callable
from email._policybase import Compat32 as Compat32, Policy as Policy, _MessageFactory, compat32 as compat32
from email._policybase import Compat32 as Compat32, Policy as Policy, _MessageFactory, _MessageT, compat32 as compat32
from email.contentmanager import ContentManager
from email.message import EmailMessage, Message
from typing import Any, TypeVar, overload
from email.message import EmailMessage
from typing import Any, overload
from typing_extensions import Self

__all__ = ["Compat32", "compat32", "Policy", "EmailPolicy", "default", "strict", "SMTP", "HTTP"]

_MessageT = TypeVar("_MessageT", bound=Message, default=Message)

class EmailPolicy(Policy[_MessageT]):
utf8: bool
refold_source: str
Expand Down
2 changes: 1 addition & 1 deletion stdlib/http/client.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import sys
import types
from _typeshed import MaybeNone, ReadableBuffer, SupportsRead, SupportsReadline, WriteableBuffer
from collections.abc import Callable, Iterable, Iterator, Mapping
from email._policybase import _MessageT
from socket import socket
from typing import BinaryIO, Literal, TypeVar, overload
from typing_extensions import Self, TypeAlias
Expand Down Expand Up @@ -33,7 +34,6 @@ __all__ = [

_DataType: TypeAlias = SupportsRead[bytes] | Iterable[ReadableBuffer] | ReadableBuffer
_T = TypeVar("_T")
_MessageT = TypeVar("_MessageT", bound=email.message.Message)
_HeaderValue: TypeAlias = ReadableBuffer | str | int

HTTP_PORT: int
Expand Down
2 changes: 1 addition & 1 deletion stdlib/mailbox.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import sys
from _typeshed import StrPath, SupportsNoArgReadline, SupportsRead
from abc import ABCMeta, abstractmethod
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
from email._policybase import _MessageT
from types import GenericAlias, TracebackType
from typing import IO, Any, AnyStr, Generic, Literal, Protocol, TypeVar, overload
from typing_extensions import Self, TypeAlias
Expand All @@ -29,7 +30,6 @@ __all__ = [
]

_T = TypeVar("_T")
_MessageT = TypeVar("_MessageT", bound=Message)

class _SupportsReadAndReadline(SupportsRead[bytes], SupportsNoArgReadline[bytes], Protocol): ...

Expand Down
Loading