Repository navigation
First Check
Commit to Help
Example Codeimport click
LONG_HELP_TEXT = "This is a really long help text that does eventually wrap in the command output"
@click.command()
@click.option('--name', 'name', help=LONG_HELP_TEXT)
def hello_click(name):
click.echo(f'Hello {name}!')
from click.testing import CliRunner as ClickCliRunner
def test_click_runner():
runner = ClickCliRunner()
# DOES WORK
result = runner.invoke(hello_click, ['--help'], terminal_width=1000)
print(result.output)
assert result.exit_code == 0
assert LONG_HELP_TEXT in result.output
import typer
app = typer.Typer()
@app.command()
def hello_typer(name: str = typer.Option(help=LONG_HELP_TEXT)):
typer.echo(f'Hello {name}!')
from typer.testing import CliRunner as TyperCliRunner
def test_typer_runner():
runner = TyperCliRunner()
# DOES NOT WORK
result = runner.invoke(app, ['hello_typer', '--help'], terminal_width=1000)
print(result.output)
assert result.exit_code == 0
assert LONG_HELP_TEXT in result.outputDescriptionWhen using the CliRunner for testing, the terminal width seems to be at 80 chars. According to Click documentation, passing When using a typer app and typer CliRunner, adjusting the terminal_width in CliRunner does not have any effect. Operating SystemLinux Operating System DetailsNo response Typer Version0.21.1 Python Version3.12 Additional ContextNo response |
Replies: 4 comments 12 replies
|
Hi @mbergen, thanks for the report! This seems to only be an issue when |
|
For reference: Terminal width for output using Rich can be set with environment variable |
|
Still reproduces on
Lines 174 to 175 in 9a7b2e8 The constant it sets is the Click formatter's test hook: typer/typer/_click/formatting.py Lines 7 to 8 in 9a7b2e8 With Lines 981 to 994 in 9a7b2e8 The Rich renderer builds its own console, whose width comes from a module-level constant read once at import: Lines 145 to 163 in 9a7b2e8 Lines 72 to 73 in 9a7b2e8 So The clearest sign of the gap is in this repo's own tests. All four tests that pass typer/tests/test_cli/test_help.py Lines 125 to 141 in 9a7b2e8
Reproductionimport typer
from typer._click import formatting
from typer.testing import CliRunner
app = typer.Typer()
@app.command()
def build(
env_file: str = typer.Option(
None,
help=(
"A deliberately long help line so any wrapping is obvious: "
"DBMLSP_ENTERPRISE_READER sets the reporting service account."
),
),
) -> None:
"""Build something."""
runner = CliRunner()
outside = formatting.FORCED_WIDTH
with runner.isolation():
inside = formatting.FORCED_WIDTH
print(f"formatting.FORCED_WIDTH outside isolation(): {outside}")
print(f"formatting.FORCED_WIDTH inside isolation(): {inside}")
for label, kwargs in (("no argument", {}), ("terminal_width=200", {"terminal_width": 200})):
result = runner.invoke(app, ["--help"], **kwargs)
widest = max((len(line) for line in result.output.splitlines()), default=0)
print(f"invoke({label:<20}) -> widest rendered line = {widest}")Output:
The fixResolve the width from the context before building the console, so an explicit typer/typer/_click/formatting.py Lines 105 to 115 in 9a7b2e8 def _get_help_width(ctx: _click.Context | None) -> int | None:
if ctx is None or ctx.terminal_width is None:
return MAX_WIDTH
return ctx.terminal_width
def _get_rich_console(stderr: bool = False, width: int | None = None) -> Console:
return Console(
...
width=width if width is not None else MAX_WIDTH,
...
)
That is 20 changed lines in The three tests fail on The branch and its CI run are here, staged on a fork rather than opened against this repo: shauneccles#1 Full matrix is green: all seven I have deliberately left FORCE_TERMINAL under GITHUB_ACTIONSA second difference, which the patch does not touch. Lines 77 to 84 in 9a7b2e8 A downstream test then gets ANSI escapes on CI that it never gets locally, on top of wrapping at a different width. Stripping the escapes produced a second failure: The temp path wrapped mid-token, so Environment
Related
Glad to open the PR if this shape works for you. One housekeeping note: this thread is marked as answered, but the answer records the |
|
Just confirming this workaround from another real-world project. We hit the same issue with Typer 0.27.0 + Rich 15.0.0 on GitHub Actions ( We added the following only to the pytest step: - name: Run tests
env:
_TYPER_FORCE_DISABLE_TERMINAL: "1"
run: uv run pytestAfter that change, the complete test suite passed on GitHub Actions. We deliberately did not set - name: Run doctor
run: uv run midi-cleaner doctor --jsonThat step also passed, so in our case the workaround was needed specifically for the Hopefully this confirmation helps others who encounter tests that are green locally but fail only under GitHub Actions. |
For reference:
Terminal width for output using Rich can be set with environment variable
COLUMNSTerminal width for output of Typer can be set with environment variable
TERMINAL_WIDTH