I have a library I'm working on which makes use of Click. It's contained within a Docker image. I'm trying to test it using pytest using click.testing.CliRunner. I'm using logging to write logs, and I've specified that these logs should be emitted in the pyproject.toml. When an exception is raised in my code, and only within Docker, I get the following exception from Click:
/opt/conda/lib/python3.8/site-packages/click/testing.py:434: ValueError
except Exception as e:
if not catch_exceptions:
raise
exception = e
exit_code = 1
exc_info = sys.exc_info()
finally:
sys.stdout.flush()
> stdout = outstreams[0].getvalue()
E ValueError: I/O operation on closed file.
/opt/conda/lib/python3.8/site-packages/click/testing.py:434: ValueError
I've managed to minimally reproduce this issue. My code looks something like this:
import logging, click
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
@click.command()
@click.argument('value')
def main(value):
logger.info(value)
raise RuntimeError()
My tests look like this:
import pytest
from click.testing import CliRunner
from main import main
def test_main():
runner = CliRunner()
runner.invoke(main, ['hello'], catch_exceptions=False)
assert True
And my pyproject.toml is:
[tool.pytest.ini_options]
log_cli = true
log_level = "INFO"
Removing the logging, the CliRunner, or pytest (i.e. running test_main directly) does not trigger the ValueError, and the RuntimeError is the only exception raised. Running this outside of a Docker container also does not raise the ValueError.
How can I avoid this error?
This code is available on a GitHub repo for reproduction. I reproduced this issue in a continuum/miniconda3 container.