pytest-dev / pytest-dev/pytest-xdist

`ValueError: I/O operation on closed file.` when using `conftest.py` with `xdist`

Open
#1,019 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.9k
Forks
287
Avg merge
9h 30m
Merged PRs (30d)
2

Description

I have a regression test suite that I run in parallel with xdist.

My application has permanent threads that poll and log every 5 seconds for the life time of the application.

If I create an empty conftest.py file, and run pytest -n 16 to run under xdist, the tests will eventually start logging ValueError: I/O operation on closed file. each time that these permanent thread calls logger.debug.

It appears that these error messages don't start until an xdist worker finally stops, and each xdist worker once stopped will start contributing these error messages. Usually when the tests are around 90% completed is when these error messages start to occur.

If I add the -s flag when calling pytests (pytest -n16 -s), this issue doesn't occur. Or if I remove the conftest.py file the issue does not occur.

It seems like the mere existence of a conftest.py file is enough to trigger this issue. I'm trying to write a custom plugin, but even if I remove all the code and just leave an empty conftest.py, this issue occurs.

Unfortunately I cannot reproduce this issue outside of my application. For example creating a small test file with a permanent thread that logs every second doesn't reproduce the issue.

Has anyone encountered this issue, or can offer insight into why the presence of conftest.py affects logging in this way? Any suggestions for workarounds or fixes would be greatly appreciated.

Here is the logging error that I see over and over again when running the tests:

--- Logging error ---
Traceback (most recent call last):
  File "/app/Python-3.12.1/Lib/logging/__init__.py", line 1163, in emit
    stream.write(msg + self.terminator)
Call stack:
  File "/app/Python-3.12.1/Lib/threading.py", line 1030, in _bootstrap
    self._bootstrap_inner()
  File "/app/Python-3.12.1/Lib/threading.py", line 1073, in _bootstrap_inner
    self.run()
  File "/app/Python-3.12.1/Lib/threading.py", line 1010, in run
    self._target(*self._args, **self._kwargs)
  ... [logs abridged]
  File "/app/src/engine/poll/__init__.py", line 76, in _poll
    logger.info('polling message')
Message: 'polling message'
Arguments: ()

I'm using Pytest==8.0.0 and pytest-xdist==3.5.0

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reported pytest 8.0.0 and pytest-xdist 3.5.0 setup, using an empty conftest.py and pytest -n 16. Compare runs with and without -s, and observe worker shutdown alongside the logging traceback from the permanent polling thread. Done means identifying why the conftest.py presence changes stream handling and preventing the repeated closed-file logging errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
distributed-systems, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.