仅在 Docker 内使用日志记录和 Click 进行 Pytest 失败并出现 ValueError

Mat*_*hew 5 python pytest docker python-click

我正在开发一个使用 Click 的库。它包含在 Docker 映像中。我正在尝试使用 pytest 使用 来测试它click.testing.CliRunner。我用来logging编写日志,并且我已指定这些日志应在pyproject.toml. 当我的代码中引发异常(并且仅在 Docker 内)时,我从 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
Run Code Online (Sandbox Code Playgroud)

我已经设法最小化地重现这个问题。我的代码看起来像这样:

/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
Run Code Online (Sandbox Code Playgroud)

我的测试如下所示:

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()
Run Code Online (Sandbox Code Playgroud)

我的pyproject.toml是:

[tool.pytest.ini_options]
log_cli = true
log_level = "INFO"
Run Code Online (Sandbox Code Playgroud)

删除日志记录后,CliRunner或 pytest(即test_main直接运行)不会触发ValueError,并且RuntimeError是引发的唯一异常。在 Docker 容器之外运行它也不会引发ValueError.

我怎样才能避免这个错误?

此代码可在GitHub 存储库上进行复制。我在容器中重现了这个问题continuum/miniconda3