Skip to content

Commit c72a3e9

Browse files
authored
Don't require IO for redirect_stdout (#14905)
1 parent 6ca8824 commit c72a3e9

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

stdlib/contextlib.pyi

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ from _typeshed import FileDescriptorOrPath, Unused
44
from abc import ABC, abstractmethod
55
from collections.abc import AsyncGenerator, AsyncIterator, Awaitable, Callable, Generator, Iterator
66
from types import TracebackType
7-
from typing import IO, Any, Generic, Protocol, TypeVar, overload, runtime_checkable, type_check_only
7+
from typing import Any, Generic, Protocol, TypeVar, overload, runtime_checkable, type_check_only
88
from typing_extensions import ParamSpec, Self, TypeAlias
99

1010
__all__ = [
@@ -30,7 +30,6 @@ if sys.version_info >= (3, 11):
3030

3131
_T = TypeVar("_T")
3232
_T_co = TypeVar("_T_co", covariant=True)
33-
_T_io = TypeVar("_T_io", bound=IO[str] | None)
3433
_ExitT_co = TypeVar("_ExitT_co", covariant=True, bound=bool | None, default=bool | None)
3534
_F = TypeVar("_F", bound=Callable[..., Any])
3635
_G_co = TypeVar("_G_co", bound=Generator[Any, Any, Any] | AsyncGenerator[Any, Any], covariant=True)
@@ -141,14 +140,24 @@ class suppress(AbstractContextManager[None, bool]):
141140
self, exctype: type[BaseException] | None, excinst: BaseException | None, exctb: TracebackType | None
142141
) -> bool: ...
143142

144-
class _RedirectStream(AbstractContextManager[_T_io, None]):
145-
def __init__(self, new_target: _T_io) -> None: ...
143+
# This is trying to describe what is needed for (most?) uses
144+
# of `redirect_stdout` and `redirect_stderr`.
145+
# https://github.com/python/typeshed/issues/14903
146+
@type_check_only
147+
class _SupportsRedirect(Protocol):
148+
def write(self, s: str, /) -> int: ...
149+
def flush(self) -> None: ...
150+
151+
_SupportsRedirectT = TypeVar("_SupportsRedirectT", bound=_SupportsRedirect | None)
152+
153+
class _RedirectStream(AbstractContextManager[_SupportsRedirectT, None]):
154+
def __init__(self, new_target: _SupportsRedirectT) -> None: ...
146155
def __exit__(
147156
self, exctype: type[BaseException] | None, excinst: BaseException | None, exctb: TracebackType | None
148157
) -> None: ...
149158

150-
class redirect_stdout(_RedirectStream[_T_io]): ...
151-
class redirect_stderr(_RedirectStream[_T_io]): ...
159+
class redirect_stdout(_RedirectStream[_SupportsRedirectT]): ...
160+
class redirect_stderr(_RedirectStream[_SupportsRedirectT]): ...
152161

153162
class _BaseExitStack(Generic[_ExitT_co]):
154163
def enter_context(self, cm: AbstractContextManager[_T, _ExitT_co]) -> _T: ...

0 commit comments

Comments
 (0)