pytest: Warning integration breaks warnings.filterwarnings
SQLAlchemy CI is now broken due to the unconditional inclusion of pytest-warnings in py.test 3.1.0. I need at least to know how to disable this plugin entirely.
In our test suite we make use of the warnings filter internally in order to propagate our own warnings to errors. It seems like warnings.filter() is now non-functional when this plugin is installed.
Demo test case:
import warnings
class MyWarning(Warning):
pass
warnings.filterwarnings("error", category=MyWarning)
class TestWarnings(object):
def test_my_warning(self):
try:
warnings.warn(MyWarning("warn!"))
assert False
except MyWarning:
assert True
with py.test 3.0.7:
$ py.test test_warning.py
======================================================== test session starts ========================================================
platform linux2 -- Python 2.7.13, pytest-3.0.7, py-1.4.33, pluggy-0.4.0
rootdir: /home/classic/Desktop/tmp, inifile:
plugins: xdist-1.15.0, cov-2.4.0
collected 1 items
test_warning.py .
===================================================== 1 passed in 0.01 seconds ======================================================
with py.test 3.1.0:
$ py.test test_warning.py
======================================================== test session starts ========================================================
platform linux2 -- Python 2.7.13, pytest-3.1.0, py-1.4.33, pluggy-0.4.0
rootdir: /home/classic/Desktop/tmp, inifile:
plugins: xdist-1.15.0, cov-2.4.0
collected 1 items
test_warning.py F
============================================================= FAILURES ==============================================================
___________________________________________________ TestWarnings.test_my_warning ____________________________________________________
self = <test_warning.TestWarnings object at 0x7fecb08a5290>
def test_my_warning(self):
try:
warnings.warn(MyWarning("warn!"))
> assert False
E assert False
test_warning.py:12: AssertionError
========================================================= warnings summary ==========================================================
test_warning.py::TestWarnings::()::test_my_warning
/home/classic/Desktop/tmp/test_warning.py:11: MyWarning: warn!
warnings.warn(MyWarning("warn!"))
-- Docs: http://doc.pytest.org/en/latest/warnings.html
=============================================== 1 failed, 1 warnings in 0.03 seconds ================================================
I have tried everything I can think of with the new -W flag, disable-warnings, no luck.
Please advise on the correct options to allow Python stdlib warnings.filter() to work again, thanks!
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 30 (21 by maintainers)
Commits related to this issue
- - pin py.test at 3.0.7 due to https://github.com/pytest-dev/pytest/issues/2430 Change-Id: I587282da141aa6ea92f944eeb4c9e5782d0b5f29 (cherry picked from commit eed7888f85a4255390e2522dbd428cbfe7a08bab... — committed to zzzeek/sqlalchemy by zzzeek 7 years ago
- - pin py.test at 3.0.7 due to https://github.com/pytest-dev/pytest/issues/2430 Change-Id: I587282da141aa6ea92f944eeb4c9e5782d0b5f29 — committed to zzzeek/sqlalchemy by zzzeek 7 years ago
- - add option to disable py.test warnings plugin; lift cap on py.test. references: https://github.com/pytest-dev/pytest/issues/2430 Change-Id: Ieb8a6258ba1d15efa570d9cda2b51cf021499a23 — committed to zzzeek/sqlalchemy by zzzeek 7 years ago
- - add option to disable py.test warnings plugin; lift cap on py.test. references: https://github.com/pytest-dev/pytest/issues/2430 Change-Id: Ieb8a6258ba1d15efa570d9cda2b51cf021499a23 (cherry picked ... — committed to zzzeek/sqlalchemy by zzzeek 7 years ago
- Fix errors in the test suite due to pytest warning changes This is causing CI failures for some builds. This is really a pytest bug (https://github.com/pytest-dev/pytest/issues/2430), but working ar... — committed to shoyer/xarray by shoyer 7 years ago
- Fix errors in the test suite due to pytest warning changes (#1423) * Fix errors in the test suite due to pytest warning changes This is causing CI failures for some builds. This is really a pyt... — committed to pydata/xarray by shoyer 7 years ago
- Disable pytest messing with warnings. We may be able to remove this if pytest resolves pytest-dev/pytest#2430 — committed to Lukasa/requests by Lukasa 7 years ago
- Disable pytest messing with warnings. We may be able to remove this if pytest resolves pytest-dev/pytest#2430 — committed to Lukasa/requests by Lukasa 7 years ago
- Warn that warning-capture can break existing suites in the docs and CHANGELOG Related to discussion in #2430 — committed to nicoddemus/pytest by nicoddemus 7 years ago
- Make warnings plugin opt-in Fix #2430 — committed to nicoddemus/pytest by nicoddemus 7 years ago
- No longer mess with warning filters during warnings capture Fix #2430 — committed to nicoddemus/pytest by nicoddemus 7 years ago
- No longer override existing warning filters during warnings capture Fix #2430 — committed to nicoddemus/pytest by nicoddemus 7 years ago
- No longer override existing warning filters during warnings capture Fix #2430 — committed to nicoddemus/pytest by nicoddemus 7 years ago
- No longer override existing warning filters during warnings capture Fix #2430 — committed to nicoddemus/pytest by nicoddemus 7 years ago
- No longer override existing warning filters during warnings capture Fix #2430 — committed to nicoddemus/pytest by nicoddemus 7 years ago
- No longer override existing warning filters during warnings capture Fix #2430 — committed to nicoddemus/pytest by nicoddemus 7 years ago
@zzzeek you can disable the warnings plugin by passing
-p no:warnings
; this will disable the plugin completely and you should get green builds again. You can choose to add this to yourpytest.ini
file:As for the problem itself, I will take a more careful look later.
@zzzeek thanks for the comprehensive and detailed response! I really appreciate your time to write it, it is invaluable to us to get the whole picture. 👍
We (the core team) feel that most warnings go unnoticed, specially deprecation warnings where action about the deprecation is usually taken only when things actualy brake, long after the initial deprecation warnings started to be emited. We made good strides towards this by always showing that some warnings were emitted in the summary (“X pytest-warnings”), and later on by finally deciding to always show warnings regardless if the user opt-in to see them (although it was easy to opt-out). Given this experience, our general conclusion is that pytest should display warnings more proemiently because otherwise very few users will bother to opt-in to see them.
So we decided to introduce the pytest-warnings plugin to the core: improve communication on deprecated pytest features and to give users ample time to deal with them at their own pace, but also important for warnings from libraries in general.
Now, your test suite has an advanced treatment of warnings and that unfortunately conflicts with pytest’s own warning treatment. That’s unfortunate but also understandable, and I can see where the same problem could happen with other internal plugins: the terminal plugin and pytest-xdist comes to mind and I also can imagine a test suite which does its own stdin/stdout capture can conflict with the standard pytest capture for example.
Given that pytest’s warning handling is a problem only in the few advanced and rare cases, having it on by default and in consequence benefit the larger user base is the best long term decision, specially if it is easily opted out.
As @The-Compiler mentioned, this is also apparently the approach taken by the standard library:
(This is the original example posted, only adapted to standard unittest)
This further makes me believe that we are following the correct course of action: the most value out of the box for most users, with an easy way to opt-out when it is problematic. Of course we should improve the documentation on how to op-out if this is the instance we will ultimately go with.
Well that’s the full picture as I see it. Would love to hear other’s opinions on this.
Having a warning system is hugely useful. Defaulting to all warnings on is not.
Even if everyone decides to leave this feature in, it’s broken. Only reasonable course of action is to back it out until it’s more thoroughly tested.ASAP
1. This code shows a warning that should not be on by default:
test_something.py
2. --strict doesn’t work
@zzzeek
This is a very valid point, thanks. This seems like a feature request though, would you like to create a new issue for it so we can track it?
Python does hide DeprecationWarnings (and some others?) by default, because it doesn’t want to confront users with those when they’re simply using a library.
Test runners should turn them on (like unittest.py does too), so they aren’t simply ignored.
@The-Compiler this is not about showing vs hiding, but about not altering the warnings subsystem unless requested
python warnings are inherently state-full, and people register different actions for different warnings any test-runner that changes anything by default is broken
note that warnings are not hidden by default, but library authors may choose to hide/error on certain errors, or decide to show some errors only once
changing those behaviours inwarranted breaks code
any choice we make breaks some peoples expectations, we should jsut let the people decide
we simply should not do anying per default