From afa2a8e3dd4911bb3c637a028bb1b64a1146e93c Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 8 Nov 2022 13:50:51 -0800 Subject: [PATCH] mailbox: improve bytes handling (#9083) - The _MessageData alias refers to objects handled in the _dump_message method: https://github.com/python/cpython/blob/016c7d37b6acfe2203542a2655080c6402b3be1f/Lib/mailbox.py#L210 - The path passed to __init__ should be a str path because there are many places in the file (search for self._path) where we join it with a str, which won't work with a bytes path. --- stdlib/mailbox.pyi | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/stdlib/mailbox.pyi b/stdlib/mailbox.pyi index 3169e8cfa..29cea5cad 100644 --- a/stdlib/mailbox.pyi +++ b/stdlib/mailbox.pyi @@ -1,6 +1,7 @@ import email.message +import io import sys -from _typeshed import Self, StrOrBytesPath +from _typeshed import Self, StrPath, SupportsNoArgReadline, SupportsRead from abc import ABCMeta, abstractmethod from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence from types import TracebackType @@ -32,7 +33,10 @@ __all__ = [ _T = TypeVar("_T") _MessageT = TypeVar("_MessageT", bound=Message) -_MessageData: TypeAlias = email.message.Message | bytes | str | IO[str] | IO[bytes] + +class _SupportsReadAndReadline(SupportsRead[bytes], SupportsNoArgReadline[bytes], Protocol): ... + +_MessageData: TypeAlias = email.message.Message | bytes | str | io.StringIO | _SupportsReadAndReadline class _HasIteritems(Protocol): def iteritems(self) -> Iterator[tuple[str, _MessageData]]: ... @@ -43,13 +47,12 @@ class _HasItems(Protocol): linesep: bytes class Mailbox(Generic[_MessageT]): - - _path: bytes | str # undocumented + _path: str # undocumented _factory: Callable[[IO[Any]], _MessageT] | None # undocumented @overload - def __init__(self, path: StrOrBytesPath, factory: Callable[[IO[Any]], _MessageT], create: bool = ...) -> None: ... + def __init__(self, path: StrPath, factory: Callable[[IO[Any]], _MessageT], create: bool = ...) -> None: ... @overload - def __init__(self, path: StrOrBytesPath, factory: None = ..., create: bool = ...) -> None: ... + def __init__(self, path: StrPath, factory: None = ..., create: bool = ...) -> None: ... @abstractmethod def add(self, message: _MessageData) -> str: ... @abstractmethod @@ -105,7 +108,7 @@ class Maildir(Mailbox[MaildirMessage]): colon: str def __init__( - self, dirname: StrOrBytesPath, factory: Callable[[IO[Any]], MaildirMessage] | None = ..., create: bool = ... + self, dirname: StrPath, factory: Callable[[IO[Any]], MaildirMessage] | None = ..., create: bool = ... ) -> None: ... def add(self, message: _MessageData) -> str: ... def remove(self, key: str) -> None: ... @@ -146,19 +149,13 @@ class _mboxMMDF(_singlefileMailbox[_MessageT]): def get_string(self, key: str, from_: bool = ...) -> str: ... class mbox(_mboxMMDF[mboxMessage]): - def __init__( - self, path: StrOrBytesPath, factory: Callable[[IO[Any]], mboxMessage] | None = ..., create: bool = ... - ) -> None: ... + def __init__(self, path: StrPath, factory: Callable[[IO[Any]], mboxMessage] | None = ..., create: bool = ...) -> None: ... class MMDF(_mboxMMDF[MMDFMessage]): - def __init__( - self, path: StrOrBytesPath, factory: Callable[[IO[Any]], MMDFMessage] | None = ..., create: bool = ... - ) -> None: ... + def __init__(self, path: StrPath, factory: Callable[[IO[Any]], MMDFMessage] | None = ..., create: bool = ...) -> None: ... class MH(Mailbox[MHMessage]): - def __init__( - self, path: StrOrBytesPath, factory: Callable[[IO[Any]], MHMessage] | None = ..., create: bool = ... - ) -> None: ... + def __init__(self, path: StrPath, factory: Callable[[IO[Any]], MHMessage] | None = ..., create: bool = ...) -> None: ... def add(self, message: _MessageData) -> str: ... def remove(self, key: str) -> None: ... def __setitem__(self, key: str, message: _MessageData) -> None: ... @@ -173,17 +170,15 @@ class MH(Mailbox[MHMessage]): def unlock(self) -> None: ... def close(self) -> None: ... def list_folders(self) -> list[str]: ... - def get_folder(self, folder: StrOrBytesPath) -> MH: ... - def add_folder(self, folder: StrOrBytesPath) -> MH: ... - def remove_folder(self, folder: StrOrBytesPath) -> None: ... + def get_folder(self, folder: StrPath) -> MH: ... + def add_folder(self, folder: StrPath) -> MH: ... + def remove_folder(self, folder: StrPath) -> None: ... def get_sequences(self) -> dict[str, list[int]]: ... def set_sequences(self, sequences: Mapping[str, Sequence[int]]) -> None: ... def pack(self) -> None: ... class Babyl(_singlefileMailbox[BabylMessage]): - def __init__( - self, path: StrOrBytesPath, factory: Callable[[IO[Any]], BabylMessage] | None = ..., create: bool = ... - ) -> None: ... + def __init__(self, path: StrPath, factory: Callable[[IO[Any]], BabylMessage] | None = ..., create: bool = ...) -> None: ... def get_message(self, key: str) -> BabylMessage: ... def get_bytes(self, key: str) -> bytes: ... def get_file(self, key: str) -> IO[bytes]: ...