pallets / click

Python composable command line interface toolkit
https://click.palletsprojects.com
BSD 3-Clause "New" or "Revised" License
15.54k stars 1.39k forks source link

echo_via_pager with generators leaves terminal in broken state #2674

Open 0xDEC0DE opened 7 months ago

0xDEC0DE commented 7 months ago

Steps to reproduce

Run the following test case:

import click

def output_generator():
    counter = 0
    while True:
        yield "this is a line of output\n"
        if counter == 1024:
            click.echo("kaboom", err=True)
            click.get_current_context().exit(0)
        counter += 1

@click.command
def kaboom():
    click.echo_via_pager(output_generator)

if __name__ == "__main__":
    kaboom()

Attempt to use the terminal afterwards

Expected result

A working terminal.

Actual behavior

Newlines and output are obscured. Commands may be entered, but they are not displayed.

Workaround

Run the reset command after the command terminates.

Environment:

Reproducible on OS X and Ubuntu (x86_64):

$ sw_vers
ProductName:            macOS
ProductVersion:         14.3.1
BuildVersion:           23D60
# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.3 LTS"
0xDEC0DE commented 7 months ago

Addendum

If the generator exits "normally", the terminal works fine. It's only when doing things like error handling that it goes sideways.

stefreak commented 1 week ago

Successfully reproduced this problem using bash, but failed to reproduce using zsh in my case (also macos)

stefreak commented 1 week ago

Hi @0xDEC0DE, thank you for the detailed bug report and the repro! I found a solution for the problem in #2775, if this is still relevant to you and you have time for it I'd be happy to receive feedback and/or a quick review 👍