Skip to content

Terminal output fails with faulthandler + eventlet #5725

Open
@tomviner

Description

@tomviner

There seems to be an issue with Pytest 5 when testing codebases using eventlet. It only happens when faulthandler is enabled (now the default).

I first saw the issue when running tests against my Nameko service, and it prevented me from seeing my test failures, because the output was truncated.

I narrowed down the reproduction case to just running pytest --help. The effect is to truncate the terminal output, with the following error message sometimes interspersed near the end of wherever the output got up to:

Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BlockingIOError: [Errno 35] write could not complete without blocking

this is clearly a race condition, as this error can appear in random parts of the output, and only some of the time. However I did manage to force a similar error to be displayed, via pytest --help | cat which ended with:

Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe

To reproduce:

pip install 'pytest>=5.0' eventlet
conftest.py:

def pytest_configure():
    # make sure we monkey_patch before `--help` is run
    import eventlet
    eventlet.monkey_patch()

Random truncation of output:

pytest --help

some of the time this includes the BlockingIOError above.

To force the error:

pytest --help | cat
usage: pytest [options] [file_or_dir] [file_or_dir] [...]

positional arguments:
  file_or_dir

general:
  -k EXPRESSION         only run tests which match the given substring
...
                        'extra_keyword_matcTraceback (most recent call last):
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/bin/pytest", line 10, in <module>
    sys.exit(main())
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/_pytest/config/__init__.py", line 74, in main
    return config.hook.pytest_cmdline_main(config=config)
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/pluggy/hooks.py", line 289, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/pluggy/manager.py", line 87, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/pluggy/manager.py", line 81, in <lambda>
    firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/pluggy/callers.py", line 208, in _multicall
    return outcome.get_result()
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/_pytest/helpconfig.py", line 134, in pytest_cmdline_main
    showhelp(config)
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/_pytest/helpconfig.py", line 179, in showhelp
    tw.line(wrapped[0])
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/py/_io/terminalwriter.py", line 273, in line
    self.write('\n')
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/py/_io/terminalwriter.py", line 256, in write
    write_out(self._file, markupmsg)
  File "/Users/me/.virtualenvs/eventlet-pytest-bug/lib/python3.7/site-packages/py/_io/terminalwriter.py", line 421, in write_out
    fil.flush()
BrokenPipeError: [Errno 32] Broken pipe
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe

There's no error without faulthandler enabled:

pytest -p no:faulthandler --help | cat
<entire help message shown>

No error before pytest 5:

pip install 'pytest<=5'
pytest --help | cat
<entire help message shown>

I can only reproduce this on OSX. Could not reproduce on Ubuntu. Seems to be independent of Python version and eventlet version. I git bisected the first pytest commit to have the issue, and found a37b902afea216216 where pytest-faulthandler was integrated into pytest. But I could not find an automated method to detect the failure, as I needed the real terminal for the issue to show itself.

My setup:
platform darwin -- Python 3.7.4, pytest-5.0.1, py-1.8.0, pluggy-0.12.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    platform: macmac platform-specific problemtopic: reportingrelated to terminal output and user-facing messages and errorstype: bugproblem that needs to be addressed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions