Using pytest, sometimes does not capture stderr

Cameron Simpson cs at cskk.id.au
Sun Apr 4 23:43:50 EDT 2021


On 05Apr2021 13:28, David <bouncingcats at gmail.com> wrote:
>I have just begun using pytest at a basic level and I am
>seeing behaviour that I do not understand.
>
>My platform is Debian 10.9
>
>There are 3 files involved, contents are provided below, and attached.
>- module_1.py passes the test as expected
>- module_2.py has a tiny change, and fails unexpectedly.
>- my_test.py runs the same test on each module
>
>Can anyone explain why the module_2.py test fails?
>Is it because stderr during module import is not the same as during test?
>Is it something to do with mutable defaults?
>How to investigate this?
>And how can I get the test to pass without changing module_2?
>
>Thanks :)
>
>#---------------------------------------------------------------------
>Here is the file module_1.py:
>#!/usr/bin/python3
>import sys
>def msg(*args):
>    print(*args, file=sys.stderr)
>
>#---------------------------------------------------------------------
>Here is the file module_2.py:
>#!/usr/bin/python3
>import sys
>MSG_DESTINATION = sys.stderr
>def msg(*args):
>    print(*args, file=MSG_DESTINATION)

The code in module_2.py runs at different times.

When it is imported, sys.stderr is the OS-provided stderr. That 
reference is kept in MSG_DESTINATION.

Then your test code runs, and changes sys.stderr. It then runs msg(), 
which writes to the _original_ sys.stderr as preserved by 
MSG_DESTINATION. Thus not captured.

By contrast, module_1.py looks up sys.stderr inside msg(), and finds the 
new one the code harness put at sys.stderr. So it writes to the thing 
that captures stuff.

Cheers,
Cameron Simpson <cs at cskk.id.au>


More information about the Python-list mailing list