[Python-Dev] Py3k DeprecationWarning in stdlib (original) (raw)

Jean-Paul Calderone exarkun at divmod.com
Thu Jun 26 16:46:46 CEST 2008


On Thu, 26 Jun 2008 23:56:23 +1000, Nick Coghlan <ncoghlan at gmail.com> wrote:

[snip]

Ok, then we're back to there being no supported way to write tests that need to intercept warnings. Twisted has already suffered from this (JP reports that Twisted's assertWarns is broken in 2.6), and I doubt it's alone. So I guess I am filing a bug after all... :) Yeah - Brett's correct that everything under "test.testsupport" should really be formally undocumented. It's mostly a place for code that reflects "things we do a lot in our unit tests and are tired of repeating" rather than "this is a good API that we want to support forever and encourage other people to use". However, if other folks turn out to have similar needs, then it may be possible to add something to unittest to support it. However, given that the beta deadline has already passed, you may need to use similar hackery to that used by catchwarning and replace warnings.showwarning with a test function that saves the raised exception (it also wouldn't be hard to enhance it a bit to handle more than a single warning).

We don't use showwarning because in order to reliably catch warnings that way, it's necessary to rely on even more private implementation details of the warning system.

Consider this:

from warnings import warn
from test.test_support import catch_warning

def f():
    warn("foo")

def test():
    with catch_warning() as w:
        f()
        assert str(w.message) == "foo", "%r != %r" % (w.message, "foo")

test()
test()

The first assertion passes (by the way, I don't understand why w.message isn't the message passed to warn, but is instead an instance of UserWarning) but the second assertion fails. A more subtle example might include two functions, the first of which is deprecated and called by the second, and one test for each of them. Now the test for the warning will only pass if it runs before the other test; if they accidentally run in the other order, you won't see the warning, so as far as I can tell, you can't reliably write a unit test for warnings using catch_warning.

The real problem with testing many uses of the warning system is that it doesn't expose enough public APIs for this to be possible. You have to use APIs which are, apparently, private (such as warn_explicit).

Jean-Paul



More information about the Python-Dev mailing list