Skip to content

click.echo() raises UnsupportedOperation on Windows when using pytest capsys #1590

@andy-maier

Description

@andy-maier

Actual behavior

When using click.echo() in a test function that uses the pytest capsys fixture, it raises UnsupportedOperation on Windows. It runs fine on Linux and macOS.

Here is a complete test module tests/unit/test_error_click.py that reproduces the issue:

import click
import pytest

def myfunc():
    """Function to be tested"""
    click.echo('bla')

def test_myfunc(capsys):
    myfunc()
    stdout, stderr = capsys.readouterr()
    assert stdout == 'bla\n'

Here is the failure on Windows (using Python 2.7):

$ pytest tests
. . .
_________________________________ test_myfunc _________________________________
capsys = <_pytest.capture.CaptureFixture object at 0x04865830>
    def test_myfunc(capsys):
>       myfunc()
tests\unit\test_error_click.py:15: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests\unit\test_error_click.py:11: in myfunc
    click.echo('bla')
.tox\win64_py27_32\lib\site-packages\click\utils.py:230: in echo
    file = _default_text_stdout()
.tox\win64_py27_32\lib\site-packages\click\_compat.py:760: in func
    rv = wrapper_func()
.tox\win64_py27_32\lib\site-packages\click\_compat.py:256: in get_text_stdout
    rv = _get_windows_console_stream(sys.stdout, encoding, errors)
.tox\win64_py27_32\lib\site-packages\click\_winconsole.py:356: in _get_windows_console_stream
    and _is_console(f)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
f = <_pytest.compat.CaptureIO object at 0x049156F0>
    def _is_console(f):
        if not hasattr(f, "fileno"):
            return False
    
        try:
>           fileno = f.fileno()
E           UnsupportedOperation: fileno
.tox\win64_py27_32\lib\site-packages\click\_winconsole.py:343: UnsupportedOperation

This is from this Appveyor run on Python 2.7: https://ci.appveyor.com/project/KSchopmeyer/pywbemtools/builds/33566529/job/j22nqi2rq10f7uk2#L1463

It also happens on Python 3.8: https://ci.appveyor.com/project/KSchopmeyer/pywbemtools/builds/33566529/job/0mo646j7ck1yidhs#L1473

Expected behavior

This should succeed on Windows as it does on Linux and macOS.

Possible solutions

I think UnsupportedOperation should be tolerated in the call to f.fileno() in _winconsole._is_console(). This seems to be done in other people's code calling fileno(), too: https://www.programcreek.com/python/example/17474/io.UnsupportedOperation

Environment

  • Python version: 2.7, 3.8
  • Click version: 7.1.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions