[Python-Dev] Py3k DeprecationWarning in stdlib

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.test_support" 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 catch_warning 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