Skip to content

contextlib.redirect_std{out,err} stubs don't yield the new target #4283

@PeterJCLaw

Description

@PeterJCLaw

In contextlib, _RedirectStream (the class behind redirect_stdout and redirect_stderr) returns the current stream target as its context variable, which allows code like this:

with redirect_stdout(io.StringIO()) as buffer:
    do_stuff()

use(buffer.getvalue())

where you capture the redirected stream without a separate line to declare the variable.

However the typeshed doesn't allow this, because redirect_stdout is a ContextManager[None].

I think the fix here would be to have the stub be a ContextManager[T], perhaps like:

_T_io = TypeVar('_T_io', bound=Optional[IO[str]])

class redirect_stdout(ContextManager[_T_io]):
    def __init__(self, new_target: _T_io) -> None: ...

I'd be happy to put together a PR if we like this approach.

Aside: this behaviour isn't actually included in the docs, though maybe it should be?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions