Skip to content

click.get_pager_file: add tests (#1572 followup)#3405

Open
AndreasBackx wants to merge 2 commits intopallets:mainfrom
AndreasBackx:tests/get_pager_file
Open

click.get_pager_file: add tests (#1572 followup)#3405
AndreasBackx wants to merge 2 commits intopallets:mainfrom
AndreasBackx:tests/get_pager_file

Conversation

@AndreasBackx
Copy link
Copy Markdown
Collaborator

This is a follow-up to #1572 which adds tests to validate the behaviour of click.get_pager_file. There are still some open-standing questions / todos depending on requirements:

  • No Windows tests (yet) because I'm visiting family right now and only have access to a Linux machine.
    • What pager like a simple cat could we use to create simple tests? We might be able to install cat on our CI, though I haven't looked into it yet.
  • What are some other edge cases we could check for? So far I've only added some simple tests:
    • Simple unit tests to test some internal implementation details. I'm not the happiest with this, but it seems like the termui testcode favours testing some internals and it was the easiest of the bunch to add.
    • Simple cat-based integration tests. We basically want to make sure that it works how we expect with a real pager, but using cat seems like the easiest way to validate this as I don't know how we'd test interactive CLIs. 🤔
    • Decide whether the current list of tests are complete enough or if we're missing anything, particularly edge cases.

@kdeldycke kdeldycke changed the title click.get_pager_file: add tests (#1572 followup) click.get_pager_file: add tests (#1572 followup) May 5, 2026
@kdeldycke kdeldycke added this to the 8.4.0 milestone May 5, 2026
@kdeldycke kdeldycke added the f:prompt feature: prompt for input label May 5, 2026
@kdeldycke kdeldycke self-requested a review May 5, 2026 07:25
Copy link
Copy Markdown
Collaborator

@kdeldycke kdeldycke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add reference to that PR in the changelog along side the one from #1572?

i.e.:

-   Add ``click.get_pager_file`` for file-like access to an output
    pager. :pr:`1572` :pr:`3405`

Also update the .. versionadded:: 8.2 that was left-over from #1572.

Copy link
Copy Markdown
Collaborator

@kdeldycke kdeldycke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are workaround and late changes in #1572 about windows so yes, it's better to try to test on that platform too. If you don't have access to a Windows machine, just remove your skip decorator and use the feedback from GitHub workflow runs. Slow, but doable.

Comment thread tests/test_termui.py Outdated

@pytest.mark.skipif(WIN, reason="Exercises the pipe pager path.")
@pytest.mark.parametrize(
("text", "color", "expected"),
Copy link
Copy Markdown
Collaborator

@kdeldycke kdeldycke May 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this matrix of ANSI test cases! 👍

Comment thread tests/test_termui.py Outdated
yield wrapped, "utf-8", color

monkeypatch.setattr(
click._termui_impl, "_pager_contextmanager", pager_contextmanager
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of monkeypatching _pager_contextmanager everytwhere, you can just feed get_pager_file with PAGER=. That way you can check with PAGER being set to cat, PAGER left unset, PAGER set to a missing binary etc to test even more edge-cases.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think that's the way to go because this is the top level API that is being modified by #1572. So if there are regressions, they will surface from here. Maybe you can even repack your tests to only target that higher-level API and demonstrate more use-cases, and skip testing implementation details.

And you can do the same with the other echo_via_pager function that was impacted by #1572.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've redesigned it all a bit because I made the mistake of diving into the differences between BinaryIO, TextIO, io.StringIO, and other io shenanigans. My brain is a bit fried and I'm just going to make dinner as I'm starving.

Let me know what you think. I don't think it's perfect yet, but honestly am just gonna put this down for today and give it another look another day.

Comment thread tests/test_termui.py Outdated
"Popen",
partial(subprocess.Popen, stdout=f),
)
with force_subprocess_stdout:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a style nitpicking: why do you need the temporary force_subprocess_stdout variblae? Just fold everything in the with statement.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explains a bit what it does and makes the with statement a bit less unsightly, just a preference and I don't think too much about it in test code.

Comment thread tests/test_termui.py Outdated
return pager_out.read_text()


@pytest.mark.skipif(WIN, reason="Exercises the pipe pager path.")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just learned the existence of the more utility on Windows. So you can probably test with that as a PAGER.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've given more a try. Let's see if it passes.

@kdeldycke kdeldycke requested a review from davidism May 5, 2026 07:53
Copy link
Copy Markdown
Collaborator Author

@AndreasBackx AndreasBackx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will still update the change entries, but likely not today.

Comment thread tests/test_termui.py Outdated
"Popen",
partial(subprocess.Popen, stdout=f),
)
with force_subprocess_stdout:
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explains a bit what it does and makes the with statement a bit less unsightly, just a preference and I don't think too much about it in test code.

Comment thread tests/test_termui.py Outdated
return pager_out.read_text()


@pytest.mark.skipif(WIN, reason="Exercises the pipe pager path.")
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've given more a try. Let's see if it passes.

Comment thread tests/test_termui.py Outdated
yield wrapped, "utf-8", color

monkeypatch.setattr(
click._termui_impl, "_pager_contextmanager", pager_contextmanager
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've redesigned it all a bit because I made the mistake of diving into the differences between BinaryIO, TextIO, io.StringIO, and other io shenanigans. My brain is a bit fried and I'm just going to make dinner as I'm starving.

Let me know what you think. I don't think it's perfect yet, but honestly am just gonna put this down for today and give it another look another day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

f:prompt feature: prompt for input

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants