Pytest with logging and Click fails with ValueError only within Docker

Viewed 233

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.

0 Answers
Related