(
    output: Collection[Collection[str]], pager: bool = True, overrun_pages: int = 0
)
Possibly prints a string through less.

    Parameters:
        pager: If false, the string is always echoed directly to stdout
        overrun_pages: Minimum number of pages in output before paging is triggered (paging is never triggered if
                       less than or equal to 0)
Possibly prints a string through less.
Possibly prints a string through less .
def less(
    output: Collection[Collection[str]], pager: bool = True, overrun_pages: int = 0
) -> None:
    """
    Possibly prints a string through less.

    Parameters:
        pager: If false, the string is always echoed directly to stdout
        overrun_pages: Minimum number of pages in output before paging is triggered (paging is never triggered if
                       less than or equal to 0)
    """
    use_echo = False
    text = (line for o in output for line in o)
    text_len = sum(len(o) for o in output)

    # In order to prevent an early pager exit from killing the CLI,
    # we must both ignore the resulting SIGPIPE and BrokenPipeError
    def drop_sig(signal: int, frame: Optional[types.FrameType]) -> None:
        pass

    if not pager or not sys.stdout.isatty():
        use_echo = True

    if not use_echo:
        _, height = shutil.get_terminal_size()
        if text_len < height * overrun_pages:
            use_echo = True

    if use_echo:
        for t in text:
            secho(t)
    else:
        # NOTE: Using signal.SIG_IGN here DOES NOT IGNORE the resulting SIGPIPE
        signal.signal(signal.SIGPIPE, drop_sig)
        try:
            process = subprocess.Popen(["less", "-r"], stdin=subprocess.PIPE)
            stdin = cast(IO[bytes], process.stdin)
            for ix, t in enumerate(text):
                stdin.write(bytearray(t, "utf8"))
                if ix != text_len - 1:
                    stdin.write(bytearray("\n", "utf8"))
            process.communicate()
        except BrokenPipeError:
            pass
        finally:
            signal.signal(signal.SIGPIPE, signal.SIG_DFL)
def less ( output : Collection [ Collection [ str ] ] , pager : bool = True , overrun_pages : int = 0 ) -> None : use_echo = False text = ( line for o in output for line in o ) text_len = sum ( len ( o ) for o in output ) # In order to prevent an early pager exit from killing the CLI, # we must both ignore the resulting SIGPIPE and BrokenPipeError def drop_sig ( signal : int , frame : Optional [ types . FrameType ] ) -> None : pass if not pager or not sys . stdout . isatty ( ) : use_echo = True if not use_echo : _ , height = shutil . get_terminal_size ( ) if text_len < height * overrun_pages : use_echo = True if use_echo : for t in text : secho ( t ) else : # NOTE: Using signal.SIG_IGN here DOES NOT IGNORE the resulting SIGPIPE signal . signal ( signal . SIGPIPE , drop_sig ) try : process = subprocess . Popen ( [ "less" , "-r" ] , stdin = subprocess . PIPE ) stdin = cast ( IO [ bytes ] , process . stdin ) for ix , t in enumerate ( text ) : stdin . write ( bytearray ( t , "utf8" ) ) if ix != text_len - 1 : stdin . write ( bytearray ( "\n" , "utf8" ) ) process . communicate ( ) except BrokenPipeError : pass finally : signal . signal ( signal . SIGPIPE , signal . SIG_DFL )