From 3c85f36b7f9afd599409d10a214aafdecf38251e Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 6 Apr 2022 11:20:14 +0100 Subject: [PATCH] Reduce code duplication in the email module (#7558) --- stdlib/email/__init__.pyi | 7 ++++++- stdlib/email/feedparser.pyi | 17 ++++++++--------- stdlib/email/message.pyi | 5 ++--- stdlib/email/mime/application.pyi | 5 ++--- stdlib/email/mime/audio.pyi | 5 ++--- stdlib/email/mime/base.pyi | 4 +--- stdlib/email/mime/image.pyi | 5 ++--- stdlib/email/mime/multipart.pyi | 5 ++--- stdlib/email/parser.pyi | 9 ++++----- stdlib/email/utils.pyi | 4 ++-- 10 files changed, 31 insertions(+), 35 deletions(-) diff --git a/stdlib/email/__init__.pyi b/stdlib/email/__init__.pyi index e2c22554a..49e18ccb8 100644 --- a/stdlib/email/__init__.pyi +++ b/stdlib/email/__init__.pyi @@ -1,6 +1,11 @@ from email.message import Message from email.policy import Policy -from typing import IO, Callable +from typing import IO, Callable, TypeVar, Union + +# Definitions imported by multiple submodules in typeshed +_MessageT = TypeVar("_MessageT", bound=Message) # noqa: Y018 +_ParamType = Union[str, tuple[str | None, str | None, str]] +_ParamsType = Union[str, None, tuple[str, str | None, str]] def message_from_string(s: str, _class: Callable[[], Message] = ..., *, policy: Policy = ...) -> Message: ... def message_from_bytes(s: bytes, _class: Callable[[], Message] = ..., *, policy: Policy = ...) -> Message: ... diff --git a/stdlib/email/feedparser.pyi b/stdlib/email/feedparser.pyi index fd27a7242..b1c7e0f7d 100644 --- a/stdlib/email/feedparser.pyi +++ b/stdlib/email/feedparser.pyi @@ -1,23 +1,22 @@ +from email import _MessageT from email.message import Message from email.policy import Policy -from typing import Callable, Generic, TypeVar, overload +from typing import Callable, Generic, overload __all__ = ["FeedParser", "BytesFeedParser"] -_M = TypeVar("_M", bound=Message) - -class FeedParser(Generic[_M]): +class FeedParser(Generic[_MessageT]): @overload def __init__(self: FeedParser[Message], _factory: None = ..., *, policy: Policy = ...) -> None: ... @overload - def __init__(self, _factory: Callable[[], _M], *, policy: Policy = ...) -> None: ... + def __init__(self, _factory: Callable[[], _MessageT], *, policy: Policy = ...) -> None: ... def feed(self, data: str) -> None: ... - def close(self) -> _M: ... + def close(self) -> _MessageT: ... -class BytesFeedParser(Generic[_M]): +class BytesFeedParser(Generic[_MessageT]): @overload def __init__(self: BytesFeedParser[Message], _factory: None = ..., *, policy: Policy = ...) -> None: ... @overload - def __init__(self, _factory: Callable[[], _M], *, policy: Policy = ...) -> None: ... + def __init__(self, _factory: Callable[[], _MessageT], *, policy: Policy = ...) -> None: ... def feed(self, data: bytes) -> None: ... - def close(self) -> _M: ... + def close(self) -> _MessageT: ... diff --git a/stdlib/email/message.pyi b/stdlib/email/message.pyi index 60deccdc0..97de1cf5d 100644 --- a/stdlib/email/message.pyi +++ b/stdlib/email/message.pyi @@ -1,8 +1,9 @@ +from email import _ParamsType, _ParamType from email.charset import Charset from email.contentmanager import ContentManager from email.errors import MessageDefect from email.policy import Policy -from typing import Any, Generator, Iterator, Sequence, TypeVar, Union +from typing import Any, Generator, Iterator, Sequence, TypeVar __all__ = ["Message", "EmailMessage"] @@ -10,8 +11,6 @@ _T = TypeVar("_T") _PayloadType = list[Message] | str | bytes _CharsetType = Charset | str | None -_ParamsType = Union[str, None, tuple[str, str | None, str]] -_ParamType = Union[str, tuple[str | None, str | None, str]] _HeaderType = Any class Message: diff --git a/stdlib/email/mime/application.pyi b/stdlib/email/mime/application.pyi index c0b2a41c5..4966a17d9 100644 --- a/stdlib/email/mime/application.pyi +++ b/stdlib/email/mime/application.pyi @@ -1,11 +1,10 @@ +from collections.abc import Callable +from email import _ParamsType from email.mime.nonmultipart import MIMENonMultipart from email.policy import Policy -from typing import Callable, Union __all__ = ["MIMEApplication"] -_ParamsType = Union[str, None, tuple[str, str | None, str]] - class MIMEApplication(MIMENonMultipart): def __init__( self, diff --git a/stdlib/email/mime/audio.pyi b/stdlib/email/mime/audio.pyi index 438209a90..fd107d7fc 100644 --- a/stdlib/email/mime/audio.pyi +++ b/stdlib/email/mime/audio.pyi @@ -1,11 +1,10 @@ +from collections.abc import Callable +from email import _ParamsType from email.mime.nonmultipart import MIMENonMultipart from email.policy import Policy -from typing import Callable, Union __all__ = ["MIMEAudio"] -_ParamsType = Union[str, None, tuple[str, str | None, str]] - class MIMEAudio(MIMENonMultipart): def __init__( self, diff --git a/stdlib/email/mime/base.pyi b/stdlib/email/mime/base.pyi index d583f696f..c8f2fe6db 100644 --- a/stdlib/email/mime/base.pyi +++ b/stdlib/email/mime/base.pyi @@ -1,10 +1,8 @@ import email.message +from email import _ParamsType from email.policy import Policy -from typing import Union __all__ = ["MIMEBase"] -_ParamsType = Union[str, None, tuple[str, str | None, str]] - class MIMEBase(email.message.Message): def __init__(self, _maintype: str, _subtype: str, *, policy: Policy | None = ..., **_params: _ParamsType) -> None: ... diff --git a/stdlib/email/mime/image.pyi b/stdlib/email/mime/image.pyi index a2d1f142b..480f6dcab 100644 --- a/stdlib/email/mime/image.pyi +++ b/stdlib/email/mime/image.pyi @@ -1,11 +1,10 @@ +from collections.abc import Callable +from email import _ParamsType from email.mime.nonmultipart import MIMENonMultipart from email.policy import Policy -from typing import Callable, Union __all__ = ["MIMEImage"] -_ParamsType = Union[str, None, tuple[str, str | None, str]] - class MIMEImage(MIMENonMultipart): def __init__( self, diff --git a/stdlib/email/mime/multipart.pyi b/stdlib/email/mime/multipart.pyi index 255fc9d5d..6cd480ccf 100644 --- a/stdlib/email/mime/multipart.pyi +++ b/stdlib/email/mime/multipart.pyi @@ -1,12 +1,11 @@ +from collections.abc import Sequence +from email import _ParamsType from email.message import Message from email.mime.base import MIMEBase from email.policy import Policy -from typing import Sequence, Union __all__ = ["MIMEMultipart"] -_ParamsType = Union[str, None, tuple[str, str | None, str]] - class MIMEMultipart(MIMEBase): def __init__( self, diff --git a/stdlib/email/parser.pyi b/stdlib/email/parser.pyi index bbc5d0124..1846bdcc3 100644 --- a/stdlib/email/parser.pyi +++ b/stdlib/email/parser.pyi @@ -1,14 +1,13 @@ import email.feedparser +from email import _MessageT from email.message import Message from email.policy import Policy -from typing import BinaryIO, Callable, TextIO, TypeVar +from typing import BinaryIO, Callable, TextIO __all__ = ["Parser", "HeaderParser", "BytesParser", "BytesHeaderParser", "FeedParser", "BytesFeedParser"] -_M = TypeVar("_M", bound=Message) - -FeedParser = email.feedparser.FeedParser[_M] -BytesFeedParser = email.feedparser.BytesFeedParser[_M] +FeedParser = email.feedparser.FeedParser[_MessageT] +BytesFeedParser = email.feedparser.BytesFeedParser[_MessageT] class Parser: def __init__(self, _class: Callable[[], Message] | None = ..., *, policy: Policy = ...) -> None: ... diff --git a/stdlib/email/utils.pyi b/stdlib/email/utils.pyi index 0cad7d950..aeffb0ef1 100644 --- a/stdlib/email/utils.pyi +++ b/stdlib/email/utils.pyi @@ -1,7 +1,8 @@ import datetime import sys +from email import _ParamType from email.charset import Charset -from typing import Union, overload +from typing import overload __all__ = [ "collapse_rfc2231_value", @@ -21,7 +22,6 @@ __all__ = [ "unquote", ] -_ParamType = Union[str, tuple[str | None, str | None, str]] _PDTZ = tuple[int, int, int, int, int, int, int, int, int, int | None] def quote(str: str) -> str: ...