From cf96ed5c930ab01432027c70798759629cf49d04 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 28 Oct 2022 19:41:45 -0700 Subject: [PATCH 1/3] email: improve bytes handling --- stdlib/email/__init__.pyi | 2 +- stdlib/email/base64mime.pyi | 12 ++++++++---- stdlib/email/feedparser.pyi | 2 +- stdlib/email/header.pyi | 7 ++++--- stdlib/email/message.pyi | 2 +- stdlib/email/mime/application.pyi | 2 +- stdlib/email/mime/audio.pyi | 2 +- stdlib/email/mime/image.pyi | 2 +- stdlib/email/parser.pyi | 2 +- stdlib/email/quoprimime.pyi | 12 +++++++----- 10 files changed, 26 insertions(+), 19 deletions(-) diff --git a/stdlib/email/__init__.pyi b/stdlib/email/__init__.pyi index 4591b2c3340e..6b59dc73d5cc 100644 --- a/stdlib/email/__init__.pyi +++ b/stdlib/email/__init__.pyi @@ -9,7 +9,7 @@ _ParamType: TypeAlias = Union[str, tuple[str | None, str | None, str]] # noqa: _ParamsType: TypeAlias = Union[str, None, tuple[str, str | None, str]] # noqa: Y047 def message_from_string(s: str, _class: Callable[[], Message] = ..., *, policy: Policy = ...) -> Message: ... -def message_from_bytes(s: bytes, _class: Callable[[], Message] = ..., *, policy: Policy = ...) -> Message: ... +def message_from_bytes(s: bytes | bytearray, _class: Callable[[], Message] = ..., *, policy: Policy = ...) -> Message: ... def message_from_file(fp: IO[str], _class: Callable[[], Message] = ..., *, policy: Policy = ...) -> Message: ... def message_from_binary_file(fp: IO[bytes], _class: Callable[[], Message] = ..., *, policy: Policy = ...) -> Message: ... diff --git a/stdlib/email/base64mime.pyi b/stdlib/email/base64mime.pyi index e55658046f55..613a07ef9763 100644 --- a/stdlib/email/base64mime.pyi +++ b/stdlib/email/base64mime.pyi @@ -1,9 +1,13 @@ __all__ = ["body_decode", "body_encode", "decode", "decodestring", "header_encode", "header_length"] -def header_length(bytearray: str | bytes) -> int: ... -def header_encode(header_bytes: str | bytes, charset: str = ...) -> str: ... -def body_encode(s: bytes, maxlinelen: int = ..., eol: str = ...) -> str: ... -def decode(string: str | bytes) -> bytes: ... +from _typeshed import ReadableBuffer + + +def header_length(bytearray: bytes | bytearray) -> int: ... +def header_encode(header_bytes: str | ReadableBuffer, charset: str = ...) -> str: ... +# First argument should be a buffer that supports slicing and len(). +def body_encode(s: bytes | bytearray, maxlinelen: int = ..., eol: str = ...) -> str: ... +def decode(string: str | ReadableBuffer) -> bytes: ... body_decode = decode decodestring = decode diff --git a/stdlib/email/feedparser.pyi b/stdlib/email/feedparser.pyi index c535c353daad..809f0b0e112b 100644 --- a/stdlib/email/feedparser.pyi +++ b/stdlib/email/feedparser.pyi @@ -20,5 +20,5 @@ class BytesFeedParser(Generic[_MessageT]): def __init__(self: BytesFeedParser[Message], _factory: None = ..., *, policy: Policy = ...) -> None: ... @overload def __init__(self, _factory: Callable[[], _MessageT], *, policy: Policy = ...) -> None: ... - def feed(self, data: bytes) -> None: ... + def feed(self, data: bytes | bytearray) -> None: ... def close(self) -> _MessageT: ... diff --git a/stdlib/email/header.pyi b/stdlib/email/header.pyi index 9248759168a9..58740bd1bdae 100644 --- a/stdlib/email/header.pyi +++ b/stdlib/email/header.pyi @@ -1,3 +1,4 @@ +from collections.abc import Iterable from email.charset import Charset from typing import Any @@ -6,14 +7,14 @@ __all__ = ["Header", "decode_header", "make_header"] class Header: def __init__( self, - s: bytes | str | None = ..., + s: bytes | bytearray | str | None = ..., charset: Charset | str | None = ..., maxlinelen: int | None = ..., header_name: str | None = ..., continuation_ws: str = ..., errors: str = ..., ) -> None: ... - def append(self, s: bytes | str, charset: Charset | str | None = ..., errors: str = ...) -> None: ... + def append(self, s: bytes | bytearray | str, charset: Charset | str | None = ..., errors: str = ...) -> None: ... def encode(self, splitchars: str = ..., maxlinelen: int | None = ..., linesep: str = ...) -> str: ... def __eq__(self, other: object) -> bool: ... def __ne__(self, __other: object) -> bool: ... @@ -23,7 +24,7 @@ class Header: # contains at least one encoded part. def decode_header(header: Header | str) -> list[tuple[Any, Any | None]]: ... def make_header( - decoded_seq: list[tuple[bytes, str | None]], + decoded_seq: Iterable[tuple[bytes | bytearray | str, str | None]], maxlinelen: int | None = ..., header_name: str | None = ..., continuation_ws: str = ..., diff --git a/stdlib/email/message.pyi b/stdlib/email/message.pyi index 4e8f600f7ffd..3c59aeeb2d01 100644 --- a/stdlib/email/message.pyi +++ b/stdlib/email/message.pyi @@ -12,7 +12,7 @@ __all__ = ["Message", "EmailMessage"] _T = TypeVar("_T") -_PayloadType: TypeAlias = list[Message] | str | bytes +_PayloadType: TypeAlias = list[Message] | str | bytes | bytearray _CharsetType: TypeAlias = Charset | str | None _HeaderType: TypeAlias = Any diff --git a/stdlib/email/mime/application.pyi b/stdlib/email/mime/application.pyi index dfff85265ade..5ff60bff6ad2 100644 --- a/stdlib/email/mime/application.pyi +++ b/stdlib/email/mime/application.pyi @@ -8,7 +8,7 @@ __all__ = ["MIMEApplication"] class MIMEApplication(MIMENonMultipart): def __init__( self, - _data: str | bytes, + _data: str | bytes | bytearray, _subtype: str = ..., _encoder: Callable[[MIMEApplication], object] = ..., *, diff --git a/stdlib/email/mime/audio.pyi b/stdlib/email/mime/audio.pyi index b355d55070ad..05e173f5c4a1 100644 --- a/stdlib/email/mime/audio.pyi +++ b/stdlib/email/mime/audio.pyi @@ -8,7 +8,7 @@ __all__ = ["MIMEAudio"] class MIMEAudio(MIMENonMultipart): def __init__( self, - _audiodata: str | bytes, + _audiodata: str | bytes | bytearray, _subtype: str | None = ..., _encoder: Callable[[MIMEAudio], object] = ..., *, diff --git a/stdlib/email/mime/image.pyi b/stdlib/email/mime/image.pyi index f575103de2d6..7e46b835b541 100644 --- a/stdlib/email/mime/image.pyi +++ b/stdlib/email/mime/image.pyi @@ -8,7 +8,7 @@ __all__ = ["MIMEImage"] class MIMEImage(MIMENonMultipart): def __init__( self, - _imagedata: str | bytes, + _imagedata: str | bytes | bytearray, _subtype: str | None = ..., _encoder: Callable[[MIMEImage], object] = ..., *, diff --git a/stdlib/email/parser.pyi b/stdlib/email/parser.pyi index bf51c45728fd..1afd8940f4ef 100644 --- a/stdlib/email/parser.pyi +++ b/stdlib/email/parser.pyi @@ -16,6 +16,6 @@ class HeaderParser(Parser): ... class BytesParser: def __init__(self, _class: Callable[[], Message] = ..., *, policy: Policy = ...) -> None: ... def parse(self, fp: BinaryIO, headersonly: bool = ...) -> Message: ... - def parsebytes(self, text: bytes, headersonly: bool = ...) -> Message: ... + def parsebytes(self, text: bytes | bytearray, headersonly: bool = ...) -> Message: ... class BytesHeaderParser(BytesParser): ... diff --git a/stdlib/email/quoprimime.pyi b/stdlib/email/quoprimime.pyi index c5d324d17e13..ec0c799583bf 100644 --- a/stdlib/email/quoprimime.pyi +++ b/stdlib/email/quoprimime.pyi @@ -1,3 +1,5 @@ +from collections.abc import Iterable + __all__ = [ "body_decode", "body_encode", @@ -13,11 +15,11 @@ __all__ = [ def header_check(octet: int) -> bool: ... def body_check(octet: int) -> bool: ... -def header_length(bytearray: bytes) -> int: ... -def body_length(bytearray: bytes) -> int: ... -def unquote(s: str | bytes) -> str: ... -def quote(c: str | bytes) -> str: ... -def header_encode(header_bytes: bytes, charset: str = ...) -> str: ... +def header_length(bytearray: Iterable[int]) -> int: ... +def body_length(bytearray: Iterable[int]) -> int: ... +def unquote(s: str | bytes | bytearray) -> str: ... +def quote(c: str | bytes | bytearray) -> str: ... +def header_encode(header_bytes: bytes | bytearray, charset: str = ...) -> str: ... def body_encode(body: str, maxlinelen: int = ..., eol: str = ...) -> str: ... def decode(encoded: str, eol: str = ...) -> str: ... def header_decode(s: str) -> str: ... From 0abfce84695b7cc3adcb3bb08f12e459ad56410f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 29 Oct 2022 02:43:08 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/email/base64mime.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/email/base64mime.pyi b/stdlib/email/base64mime.pyi index 613a07ef9763..95c244d69c5c 100644 --- a/stdlib/email/base64mime.pyi +++ b/stdlib/email/base64mime.pyi @@ -2,9 +2,9 @@ __all__ = ["body_decode", "body_encode", "decode", "decodestring", "header_encod from _typeshed import ReadableBuffer - def header_length(bytearray: bytes | bytearray) -> int: ... def header_encode(header_bytes: str | ReadableBuffer, charset: str = ...) -> str: ... + # First argument should be a buffer that supports slicing and len(). def body_encode(s: bytes | bytearray, maxlinelen: int = ..., eol: str = ...) -> str: ... def decode(string: str | ReadableBuffer) -> bytes: ... From 2e5c4b7b3e7a89239e25a7bff3da6aa07ece44de Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 31 Oct 2022 20:47:21 -0700 Subject: [PATCH 3/3] accept str in header_length --- stdlib/email/base64mime.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/email/base64mime.pyi b/stdlib/email/base64mime.pyi index 95c244d69c5c..16118a879ad7 100644 --- a/stdlib/email/base64mime.pyi +++ b/stdlib/email/base64mime.pyi @@ -2,7 +2,7 @@ __all__ = ["body_decode", "body_encode", "decode", "decodestring", "header_encod from _typeshed import ReadableBuffer -def header_length(bytearray: bytes | bytearray) -> int: ... +def header_length(bytearray: str | bytes | bytearray) -> int: ... def header_encode(header_bytes: str | ReadableBuffer, charset: str = ...) -> str: ... # First argument should be a buffer that supports slicing and len().