pytest-dev / pytest-dev/pytest
`OSError: [Errno 9] Bad file descriptor` in terminalwritter
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 14.5k
- Forks
- 3.4k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 35
Description
I have a nightly test run via Jenkins which takes around 8 hours. Pytest runs with live logging so there is thousands of lines output to stdout during the run. Around once per month I get a crash in pytest which kills the run. There is nothing obviously different to explain why pytest crashes on particular runs.
It looks from the traceback like it cannot write to the terminal.
I'm happy to do some work on fixing this, but I will need some guidance from someone who knows the internals of pytest.
OS (where pytest is running)
OS Name: Microsoft Windows 10 Pro
OS Version: 10.0.19044 N/A Build 19044
pytest version
7.1.3
Traceback
INERNALERROR> Traceback (most recent call last):
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\main.py", line 268, in wrap_session
INTERNALERROR> session.exitstatus = doit(config, session) or 0
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\main.py", line 322, in _main
INTERNALERROR> config.hook.pytest_runtestloop(session=session)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_hooks.py", line 265, in __call__
INTERNALERROR> return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_manager.py", line 80, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_callers.py", line 60, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_result.py", line 60, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_callers.py", line 39, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\main.py", line 347, in pytest_runtestloop
INTERNALERROR> item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_hooks.py", line 265, in __call__
INTERNALERROR> return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_manager.py", line 80, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_callers.py", line 60, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_result.py", line 60, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_callers.py", line 39, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\runner.py", line 111, in pytest_runtest_protocol
INTERNALERROR> runtestprotocol(item, nextitem=nextitem)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\runner.py", line 130, in runtestprotocol
INTERNALERROR> reports.append(call_and_report(item, "call", log))
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\runner.py", line 223, in call_and_report
INTERNALERROR> hook.pytest_runtest_logreport(report=report)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_hooks.py", line 265, in __call__
INTERNALERROR> return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_manager.py", line 80, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_callers.py", line 60, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_result.py", line 60, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\pluggy\_callers.py", line 39, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\terminal.py", line 561, in pytest_runtest_logreport
INTERNALERROR> self._write_progress_information_filling_space()
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\terminal.py", line 624, in _write_progress_information_filling_space
INTERNALERROR> self.write(msg.rjust(fill), flush=True, **{color: True})
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\terminal.py", line 414, in write
INTERNALERROR> self._tw.write(content, flush=flush, **markup)
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\_io\terminalwriter.py", line 167, in write
INTERNALERROR> self.flush()
INTERNALERROR> File "C:\jenkins\workspace\my-project\.venv\lib\site-packages\_pytest\_io\terminalwriter.py", line 174, in flush
INTERNALERROR> self._file.flush()
INTERNALERROR> OSError: [Errno 9] Bad file descriptor
pip list
Package Version
--------------------- ---------
allure-pytest 2.11.1
allure-python-commons 2.11.1
astroid 2.12.12
atomicwrites 1.4.1
attrs 22.1.0
bcrypt 3.2.2
black 22.10.0
certifi 2022.6.15
cffi 1.15.1
charset-normalizer 2.1.0
click 8.1.3
colorama 0.4.5
cryptography 37.0.4
cycler 0.11.0
dill 0.3.5.1
fonttools 4.34.4
future 0.18.2
idna 3.3
iniconfig 1.1.1
invoke 1.7.3
isort 5.10.1
kiwisolver 1.4.4
lazy-object-proxy 1.7.1
matplotlib 3.5.2
mccabe 0.7.0
mypy 0.982
mypy-extensions 0.4.3
netmiko 4.1.1
ntc-templates 3.0.0
numpy 1.21.6
packaging 21.3
paramiko 2.11.0
pathspec 0.9.0
Pillow 9.2.0
pip 21.1.1
platformdirs 2.5.2
pluggy 1.0.0
py 1.11.0
pycparser 2.21
pydocstyle 6.1.1
pylint 2.15.5
pylint-pytest 1.1.2
PyNaCl 1.5.0
pyparsing 3.0.9
pyserial 3.5
pytest 7.1.3
python-dateutil 2.8.2
python-nmap 0.7.1
PyYAML 6.0
requests 2.28.1
scipy 1.8.1
scp 0.14.4
setuptools 65.5.0
six 1.16.0
snowballstemmer 2.2.0
sounddevice 0.4.4
tenacity 8.0.1
textfsm 1.1.3
toml 0.10.2
tomli 2.0.1
tomlkit 0.11.1
types-python-nmap 0.7.1
types-requests 2.28.11.2
types-urllib3 1.26.17
typing-extensions 4.3.0
urllib3 1.26.11
wheel 0.38.0
wrapt 1.14.1
- a detailed description of the bug or problem you are having
- output of
pip listfrom the virtual environment you are using - pytest and operating system versions
- minimal example if possible
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading _pytest/_io/terminalwriter.py around flush() and the _pytest/terminal.py call sites shown in the traceback. Reproduce the Windows 10 Jenkins scenario with a long-running pytest session and live logging, then determine the conditions around the bad file descriptor. Done means the intermittent crash is reproduced and a verified fix or clear limitation is covered by relevant tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100