Skip to content

Changed tempfile.NamedTemporaryFile mode to w - #3739

Merged
Rowlando13 merged 1 commit into
pallets:mainfrom
H-Sorkatti:fix-tempfile-mode
Aug 14, 2026
Merged

Rowlando13 merged 1 commit into
pallets:mainfrom
H-Sorkatti:fix-tempfile-mode

Conversation

@H-Sorkatti

@H-Sorkatti H-Sorkatti commented Jul 31, 2026 •

Copy link
Copy Markdown

Inside src/click/_termui_impl.py, the function get_pager_file delegates the creation of a tempfile to _tempfilepager, which returns a BinaryIO object of the opened file:

f = tempfile.NamedTemporaryFile(mode="wb", delete=False)
try:
    yield t.cast(t.BinaryIO, f), encoding, color
...

Which is called by _pager_contextmanager in

...
if pager_cmd_parts:
        if WIN:
            return _tempfilepager(pager_cmd_parts, color)
        return _pipepager(pager_cmd_parts, color)
...
    if WIN or sys.platform.startswith("os2"):
        return _tempfilepager(["more"], color)
    return _pipepager(["less"], color)

In the end get_pager_file

def get_pager_file(color: bool | None = None) -> t.Generator[t.TextIO, None, None]:
    ...
    with _pager_contextmanager(color=color) as (stream, encoding, color):
    # Split streams by capabilities rather than the abstract TextIO /
    # BinaryIO annotations: buffered text streams can be unwrapped to bytes,
    # while other streams are yielded as-is.
    wrapper: MaybeStripAnsi | None = None
        if _has_binary_buffer(stream):
            # Text stream backed by a binary buffer.
            wrapper = MaybeStripAnsi(stream.buffer, color=color, encoding=encoding)
            stream = wrapper
        try:
            # Narrow the BinaryIO | TextIO union that _pager_contextmanager
            # yields; the caller writes text to the pager.
            yield t.cast(t.TextIO, stream)
        ...

In the above yield t.cast(t.TextIO, stream) stream object will be BinaryIO, contradicting the TextIO annotation of the return value, all because it was created with the mode "wb" earlier.

Then if a caller tries: stream.write("some text") it will raise an exception:
TypeError: a bytes-like object is required, not 'str'

FIX:
In _tempfilepager, create the temp file with mode='w'

f = tempfile.NamedTemporaryFile(mode="w", delete=False)

Closes #3740

@kdeldycke kdeldycke added rejected AI Contribution rejected because of its untrustworthy AI origin windows Windows-specific behavior and removed windows Windows-specific behavior labels Aug 8, 2026
@H-Sorkatti

Copy link
Copy Markdown
Author

@kdeldycke
I'm not AI by the way. This a genuine human fix. But of course, it's your library.

@kdeldycke

Copy link
Copy Markdown
Collaborator

@kdeldycke I'm not AI by the way. This a genuine human fix. But of course, it's your library.

Ah. Sorry for the confusion. Maintainers are overloaded with noise these past few months so I wrongly flagged that. Let me review your proposal then.

@kdeldycke kdeldycke removed the rejected AI Contribution rejected because of its untrustworthy AI origin label Aug 13, 2026
@kdeldycke kdeldycke changed the title Changed tempfile.NamedTemporaryFile mode to 'w' Changed tempfile.NamedTemporaryFile mode to w Aug 13, 2026
@kdeldycke kdeldycke added prompt Interactive input and confirmation windows Windows-specific behavior labels Aug 13, 2026
@kdeldycke kdeldycke added typing Type annotations and stubs and removed prompt Interactive input and confirmation labels Aug 13, 2026
@kdeldycke

Copy link
Copy Markdown
Collaborator

OK this is confirmed as a regression from #1572 . And it was not caught because _tempfilepager has 0 test coverage.

@kdeldycke kdeldycke added this to the 8.5.0 milestone Aug 13, 2026
Co-authored-by: H-Sorkatti <H.Sorkatti.B@Gmail.com>
@kdeldycke

kdeldycke commented Aug 13, 2026 •

Copy link
Copy Markdown
Collaborator

Just added tests to cover the regression and added a changelog entry. Also added test for color handling. This PR is ready to be merged upstream.

@Rowlando13
Rowlando13 merged commit 8b44edf into pallets:main Aug 14, 2026
12 checks passed
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Aug 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

typing Type annotations and stubs windows Windows-specific behavior

Projects

None yet

3 participants