You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is a problem with the logging module and py.test
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
func(*targs, **kargs)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/logging/__init__.py", line 1472, in shutdown
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
func(*targs, **kargs)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/logging/__init__.py", line 1472, in shutdown
h.flush()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/logging/__init__.py", line 740, in flush
self.stream.flush()
h.flush()
ValueError: I/O operation on closed file
It seems that if it runs with the '-s' flag it doesn't do this anymore.
============================================== 1 passed in 0.01 seconds ==============================================
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
func(_targs, *_kargs)
File "/usr/lib/python2.6/logging/init.py", line 1516, in shutdown
h.flush()
File "/usr/lib/python2.6/logging/init.py", line 762, in flush
self.stream.flush()
File "/usr/lib/python2.6/io.py", line 1488, in flush
self.buffer.flush()
ValueError: I/O operation on closed file.
Error in sys.exitfunc:
Traceback (most recent call last):
File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
func(_targs, *_kargs)
File "/usr/lib/python2.6/logging/init.py", line 1516, in shutdown
h.flush()
File "/usr/lib/python2.6/logging/init.py", line 762, in flush
self.stream.flush()
File "/usr/lib/python2.6/io.py", line 1488, in flush
self.buffer.flush()
ValueError: I/O operation on closed file.
Original comment byholger krekel (BitBucket: hpk42, GitHub: hpk42):
can you quickly try with "pip install -U -i http://pypi.testrun.org pytest" which should get you 2.0.3.dev3 and fix the issue? (To be honest, i am not yet sure why it is fixed, but i'd rather first check if it works for you as well)
I am hitting this with pytest 2.7.2 and python 2.7.2. The issue seems to occur if the logger I use is instantiated at the module level instead of inside a module function.
@nicoddemus I just tried putting together a small reproducer but at the moment I can only reproduce with my entire application. I will see if I can get something together for tomorrow.
@RonnyPfannschmidt I just hit the exact same issue as @shapiy above when testing if logging output of my package is correct. What is the correct usage pattern to do this with pytest?
What is the correct usage pattern to do this with pytest?
Short answer (IMO) is to use pytest-catchlog which provides great integration with the logging package, including a caplog fixture to capture logging output.
Thank you for your pointers! I have found if I leave stream=sys.stdout out of the call in the example, it works correctly: logging.basicConfig(level=logging.DEBUG). Interestingly, in my slightly more complex usecase it still didn't work correctly despite doing that.
In the end, I found that removing the stream handler manually afterwards was enough to make the tests run as expected:
Yeah I know I could do a fixture, but it's just for those two tests, if I use it more I'll definitely refactor it.
No, I didn't try pytest-catchlog at first, I didn't want to incur another dependency if I could avoid it.
This is still an issue with the latest pytest across tests (e.g. when one tests change the logging config and add a stream handler pointing to stdout, a subsequent test that doesn't setup logging and tries to write to logging will fail).
I think the issue boils down to the fact that if you set up a Stream Handler and you enable capsys the actual output stream will be a pytest stream that will be closed and thrown away at the next test in the test suite. So when a subsequent test tries to write to it you get this error. Adding the following fixture fixed this:
Should this be automatically done always by pytest? Granted for this to work ideally you would need to do it for all loggers, not just the root one. In this case, for me, this was enough as I was only set up a custom stream logger onto the root logger.
In an ideal world, I would expect though pytest to cleanup loggig configurations at the end tests that requested the caplog fixture.
Reacted by Géry Ogam, Kyle King, Timost, Karthik Vadla, Christopher Brousseau, Jonathan Rocher, Tom, a-zhenya, Sergei Dulikov, Mariano Ruiz and 2 more
Activity
pytestbot commentedon Jan 12, 2011
Original comment by holger krekel (BitBucket: hpk42, GitHub: hpk42):
fix issue14 : it was actually issue14 instead of issue8 that was fixed with
the older https://bitbucket.org/hpk42/pytest/changeset/1c3eb86502b3
please try out with the usual "pip install -i http://pypi.testrun.org -U pytest"
pytestbot commentedon Jan 28, 2011
Original comment by Adam Wagner (BitBucket: awagner83, GitHub: awagner83):
This fixes it for me.
pytestbot commentedon Jan 28, 2011
Original comment by Alfredo Deza (BitBucket: alfredodeza, GitHub: alfredodeza):
I can confirm this gets fixed with the update. Sorry for not reporting it sooner...
pytestbot commentedon Apr 9, 2011
Original comment by eduardo schettino (BitBucket: schettino72, GitHub: schettino72):
there is still a problem with this when used with capsys...
{{{
#!python
(py26)~/work/xxx$ cat bug14.py
import logging
def test_133(capsys):
logging.error('x')
(py26)~/work/xxx$ py.test bug14.py
================================================ test session starts =================================================
platform linux2 -- Python 2.6.6 -- pytest-2.0.2
collected 1 items
bug14.py .
============================================== 1 passed in 0.01 seconds ==============================================
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
func(_targs, *_kargs)
File "/usr/lib/python2.6/logging/init.py", line 1516, in shutdown
h.flush()
File "/usr/lib/python2.6/logging/init.py", line 762, in flush
self.stream.flush()
File "/usr/lib/python2.6/io.py", line 1488, in flush
self.buffer.flush()
ValueError: I/O operation on closed file.
Error in sys.exitfunc:
Traceback (most recent call last):
File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
func(_targs, *_kargs)
File "/usr/lib/python2.6/logging/init.py", line 1516, in shutdown
h.flush()
File "/usr/lib/python2.6/logging/init.py", line 762, in flush
self.stream.flush()
File "/usr/lib/python2.6/io.py", line 1488, in flush
self.buffer.flush()
ValueError: I/O operation on closed file.
}}}
pytestbot commentedon Apr 13, 2011
Original comment by holger krekel (BitBucket: hpk42, GitHub: hpk42):
can you quickly try with "pip install -U -i http://pypi.testrun.org pytest" which should get you 2.0.3.dev3 and fix the issue? (To be honest, i am not yet sure why it is fixed, but i'd rather first check if it works for you as well)
pytestbot commentedon May 27, 2011
Original comment by Ronny Pfannschmidt (BitBucket: RonnyPfannschmidt, GitHub: RonnyPfannschmidt):
still in trunk
pytestbot commentedon May 27, 2011
Original comment by Ronny Pfannschmidt (BitBucket: RonnyPfannschmidt, GitHub: RonnyPfannschmidt):
this would probably best be fixed by integrating logcapture into pytest
pytestbot commentedon Mar 25, 2013
Original comment by Ronny Pfannschmidt (BitBucket: RonnyPfannschmidt, GitHub: RonnyPfannschmidt):
as a extra note, it seems this is version specific to python2.7
pytestbot commentedon Sep 5, 2013
Original comment by holger krekel (BitBucket: hpk42, GitHub: hpk42):
i can't reproduce this with my py27/py33 and pytest-trunk anymore
pytestbot commentedon Sep 24, 2013
Original comment by Alfredo Deza (BitBucket: alfredodeza, GitHub: alfredodeza):
I am not consistently hitting this with Python 2.6
This only happens if I use
capsys. As soon as I stop using it the error goes away.jfitzpatrick99 commentedon Jul 9, 2015
I am hitting this with pytest 2.7.2 and python 2.7.2. The issue seems to occur if the logger I use is instantiated at the module level instead of inside a module function.
nicoddemus commentedon Jul 9, 2015
Hi @jfitzpatrick99, can you provide a small example which reproduces the problem?
jfitzpatrick99 commentedon Jul 9, 2015
@nicoddemus I just tried putting together a small reproducer but at the moment I can only reproduce with my entire application. I will see if I can get something together for tomorrow.
5 remaining items
RonnyPfannschmidt commentedon Oct 31, 2015
Passing a concrete captured stream that will be closed without removing its handler in teardown is bound to fail
Not even the pending merge of log capturing can fix that particular usage pattern
bilderbuchi commentedon Jan 11, 2017
@RonnyPfannschmidt I just hit the exact same issue as @shapiy above when testing if logging output of my package is correct. What is the correct usage pattern to do this with pytest?
nicoddemus commentedon Jan 12, 2017
Short answer (IMO) is to use pytest-catchlog which provides great integration with the
loggingpackage, including acaplogfixture to capture logging output.Long answer:
The problem is (please correct me @RonnyPfannschmidt):
sys.stdoutat this point is aStringIOobject installed by thecapsysfixture.You should "undo" what
logging.basicConfigdoes when the test finishes, possibly in a fixture or a try/finally block.bilderbuchi commentedon Jan 13, 2017
Thank you for your pointers! I have found if I leave
stream=sys.stdoutout of the call in the example, it works correctly:logging.basicConfig(level=logging.DEBUG). Interestingly, in my slightly more complex usecase it still didn't work correctly despite doing that.In the end, I found that removing the stream handler manually afterwards was enough to make the tests run as expected:
nicoddemus commentedon Jan 13, 2017
Glad you found a solution!
Notice that you can add that to a fixture and even make it
autouseso all tests do that logging setup/tear down automatically.Out of curiosity, did you try to use
pytest-catchlog?bilderbuchi commentedon Jan 13, 2017
Yeah I know I could do a fixture, but it's just for those two tests, if I use it more I'll definitely refactor it.
No, I didn't try pytest-catchlog at first, I didn't want to incur another dependency if I could avoid it.
nicoddemus commentedon Jan 13, 2017
OK, thanks!
bilderbuchi commentedon Jan 13, 2017
By the way, thank you for a great tool, all you pytest devs!
Now I'll shut up and stop spamming. ^.^
nicoddemus commentedon Jan 13, 2017
Thanks, we appreciate it. 😁
Fix spurious extra spaces after opening parentheses and in default ar…
gaborbernat commentedon Aug 15, 2019
@nicoddemus @asottile
This is still an issue with the latest pytest across tests (e.g. when one tests change the logging config and add a stream handler pointing to stdout, a subsequent test that doesn't setup logging and tries to write to logging will fail).
I think the issue boils down to the fact that if you set up a Stream Handler and you enable capsys the actual output stream will be a pytest stream that will be closed and thrown away at the next test in the test suite. So when a subsequent test tries to write to it you get this error. Adding the following fixture fixed this:
Should this be automatically done always by pytest? Granted for this to work ideally you would need to do it for all loggers, not just the root one. In this case, for me, this was enough as I was only set up a custom stream logger onto the root logger.
In an ideal world, I would expect though pytest to cleanup loggig configurations at the end tests that requested the caplog fixture.
nicoddemus commentedon Aug 15, 2019
@gaborbernat thanks for the detailed description! I've created #5743 to track this.