[Feature] for embedding Click with custom stdout/stderr instances
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 17.7k
- Forks
- 2.3k
- Avg merge
- 1d 30m
- Merged PRs (30d)
- 18
Description
Along with #2360, I also encountered another issue that there is no public API to override the stdout/stderr instances used by Click contextually and globally. The only way found is that manually replacing click.utils._default_text_stdout and click.utils._default_text_stderr private functions internally used by click.echo() and other console output handlers in Click.
Could we have a public API to achieve this?
import sys
from contextvars import ContextVar, copy_context
from typing import TextIO
import click
from prompt_toolkit.contrib.telnet.server import TelnetConnection
current_stdout: ContextVar[TextIO] = ContextVar("current_stdout")
def _get_current_stdout() -> TextIO:
stdout = current_stdout.get(None)
if stdout is None:
return sys.stdout
else:
return stdout
def _get_current_stderr() -> TextIO:
stdout = current_stdout.get(None)
if stdout is None:
return sys.stderr
else:
return stdout
@monitor_cli.command()
def help(ctx: click.Context) -> None:
"""Show the list of commands"""
# You may think that we can just add `file` argument in this simple case,
# but still there are other non-accessible internal usage inside Click
# such as the default help option callback, etc.
click.echo(monitor_cli.get_help(ctx))
...
async def start_server(...):
click.utils._default_text_stdout = _get_current_stdout
click.utils._default_text_stderr = _get_current_stderr
...
async def handle_telnet_connection(connection: TelnetConnection):
...
# There may be multiple concurrent connections!
current_stdout_token = current_stdout.set(connection.stdout)
try:
ctx = copy_context()
ctx.run(monitor_cli.main, ...)
finally:
current_stdout.reset(current_stdout_token)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/click/utils.py, especially _default_text_stdout and _default_text_stderr, and trace how click.echo() and the default help option callback obtain output streams. Review the proposed contextual and global use cases, including concurrent connections through monitor_cli.main. Done means a documented public API replaces private-function overrides while supporting both scopes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100