[Python-checkins] r60872 - in python/trunk: Lib/test/output/test_logging Lib/test/test_logging.py Misc/ACKS Misc/NEWS

brett.cannon python-checkins at python.org
Sun Feb 17 02:59:19 CET 2008


Author: brett.cannon
Date: Sun Feb 17 02:59:18 2008
New Revision: 60872

Removed:
   python/trunk/Lib/test/output/test_logging
Modified:
   python/trunk/Lib/test/test_logging.py
   python/trunk/Misc/ACKS
   python/trunk/Misc/NEWS
Log:
Move test_logging over to doctest.

Thanks to Christopher White from GHOP.


Deleted: /python/trunk/Lib/test/output/test_logging
==============================================================================
--- /python/trunk/Lib/test/output/test_logging	Sun Feb 17 02:59:18 2008
+++ (empty file)
@@ -1,525 +0,0 @@
-test_logging
--- log_test0  begin  ---------------------------------------------------
-CRITICAL:ERR:Message 0
-ERROR:ERR:Message 1
-CRITICAL:INF:Message 2
-ERROR:INF:Message 3
-WARNING:INF:Message 4
-INFO:INF:Message 5
-CRITICAL:INF.UNDEF:Message 6
-ERROR:INF.UNDEF:Message 7
-WARNING:INF.UNDEF:Message 8
-INFO:INF.UNDEF:Message 9
-CRITICAL:INF.ERR:Message 10
-ERROR:INF.ERR:Message 11
-CRITICAL:INF.ERR.UNDEF:Message 12
-ERROR:INF.ERR.UNDEF:Message 13
-CRITICAL:DEB:Message 14
-ERROR:DEB:Message 15
-WARNING:DEB:Message 16
-INFO:DEB:Message 17
-DEBUG:DEB:Message 18
-CRITICAL:UNDEF:Message 19
-ERROR:UNDEF:Message 20
-WARNING:UNDEF:Message 21
-INFO:UNDEF:Message 22
-CRITICAL:INF.BADPARENT.UNDEF:Message 23
-CRITICAL:INF.BADPARENT:Message 24
-INFO:INF:Finish up, it's closing time. Messages should bear numbers 0 through 24.
--- log_test0  end    ---------------------------------------------------
--- log_test1  begin  ---------------------------------------------------
--- setting logging level to 'Boring' -----
-Boring:root:This should only be seen at the 'Boring' logging level (or lower)
-Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
-Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Chatterbox' -----
-Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
-Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Garrulous' -----
-Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Talkative' -----
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Verbose' -----
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Sociable' -----
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Effusive' -----
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Terse' -----
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Taciturn' -----
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Silent' -----
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- Filtering at handler level to SOCIABLE --
--- setting logging level to 'Boring' -----
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Chatterbox' -----
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Garrulous' -----
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Talkative' -----
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Verbose' -----
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Sociable' -----
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Effusive' -----
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Terse' -----
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Taciturn' -----
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Silent' -----
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- Filtering using GARRULOUS filter --
--- setting logging level to 'Boring' -----
-Boring:root:This should only be seen at the 'Boring' logging level (or lower)
-Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Chatterbox' -----
-Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Garrulous' -----
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Talkative' -----
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Verbose' -----
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Sociable' -----
-Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Effusive' -----
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Terse' -----
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Taciturn' -----
-Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Silent' -----
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- Filtering using specific filter for SOCIABLE, TACITURN --
--- setting logging level to 'Boring' -----
-Boring:root:This should only be seen at the 'Boring' logging level (or lower)
-Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Chatterbox' -----
-Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Garrulous' -----
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Talkative' -----
-Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Verbose' -----
-Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Sociable' -----
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Effusive' -----
-Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Terse' -----
-Terse:root:This should only be seen at the 'Terse' logging level (or lower)
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Taciturn' -----
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- setting logging level to 'Silent' -----
-Silent:root:This should only be seen at the 'Silent' logging level (or lower)
--- log_test1  end    ---------------------------------------------------
--- log_test2  begin  ---------------------------------------------------
--- logging at DEBUG, nothing should be seen yet --
--- logging at INFO, nothing should be seen yet --
--- logging at WARNING, 3 messages should be seen --
-DEBUG:root:Debug message
-INFO:root:Info message
-WARNING:root:Warn message
--- logging 0 at INFO, messages should be seen every 10 events --
--- logging 1 at INFO, messages should be seen every 10 events --
--- logging 2 at INFO, messages should be seen every 10 events --
--- logging 3 at INFO, messages should be seen every 10 events --
--- logging 4 at INFO, messages should be seen every 10 events --
--- logging 5 at INFO, messages should be seen every 10 events --
--- logging 6 at INFO, messages should be seen every 10 events --
--- logging 7 at INFO, messages should be seen every 10 events --
--- logging 8 at INFO, messages should be seen every 10 events --
--- logging 9 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 0
-INFO:root:Info index = 1
-INFO:root:Info index = 2
-INFO:root:Info index = 3
-INFO:root:Info index = 4
-INFO:root:Info index = 5
-INFO:root:Info index = 6
-INFO:root:Info index = 7
-INFO:root:Info index = 8
-INFO:root:Info index = 9
--- logging 10 at INFO, messages should be seen every 10 events --
--- logging 11 at INFO, messages should be seen every 10 events --
--- logging 12 at INFO, messages should be seen every 10 events --
--- logging 13 at INFO, messages should be seen every 10 events --
--- logging 14 at INFO, messages should be seen every 10 events --
--- logging 15 at INFO, messages should be seen every 10 events --
--- logging 16 at INFO, messages should be seen every 10 events --
--- logging 17 at INFO, messages should be seen every 10 events --
--- logging 18 at INFO, messages should be seen every 10 events --
--- logging 19 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 10
-INFO:root:Info index = 11
-INFO:root:Info index = 12
-INFO:root:Info index = 13
-INFO:root:Info index = 14
-INFO:root:Info index = 15
-INFO:root:Info index = 16
-INFO:root:Info index = 17
-INFO:root:Info index = 18
-INFO:root:Info index = 19
--- logging 20 at INFO, messages should be seen every 10 events --
--- logging 21 at INFO, messages should be seen every 10 events --
--- logging 22 at INFO, messages should be seen every 10 events --
--- logging 23 at INFO, messages should be seen every 10 events --
--- logging 24 at INFO, messages should be seen every 10 events --
--- logging 25 at INFO, messages should be seen every 10 events --
--- logging 26 at INFO, messages should be seen every 10 events --
--- logging 27 at INFO, messages should be seen every 10 events --
--- logging 28 at INFO, messages should be seen every 10 events --
--- logging 29 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 20
-INFO:root:Info index = 21
-INFO:root:Info index = 22
-INFO:root:Info index = 23
-INFO:root:Info index = 24
-INFO:root:Info index = 25
-INFO:root:Info index = 26
-INFO:root:Info index = 27
-INFO:root:Info index = 28
-INFO:root:Info index = 29
--- logging 30 at INFO, messages should be seen every 10 events --
--- logging 31 at INFO, messages should be seen every 10 events --
--- logging 32 at INFO, messages should be seen every 10 events --
--- logging 33 at INFO, messages should be seen every 10 events --
--- logging 34 at INFO, messages should be seen every 10 events --
--- logging 35 at INFO, messages should be seen every 10 events --
--- logging 36 at INFO, messages should be seen every 10 events --
--- logging 37 at INFO, messages should be seen every 10 events --
--- logging 38 at INFO, messages should be seen every 10 events --
--- logging 39 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 30
-INFO:root:Info index = 31
-INFO:root:Info index = 32
-INFO:root:Info index = 33
-INFO:root:Info index = 34
-INFO:root:Info index = 35
-INFO:root:Info index = 36
-INFO:root:Info index = 37
-INFO:root:Info index = 38
-INFO:root:Info index = 39
--- logging 40 at INFO, messages should be seen every 10 events --
--- logging 41 at INFO, messages should be seen every 10 events --
--- logging 42 at INFO, messages should be seen every 10 events --
--- logging 43 at INFO, messages should be seen every 10 events --
--- logging 44 at INFO, messages should be seen every 10 events --
--- logging 45 at INFO, messages should be seen every 10 events --
--- logging 46 at INFO, messages should be seen every 10 events --
--- logging 47 at INFO, messages should be seen every 10 events --
--- logging 48 at INFO, messages should be seen every 10 events --
--- logging 49 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 40
-INFO:root:Info index = 41
-INFO:root:Info index = 42
-INFO:root:Info index = 43
-INFO:root:Info index = 44
-INFO:root:Info index = 45
-INFO:root:Info index = 46
-INFO:root:Info index = 47
-INFO:root:Info index = 48
-INFO:root:Info index = 49
--- logging 50 at INFO, messages should be seen every 10 events --
--- logging 51 at INFO, messages should be seen every 10 events --
--- logging 52 at INFO, messages should be seen every 10 events --
--- logging 53 at INFO, messages should be seen every 10 events --
--- logging 54 at INFO, messages should be seen every 10 events --
--- logging 55 at INFO, messages should be seen every 10 events --
--- logging 56 at INFO, messages should be seen every 10 events --
--- logging 57 at INFO, messages should be seen every 10 events --
--- logging 58 at INFO, messages should be seen every 10 events --
--- logging 59 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 50
-INFO:root:Info index = 51
-INFO:root:Info index = 52
-INFO:root:Info index = 53
-INFO:root:Info index = 54
-INFO:root:Info index = 55
-INFO:root:Info index = 56
-INFO:root:Info index = 57
-INFO:root:Info index = 58
-INFO:root:Info index = 59
--- logging 60 at INFO, messages should be seen every 10 events --
--- logging 61 at INFO, messages should be seen every 10 events --
--- logging 62 at INFO, messages should be seen every 10 events --
--- logging 63 at INFO, messages should be seen every 10 events --
--- logging 64 at INFO, messages should be seen every 10 events --
--- logging 65 at INFO, messages should be seen every 10 events --
--- logging 66 at INFO, messages should be seen every 10 events --
--- logging 67 at INFO, messages should be seen every 10 events --
--- logging 68 at INFO, messages should be seen every 10 events --
--- logging 69 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 60
-INFO:root:Info index = 61
-INFO:root:Info index = 62
-INFO:root:Info index = 63
-INFO:root:Info index = 64
-INFO:root:Info index = 65
-INFO:root:Info index = 66
-INFO:root:Info index = 67
-INFO:root:Info index = 68
-INFO:root:Info index = 69
--- logging 70 at INFO, messages should be seen every 10 events --
--- logging 71 at INFO, messages should be seen every 10 events --
--- logging 72 at INFO, messages should be seen every 10 events --
--- logging 73 at INFO, messages should be seen every 10 events --
--- logging 74 at INFO, messages should be seen every 10 events --
--- logging 75 at INFO, messages should be seen every 10 events --
--- logging 76 at INFO, messages should be seen every 10 events --
--- logging 77 at INFO, messages should be seen every 10 events --
--- logging 78 at INFO, messages should be seen every 10 events --
--- logging 79 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 70
-INFO:root:Info index = 71
-INFO:root:Info index = 72
-INFO:root:Info index = 73
-INFO:root:Info index = 74
-INFO:root:Info index = 75
-INFO:root:Info index = 76
-INFO:root:Info index = 77
-INFO:root:Info index = 78
-INFO:root:Info index = 79
--- logging 80 at INFO, messages should be seen every 10 events --
--- logging 81 at INFO, messages should be seen every 10 events --
--- logging 82 at INFO, messages should be seen every 10 events --
--- logging 83 at INFO, messages should be seen every 10 events --
--- logging 84 at INFO, messages should be seen every 10 events --
--- logging 85 at INFO, messages should be seen every 10 events --
--- logging 86 at INFO, messages should be seen every 10 events --
--- logging 87 at INFO, messages should be seen every 10 events --
--- logging 88 at INFO, messages should be seen every 10 events --
--- logging 89 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 80
-INFO:root:Info index = 81
-INFO:root:Info index = 82
-INFO:root:Info index = 83
-INFO:root:Info index = 84
-INFO:root:Info index = 85
-INFO:root:Info index = 86
-INFO:root:Info index = 87
-INFO:root:Info index = 88
-INFO:root:Info index = 89
--- logging 90 at INFO, messages should be seen every 10 events --
--- logging 91 at INFO, messages should be seen every 10 events --
--- logging 92 at INFO, messages should be seen every 10 events --
--- logging 93 at INFO, messages should be seen every 10 events --
--- logging 94 at INFO, messages should be seen every 10 events --
--- logging 95 at INFO, messages should be seen every 10 events --
--- logging 96 at INFO, messages should be seen every 10 events --
--- logging 97 at INFO, messages should be seen every 10 events --
--- logging 98 at INFO, messages should be seen every 10 events --
--- logging 99 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 90
-INFO:root:Info index = 91
-INFO:root:Info index = 92
-INFO:root:Info index = 93
-INFO:root:Info index = 94
-INFO:root:Info index = 95
-INFO:root:Info index = 96
-INFO:root:Info index = 97
-INFO:root:Info index = 98
-INFO:root:Info index = 99
--- logging 100 at INFO, messages should be seen every 10 events --
--- logging 101 at INFO, messages should be seen every 10 events --
-INFO:root:Info index = 100
-INFO:root:Info index = 101
--- log_test2  end    ---------------------------------------------------
--- log_test3  begin  ---------------------------------------------------
-Unfiltered...
-INFO:a:Info 1
-INFO:a.b:Info 2
-INFO:a.c:Info 3
-INFO:a.b.c:Info 4
-INFO:a.b.c.d:Info 5
-INFO:a.bb.c:Info 6
-INFO:b:Info 7
-INFO:b.a:Info 8
-INFO:c.a.b:Info 9
-INFO:a.bb:Info 10
-Filtered with 'a.b'...
-INFO:a.b:Info 2
-INFO:a.b.c:Info 4
-INFO:a.b.c.d:Info 5
--- log_test3  end    ---------------------------------------------------
--- log_test4  begin  ---------------------------------------------------
-config0: ok.
-config1: ok.
-config2: <type 'exceptions.AttributeError'>
-config3: <type 'exceptions.KeyError'>
--- log_test4  end    ---------------------------------------------------
--- log_test5  begin  ---------------------------------------------------
-ERROR:root:just testing
-<type 'exceptions.KeyError'>... Don't panic!
--- log_test5  end    ---------------------------------------------------
--- logrecv output begin  ---------------------------------------------------
-ERR -> CRITICAL: Message 0 (via logrecv.tcp.ERR)
-ERR -> ERROR: Message 1 (via logrecv.tcp.ERR)
-INF -> CRITICAL: Message 2 (via logrecv.tcp.INF)
-INF -> ERROR: Message 3 (via logrecv.tcp.INF)
-INF -> WARNING: Message 4 (via logrecv.tcp.INF)
-INF -> INFO: Message 5 (via logrecv.tcp.INF)
-INF.UNDEF -> CRITICAL: Message 6 (via logrecv.tcp.INF.UNDEF)
-INF.UNDEF -> ERROR: Message 7 (via logrecv.tcp.INF.UNDEF)
-INF.UNDEF -> WARNING: Message 8 (via logrecv.tcp.INF.UNDEF)
-INF.UNDEF -> INFO: Message 9 (via logrecv.tcp.INF.UNDEF)
-INF.ERR -> CRITICAL: Message 10 (via logrecv.tcp.INF.ERR)
-INF.ERR -> ERROR: Message 11 (via logrecv.tcp.INF.ERR)
-INF.ERR.UNDEF -> CRITICAL: Message 12 (via logrecv.tcp.INF.ERR.UNDEF)
-INF.ERR.UNDEF -> ERROR: Message 13 (via logrecv.tcp.INF.ERR.UNDEF)
-DEB -> CRITICAL: Message 14 (via logrecv.tcp.DEB)
-DEB -> ERROR: Message 15 (via logrecv.tcp.DEB)
-DEB -> WARNING: Message 16 (via logrecv.tcp.DEB)
-DEB -> INFO: Message 17 (via logrecv.tcp.DEB)
-DEB -> DEBUG: Message 18 (via logrecv.tcp.DEB)
-UNDEF -> CRITICAL: Message 19 (via logrecv.tcp.UNDEF)
-UNDEF -> ERROR: Message 20 (via logrecv.tcp.UNDEF)
-UNDEF -> WARNING: Message 21 (via logrecv.tcp.UNDEF)
-UNDEF -> INFO: Message 22 (via logrecv.tcp.UNDEF)
-INF.BADPARENT.UNDEF -> CRITICAL: Message 23 (via logrecv.tcp.INF.BADPARENT.UNDEF)
-INF.BADPARENT -> CRITICAL: Message 24 (via logrecv.tcp.INF.BADPARENT)
-INF -> INFO: Finish up, it's closing time. Messages should bear numbers 0 through 24. (via logrecv.tcp.INF)
--- logrecv output end    ---------------------------------------------------

Modified: python/trunk/Lib/test/test_logging.py
==============================================================================
--- python/trunk/Lib/test/test_logging.py	(original)
+++ python/trunk/Lib/test/test_logging.py	Sun Feb 17 02:59:18 2008
@@ -1,38 +1,1882 @@
 #!/usr/bin/env python
-#
-# Copyright 2001-2004 by Vinay Sajip. All Rights Reserved.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose and without fee is hereby granted,
-# provided that the above copyright notice appear in all copies and that
-# both that copyright notice and this permission notice appear in
-# supporting documentation, and that the name of Vinay Sajip
-# not be used in advertising or publicity pertaining to distribution
-# of the software without specific, written prior permission.
-# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-# This file is part of the Python logging distribution. See
-# http://www.red-dove.com/python_logging.html
-#
-"""Test harness for the logging module. Run all tests.
+"""
+Test 0
+======
+
+Some preliminaries:
+>>> import sys
+>>> import logging
+>>> def nextmessage():
+...    global msgcount
+...    rv = "Message %d" % msgcount
+...    msgcount = msgcount + 1
+...    return rv
+
+Set a few variables, then go through the logger autoconfig and set the default threshold.
+>>> msgcount = 0
+>>> FINISH_UP = "Finish up, it's closing time. Messages should bear numbers 0 through 24."
+>>> logging.basicConfig(stream=sys.stdout)
+>>> rootLogger = logging.getLogger("")
+>>> rootLogger.setLevel(logging.DEBUG)
+
+Now, create a bunch of loggers, and set their thresholds.
+>>> ERR = logging.getLogger("ERR0")
+>>> ERR.setLevel(logging.ERROR)
+>>> INF = logging.getLogger("INFO0")
+>>> INF.setLevel(logging.INFO)
+>>> INF_ERR  = logging.getLogger("INFO0.ERR")
+>>> INF_ERR.setLevel(logging.ERROR)
+>>> DEB = logging.getLogger("DEB0")
+>>> DEB.setLevel(logging.DEBUG)
+>>> INF_UNDEF = logging.getLogger("INFO0.UNDEF")
+>>> INF_ERR_UNDEF = logging.getLogger("INFO0.ERR.UNDEF")
+>>> UNDEF = logging.getLogger("UNDEF0")
+>>> GRANDCHILD = logging.getLogger("INFO0.BADPARENT.UNDEF")
+>>> CHILD = logging.getLogger("INFO0.BADPARENT")
+
+
+And finally, run all the tests.
+
+>>> ERR.log(logging.FATAL, nextmessage())
+CRITICAL:ERR0:Message 0
+
+>>> ERR.error(nextmessage())
+ERROR:ERR0:Message 1
+
+>>> INF.log(logging.FATAL, nextmessage())
+CRITICAL:INFO0:Message 2
+
+>>> INF.error(nextmessage())
+ERROR:INFO0:Message 3
+
+>>> INF.warn(nextmessage())
+WARNING:INFO0:Message 4
+
+>>> INF.info(nextmessage())
+INFO:INFO0:Message 5
+
+>>> INF_UNDEF.log(logging.FATAL, nextmessage())
+CRITICAL:INFO0.UNDEF:Message 6
+
+>>> INF_UNDEF.error(nextmessage())
+ERROR:INFO0.UNDEF:Message 7
+
+>>> INF_UNDEF.warn (nextmessage())
+WARNING:INFO0.UNDEF:Message 8
+
+>>> INF_UNDEF.info (nextmessage())
+INFO:INFO0.UNDEF:Message 9
+
+>>> INF_ERR.log(logging.FATAL, nextmessage())
+CRITICAL:INFO0.ERR:Message 10
+
+>>> INF_ERR.error(nextmessage())
+ERROR:INFO0.ERR:Message 11
+
+>>> INF_ERR_UNDEF.log(logging.FATAL, nextmessage())
+CRITICAL:INFO0.ERR.UNDEF:Message 12
+
+>>> INF_ERR_UNDEF.error(nextmessage())
+ERROR:INFO0.ERR.UNDEF:Message 13
+
+>>> DEB.log(logging.FATAL, nextmessage())
+CRITICAL:DEB0:Message 14
+
+>>> DEB.error(nextmessage())
+ERROR:DEB0:Message 15
+
+>>> DEB.warn (nextmessage())
+WARNING:DEB0:Message 16
+
+>>> DEB.info (nextmessage())
+INFO:DEB0:Message 17
+
+>>> DEB.debug(nextmessage())
+DEBUG:DEB0:Message 18
+
+>>> UNDEF.log(logging.FATAL, nextmessage())
+CRITICAL:UNDEF0:Message 19
+
+>>> UNDEF.error(nextmessage())
+ERROR:UNDEF0:Message 20
+
+>>> UNDEF.warn (nextmessage())
+WARNING:UNDEF0:Message 21
+
+>>> UNDEF.info (nextmessage())
+INFO:UNDEF0:Message 22
+
+>>> GRANDCHILD.log(logging.FATAL, nextmessage())
+CRITICAL:INFO0.BADPARENT.UNDEF:Message 23
+
+>>> CHILD.log(logging.FATAL, nextmessage())
+CRITICAL:INFO0.BADPARENT:Message 24
+
+These should not log:
+
+>>> ERR.warn(nextmessage())
+
+>>> ERR.info(nextmessage())
+
+>>> ERR.debug(nextmessage())
+
+>>> INF.debug(nextmessage())
+
+>>> INF_UNDEF.debug(nextmessage())
+
+>>> INF_ERR.warn(nextmessage())
+
+>>> INF_ERR.info(nextmessage())
+
+>>> INF_ERR.debug(nextmessage())
+
+>>> INF_ERR_UNDEF.warn(nextmessage())
+
+>>> INF_ERR_UNDEF.info(nextmessage())
+
+>>> INF_ERR_UNDEF.debug(nextmessage())
+
+>>> INF.info(FINISH_UP)
+INFO:INFO0:Finish up, it's closing time. Messages should bear numbers 0 through 24.
+
+Test 1
+======
+
+>>> import sys, logging
+>>> logging.basicConfig(stream=sys.stdout)
+
+First, we define our levels. There can be as many as you want - the only
+limitations are that they should be integers, the lowest should be > 0 and
+larger values mean less information being logged. If you need specific
+level values which do not fit into these limitations, you can use a
+mapping dictionary to convert between your application levels and the
+logging system.
+
+>>> SILENT      = 10
+>>> TACITURN    = 9
+>>> TERSE       = 8
+>>> EFFUSIVE    = 7
+>>> SOCIABLE    = 6
+>>> VERBOSE     = 5
+>>> TALKATIVE   = 4
+>>> GARRULOUS   = 3
+>>> CHATTERBOX  = 2
+>>> BORING      = 1
+>>> LEVEL_RANGE = range(BORING, SILENT + 1)
+
+
+Next, we define names for our levels. You don't need to do this - in which
+  case the system will use "Level n" to denote the text for the level.
+'
+
+
+>>> my_logging_levels = {
+...     SILENT      : 'SILENT',
+...     TACITURN    : 'TACITURN',
+...     TERSE       : 'TERSE',
+...     EFFUSIVE    : 'EFFUSIVE',
+...     SOCIABLE    : 'SOCIABLE',
+...     VERBOSE     : 'VERBOSE',
+...     TALKATIVE   : 'TALKATIVE',
+...     GARRULOUS   : 'GARRULOUS',
+...     CHATTERBOX  : 'CHATTERBOX',
+...     BORING      : 'BORING',
+...     }
+
+
+Now, to demonstrate filtering: suppose for some perverse reason we only
+want to print out all except GARRULOUS messages. We create a filter for
+this purpose...
+
+>>> class SpecificLevelFilter(logging.Filter):
+...     def __init__(self, lvl):
+...         self.level = lvl
+...
+...     def filter(self, record):
+...         return self.level != record.levelno
+
+>>> class GarrulousFilter(SpecificLevelFilter):
+...     def __init__(self):
+...         SpecificLevelFilter.__init__(self, GARRULOUS)
+
+
+Now, demonstrate filtering at the logger. This time, use a filter
+which excludes SOCIABLE and TACITURN messages. Note that GARRULOUS events
+are still excluded.
+
+
+>>> class VerySpecificFilter(logging.Filter):
+...     def filter(self, record):
+...         return record.levelno not in [SOCIABLE, TACITURN]
+
+>>> SHOULD1 = "This should only be seen at the '%s' logging level (or lower)"
+
+Configure the logger, and tell the logging system to associate names with our levels.
+>>> logging.basicConfig(stream=sys.stdout)
+>>> rootLogger = logging.getLogger("")
+>>> rootLogger.setLevel(logging.DEBUG)
+>>> for lvl in my_logging_levels.keys():
+...    logging.addLevelName(lvl, my_logging_levels[lvl])
+>>> log = logging.getLogger("")
+>>> hdlr = log.handlers[0]
+>>> from test_logging import message
+
+Set the logging level to each different value and call the utility
+function to log events. In the output, you should see that each time
+round the loop, the number of logging events which are actually output
+decreases.
+
+>>> log.setLevel(1)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+BORING:root:This should only be seen at the '1' logging level (or lower)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+CHATTERBOX:root:This should only be seen at the '2' logging level (or lower)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+GARRULOUS:root:This should only be seen at the '3' logging level (or lower)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(2)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+CHATTERBOX:root:This should only be seen at the '2' logging level (or lower)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+GARRULOUS:root:This should only be seen at the '3' logging level (or lower)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(3)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+GARRULOUS:root:This should only be seen at the '3' logging level (or lower)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(4)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(5)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+
+>>> log.setLevel(6)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(7)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(8)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(9)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(10)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> hdlr.setLevel(SOCIABLE)
+
+>>> log.setLevel(1)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(2)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(3)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(4)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(5)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(6)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(7)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(8)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(9)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(10)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>>
+
+>>> hdlr.setLevel(0)
+
+>>> garr = GarrulousFilter()
+
+>>> hdlr.addFilter(garr)
+
+>>> log.setLevel(1)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+BORING:root:This should only be seen at the '1' logging level (or lower)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+CHATTERBOX:root:This should only be seen at the '2' logging level (or lower)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(2)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+CHATTERBOX:root:This should only be seen at the '2' logging level (or lower)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(3)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(4)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(5)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.setLevel(6)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+SOCIABLE:root:This should only be seen at the '6' logging level (or lower)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(7)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(8)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(9)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+TACITURN:root:This should only be seen at the '9' logging level (or lower)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(10)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> spec = VerySpecificFilter()
+
+>>> log.addFilter(spec)
+
+>>> log.setLevel(1)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+BORING:root:This should only be seen at the '1' logging level (or lower)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+CHATTERBOX:root:This should only be seen at the '2' logging level (or lower)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(2)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+CHATTERBOX:root:This should only be seen at the '2' logging level (or lower)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(3)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(4)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+TALKATIVE:root:This should only be seen at the '4' logging level (or lower)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(5)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+VERBOSE:root:This should only be seen at the '5' logging level (or lower)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(6)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(7)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+EFFUSIVE:root:This should only be seen at the '7' logging level (or lower)
 
-Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
-"""
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(8)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+TERSE:root:This should only be seen at the '8' logging level (or lower)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(9)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(10)
+
+>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING)
+
+>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX)
+
+>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS)
+
+>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE)
+
+>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE)
+
+>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE)
+
+>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE)
+
+>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE)
+
+>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN)
+
+>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT)
+SILENT:root:This should only be seen at the '10' logging level (or lower)
+
+>>> log.setLevel(0)
+
+>>> log.removeFilter(spec)
+
+>>> hdlr.removeFilter(garr)
+
+>>> logging.addLevelName(logging.DEBUG, "DEBUG")
+
+
+Test 2
+======
+Test memory handlers. These are basically buffers for log messages: they take so many messages, and then print them all.
+
+>>> import logging.handlers
+
+>>> sys.stderr = sys.stdout
+>>> logger = logging.getLogger("")
+>>> sh = logger.handlers[0]
+>>> sh.close()
+>>> logger.removeHandler(sh)
+>>> mh = logging.handlers.MemoryHandler(10,logging.WARNING, sh)
+>>> logger.setLevel(logging.DEBUG)
+>>> logger.addHandler(mh)
+
+>>> logger.debug("Debug message")
+
+-- logging at INFO, nothing should be seen yet --
+
+>>> logger.info("Info message")
+
+-- logging at WARNING, 3 messages should be seen --
+
+>>> logger.warn("Warn message")
+DEBUG:root:Debug message
+INFO:root:Info message
+WARNING:root:Warn message
+
+>>> logger.info("Info index = 0")
+
+>>> logger.info("Info index = 1")
+
+>>> logger.info("Info index = 2")
+
+>>> logger.info("Info index = 3")
+
+>>> logger.info("Info index = 4")
+
+>>> logger.info("Info index = 5")
+
+>>> logger.info("Info index = 6")
+
+>>> logger.info("Info index = 7")
+
+>>> logger.info("Info index = 8")
+
+>>> logger.info("Info index = 9")
+INFO:root:Info index = 0
+INFO:root:Info index = 1
+INFO:root:Info index = 2
+INFO:root:Info index = 3
+INFO:root:Info index = 4
+INFO:root:Info index = 5
+INFO:root:Info index = 6
+INFO:root:Info index = 7
+INFO:root:Info index = 8
+INFO:root:Info index = 9
+
+>>> logger.info("Info index = 10")
+
+>>> logger.info("Info index = 11")
+
+>>> logger.info("Info index = 12")
+
+>>> logger.info("Info index = 13")
+
+>>> logger.info("Info index = 14")
+
+>>> logger.info("Info index = 15")
+
+>>> logger.info("Info index = 16")
+
+>>> logger.info("Info index = 17")
+
+>>> logger.info("Info index = 18")
+
+>>> logger.info("Info index = 19")
+INFO:root:Info index = 10
+INFO:root:Info index = 11
+INFO:root:Info index = 12
+INFO:root:Info index = 13
+INFO:root:Info index = 14
+INFO:root:Info index = 15
+INFO:root:Info index = 16
+INFO:root:Info index = 17
+INFO:root:Info index = 18
+INFO:root:Info index = 19
+
+>>> logger.info("Info index = 20")
+
+>>> logger.info("Info index = 21")
+
+>>> logger.info("Info index = 22")
+
+>>> logger.info("Info index = 23")
+
+>>> logger.info("Info index = 24")
+
+>>> logger.info("Info index = 25")
+
+>>> logger.info("Info index = 26")
+
+>>> logger.info("Info index = 27")
+
+>>> logger.info("Info index = 28")
+
+>>> logger.info("Info index = 29")
+INFO:root:Info index = 20
+INFO:root:Info index = 21
+INFO:root:Info index = 22
+INFO:root:Info index = 23
+INFO:root:Info index = 24
+INFO:root:Info index = 25
+INFO:root:Info index = 26
+INFO:root:Info index = 27
+INFO:root:Info index = 28
+INFO:root:Info index = 29
+
+>>> logger.info("Info index = 30")
+
+>>> logger.info("Info index = 31")
+
+>>> logger.info("Info index = 32")
+
+>>> logger.info("Info index = 33")
+
+>>> logger.info("Info index = 34")
+
+>>> logger.info("Info index = 35")
+
+>>> logger.info("Info index = 36")
+
+>>> logger.info("Info index = 37")
+
+>>> logger.info("Info index = 38")
+
+>>> logger.info("Info index = 39")
+INFO:root:Info index = 30
+INFO:root:Info index = 31
+INFO:root:Info index = 32
+INFO:root:Info index = 33
+INFO:root:Info index = 34
+INFO:root:Info index = 35
+INFO:root:Info index = 36
+INFO:root:Info index = 37
+INFO:root:Info index = 38
+INFO:root:Info index = 39
+
+>>> logger.info("Info index = 40")
+
+>>> logger.info("Info index = 41")
+
+>>> logger.info("Info index = 42")
+
+>>> logger.info("Info index = 43")
+
+>>> logger.info("Info index = 44")
+
+>>> logger.info("Info index = 45")
+
+>>> logger.info("Info index = 46")
+
+>>> logger.info("Info index = 47")
+
+>>> logger.info("Info index = 48")
+
+>>> logger.info("Info index = 49")
+INFO:root:Info index = 40
+INFO:root:Info index = 41
+INFO:root:Info index = 42
+INFO:root:Info index = 43
+INFO:root:Info index = 44
+INFO:root:Info index = 45
+INFO:root:Info index = 46
+INFO:root:Info index = 47
+INFO:root:Info index = 48
+INFO:root:Info index = 49
+
+>>> logger.info("Info index = 50")
+
+>>> logger.info("Info index = 51")
+
+>>> logger.info("Info index = 52")
+
+>>> logger.info("Info index = 53")
+
+>>> logger.info("Info index = 54")
+
+>>> logger.info("Info index = 55")
+
+>>> logger.info("Info index = 56")
+
+>>> logger.info("Info index = 57")
+
+>>> logger.info("Info index = 58")
+
+>>> logger.info("Info index = 59")
+INFO:root:Info index = 50
+INFO:root:Info index = 51
+INFO:root:Info index = 52
+INFO:root:Info index = 53
+INFO:root:Info index = 54
+INFO:root:Info index = 55
+INFO:root:Info index = 56
+INFO:root:Info index = 57
+INFO:root:Info index = 58
+INFO:root:Info index = 59
+
+>>> logger.info("Info index = 60")
+
+>>> logger.info("Info index = 61")
+
+>>> logger.info("Info index = 62")
+
+>>> logger.info("Info index = 63")
+
+>>> logger.info("Info index = 64")
+
+>>> logger.info("Info index = 65")
+
+>>> logger.info("Info index = 66")
+
+>>> logger.info("Info index = 67")
+
+>>> logger.info("Info index = 68")
+
+>>> logger.info("Info index = 69")
+INFO:root:Info index = 60
+INFO:root:Info index = 61
+INFO:root:Info index = 62
+INFO:root:Info index = 63
+INFO:root:Info index = 64
+INFO:root:Info index = 65
+INFO:root:Info index = 66
+INFO:root:Info index = 67
+INFO:root:Info index = 68
+INFO:root:Info index = 69
+
+>>> logger.info("Info index = 70")
+
+>>> logger.info("Info index = 71")
+
+>>> logger.info("Info index = 72")
+
+>>> logger.info("Info index = 73")
+
+>>> logger.info("Info index = 74")
+
+>>> logger.info("Info index = 75")
+
+>>> logger.info("Info index = 76")
+
+>>> logger.info("Info index = 77")
+
+>>> logger.info("Info index = 78")
 
+>>> logger.info("Info index = 79")
+INFO:root:Info index = 70
+INFO:root:Info index = 71
+INFO:root:Info index = 72
+INFO:root:Info index = 73
+INFO:root:Info index = 74
+INFO:root:Info index = 75
+INFO:root:Info index = 76
+INFO:root:Info index = 77
+INFO:root:Info index = 78
+INFO:root:Info index = 79
+
+>>> logger.info("Info index = 80")
+
+>>> logger.info("Info index = 81")
+
+>>> logger.info("Info index = 82")
+
+>>> logger.info("Info index = 83")
+
+>>> logger.info("Info index = 84")
+
+>>> logger.info("Info index = 85")
+
+>>> logger.info("Info index = 86")
+
+>>> logger.info("Info index = 87")
+
+>>> logger.info("Info index = 88")
+
+>>> logger.info("Info index = 89")
+INFO:root:Info index = 80
+INFO:root:Info index = 81
+INFO:root:Info index = 82
+INFO:root:Info index = 83
+INFO:root:Info index = 84
+INFO:root:Info index = 85
+INFO:root:Info index = 86
+INFO:root:Info index = 87
+INFO:root:Info index = 88
+INFO:root:Info index = 89
+
+>>> logger.info("Info index = 90")
+
+>>> logger.info("Info index = 91")
+
+>>> logger.info("Info index = 92")
+
+>>> logger.info("Info index = 93")
+
+>>> logger.info("Info index = 94")
+
+>>> logger.info("Info index = 95")
+
+>>> logger.info("Info index = 96")
+
+>>> logger.info("Info index = 97")
+
+>>> logger.info("Info index = 98")
+
+>>> logger.info("Info index = 99")
+INFO:root:Info index = 90
+INFO:root:Info index = 91
+INFO:root:Info index = 92
+INFO:root:Info index = 93
+INFO:root:Info index = 94
+INFO:root:Info index = 95
+INFO:root:Info index = 96
+INFO:root:Info index = 97
+INFO:root:Info index = 98
+INFO:root:Info index = 99
+
+>>> logger.info("Info index = 100")
+
+>>> logger.info("Info index = 101")
+
+>>> mh.close()
+INFO:root:Info index = 100
+INFO:root:Info index = 101
+
+>>> logger.removeHandler(mh)
+>>> logger.addHandler(sh)
+
+
+
+Test 3
+======
+
+>>> import sys, logging
+>>> sys.stderr = sys
+>>> logging.basicConfig()
+>>> FILTER = "a.b"
+>>> root = logging.getLogger()
+>>> root.setLevel(logging.DEBUG)
+>>> hand = root.handlers[0]
+
+>>> logging.getLogger("a").info("Info 1")
+INFO:a:Info 1
+
+>>> logging.getLogger("a.b").info("Info 2")
+INFO:a.b:Info 2
+
+>>> logging.getLogger("a.c").info("Info 3")
+INFO:a.c:Info 3
+
+>>> logging.getLogger("a.b.c").info("Info 4")
+INFO:a.b.c:Info 4
+
+>>> logging.getLogger("a.b.c.d").info("Info 5")
+INFO:a.b.c.d:Info 5
+
+>>> logging.getLogger("a.bb.c").info("Info 6")
+INFO:a.bb.c:Info 6
+
+>>> logging.getLogger("b").info("Info 7")
+INFO:b:Info 7
+
+>>> logging.getLogger("b.a").info("Info 8")
+INFO:b.a:Info 8
+
+>>> logging.getLogger("c.a.b").info("Info 9")
+INFO:c.a.b:Info 9
+
+>>> logging.getLogger("a.bb").info("Info 10")
+INFO:a.bb:Info 10
+
+Filtered with 'a.b'...
+
+>>> filt = logging.Filter(FILTER)
+
+>>> hand.addFilter(filt)
+
+>>> logging.getLogger("a").info("Info 1")
+
+>>> logging.getLogger("a.b").info("Info 2")
+INFO:a.b:Info 2
+
+>>> logging.getLogger("a.c").info("Info 3")
+
+>>> logging.getLogger("a.b.c").info("Info 4")
+INFO:a.b.c:Info 4
+
+>>> logging.getLogger("a.b.c.d").info("Info 5")
+INFO:a.b.c.d:Info 5
+
+>>> logging.getLogger("a.bb.c").info("Info 6")
+
+>>> logging.getLogger("b").info("Info 7")
+
+>>> logging.getLogger("b.a").info("Info 8")
+
+>>> logging.getLogger("c.a.b").info("Info 9")
+
+>>> logging.getLogger("a.bb").info("Info 10")
+
+>>> hand.removeFilter(filt)
+
+
+Test 4
+======
+>>> import sys, logging, logging.handlers, string
+>>> import tempfile, logging.config, os, test.test_support
+>>> sys.stderr = sys.stdout
+
+>>> from test_logging import config0, config1
+
+config2 has a subtle configuration error that should be reported
+>>> config2 = string.replace(config1, "sys.stdout", "sys.stbout")
+
+config3 has a less subtle configuration error
+>>> config3 = string.replace(config1, "formatter=form1", "formatter=misspelled_name")
+
+>>> def test4(conf):
+...     loggerDict = logging.getLogger().manager.loggerDict
+...     logging._acquireLock()
+...     try:
+...         saved_handlers = logging._handlers.copy()
+...         saved_handler_list = logging._handlerList[:]
+...         saved_loggers = loggerDict.copy()
+...     finally:
+...         logging._releaseLock()
+...     try:
+...         fn = test.test_support.TESTFN
+...         f = open(fn, "w")
+...         f.write(conf)
+...         f.close()
+...         try:
+...             logging.config.fileConfig(fn)
+...             #call again to make sure cleanup is correct
+...             logging.config.fileConfig(fn)
+...         except:
+...             t = sys.exc_info()[0]
+...             message(str(t))
+...         else:
+...             message('ok.')
+...             os.remove(fn)
+...     finally:
+...         logging._acquireLock()
+...         try:
+...             logging._handlers.clear()
+...             logging._handlers.update(saved_handlers)
+...             logging._handlerList[:] = saved_handler_list
+...             loggerDict = logging.getLogger().manager.loggerDict
+...             loggerDict.clear()
+...             loggerDict.update(saved_loggers)
+...         finally:
+...             logging._releaseLock()
+
+>>> test4(config0)
+ok.
+
+>>> test4(config1)
+ok.
+
+>>> test4(config2)
+<type 'exceptions.AttributeError'>
+
+>>> test4(config3)
+<type 'exceptions.KeyError'>
+
+>>> import test_logging
+>>> test_logging.test5()
+ERROR:root:just testing
+<type 'exceptions.KeyError'>... Don't panic!
+
+
+Test Main
+=========
+>>> import select
+>>> import os, sys, string, struct, types, cPickle, cStringIO
+>>> import socket, tempfile, threading, time
+>>> import logging, logging.handlers, logging.config
+>>> import test_logging
+
+>>> test_logging.test_main_inner()
+ERR -> CRITICAL: Message 0 (via logrecv.tcp.ERR)
+ERR -> ERROR: Message 1 (via logrecv.tcp.ERR)
+INF -> CRITICAL: Message 2 (via logrecv.tcp.INF)
+INF -> ERROR: Message 3 (via logrecv.tcp.INF)
+INF -> WARNING: Message 4 (via logrecv.tcp.INF)
+INF -> INFO: Message 5 (via logrecv.tcp.INF)
+INF.UNDEF -> CRITICAL: Message 6 (via logrecv.tcp.INF.UNDEF)
+INF.UNDEF -> ERROR: Message 7 (via logrecv.tcp.INF.UNDEF)
+INF.UNDEF -> WARNING: Message 8 (via logrecv.tcp.INF.UNDEF)
+INF.UNDEF -> INFO: Message 9 (via logrecv.tcp.INF.UNDEF)
+INF.ERR -> CRITICAL: Message 10 (via logrecv.tcp.INF.ERR)
+INF.ERR -> ERROR: Message 11 (via logrecv.tcp.INF.ERR)
+INF.ERR.UNDEF -> CRITICAL: Message 12 (via logrecv.tcp.INF.ERR.UNDEF)
+INF.ERR.UNDEF -> ERROR: Message 13 (via logrecv.tcp.INF.ERR.UNDEF)
+DEB -> CRITICAL: Message 14 (via logrecv.tcp.DEB)
+DEB -> ERROR: Message 15 (via logrecv.tcp.DEB)
+DEB -> WARNING: Message 16 (via logrecv.tcp.DEB)
+DEB -> INFO: Message 17 (via logrecv.tcp.DEB)
+DEB -> DEBUG: Message 18 (via logrecv.tcp.DEB)
+UNDEF -> CRITICAL: Message 19 (via logrecv.tcp.UNDEF)
+UNDEF -> ERROR: Message 20 (via logrecv.tcp.UNDEF)
+UNDEF -> WARNING: Message 21 (via logrecv.tcp.UNDEF)
+UNDEF -> INFO: Message 22 (via logrecv.tcp.UNDEF)
+INF.BADPARENT.UNDEF -> CRITICAL: Message 23 (via logrecv.tcp.INF.BADPARENT.UNDEF)
+INF.BADPARENT -> CRITICAL: Message 24 (via logrecv.tcp.INF.BADPARENT)
+INF -> INFO: Finish up, it's closing time. Messages should bear numbers 0 through 24. (via logrecv.tcp.INF)
+<BLANKLINE>
+"""
 import select
 import os, sys, string, struct, types, cPickle, cStringIO
 import socket, tempfile, threading, time
-import logging, logging.handlers, logging.config
-from test.test_support import run_with_locale
+import logging, logging.handlers, logging.config, test.test_support
+
 
 BANNER = "-- %-10s %-6s ---------------------------------------------------\n"
 
 FINISH_UP = "Finish up, it's closing time. Messages should bear numbers 0 through 24."
+#----------------------------------------------------------------------------
+# Test 0
+#----------------------------------------------------------------------------
+
+msgcount = 0
+
+def nextmessage():
+    global msgcount
+    rv = "Message %d" % msgcount
+    msgcount = msgcount + 1
+    return rv
 
 #----------------------------------------------------------------------------
 # Log receiver
@@ -78,11 +1922,80 @@
         if record.msg == FINISH_UP:
             self.server.abort = 1
         record.msg = record.msg + " (via " + logname + ")"
-        logger = logging.getLogger(logname)
+        logger = logging.getLogger("logrecv")
         logger.handle(record)
 
-# The server sets socketDataProcessed when it's done.
-socketDataProcessed = threading.Event()
+# The server sets socketDataProcessed when it's done.
+socketDataProcessed = threading.Event()
+#----------------------------------------------------------------------------
+# Test 5
+#----------------------------------------------------------------------------
+
+test5_config = """
+[loggers]
+keys=root
+
+[handlers]
+keys=hand1
+
+[formatters]
+keys=form1
+
+[logger_root]
+level=NOTSET
+handlers=hand1
+
+[handler_hand1]
+class=StreamHandler
+level=NOTSET
+formatter=form1
+args=(sys.stdout,)
+
+[formatter_form1]
+class=test.test_logging.FriendlyFormatter
+format=%(levelname)s:%(name)s:%(message)s
+datefmt=
+"""
+
+class FriendlyFormatter (logging.Formatter):
+    def formatException(self, ei):
+        return "%s... Don't panic!" % str(ei[0])
+
+
+def test5():
+    loggerDict = logging.getLogger().manager.loggerDict
+    logging._acquireLock()
+    try:
+        saved_handlers = logging._handlers.copy()
+        saved_handler_list = logging._handlerList[:]
+        saved_loggers = loggerDict.copy()
+    finally:
+        logging._releaseLock()
+    try:
+        fn = test.test_support.TESTFN
+        f = open(fn, "w")
+        f.write(test5_config)
+        f.close()
+        logging.config.fileConfig(fn)
+        try:
+            raise KeyError
+        except KeyError:
+            logging.exception("just testing")
+        os.remove(fn)
+        hdlr = logging.getLogger().handlers[0]
+        logging.getLogger().handlers.remove(hdlr)
+    finally:
+        logging._acquireLock()
+        try:
+            logging._handlers.clear()
+            logging._handlers.update(saved_handlers)
+            logging._handlerList[:] = saved_handler_list
+            loggerDict = logging.getLogger().manager.loggerDict
+            loggerDict.clear()
+            loggerDict.update(saved_loggers)
+        finally:
+            logging._releaseLock()
+
 
 class LogRecordSocketReceiver(ThreadingTCPServer):
     """
@@ -105,8 +2018,6 @@
                                        self.timeout)
             if rd:
                 self.handle_request()
-        #notify the main thread that we're about to exit
-        socketDataProcessed.set()
         # close the listen socket
         self.server_close()
 
@@ -119,17 +2030,10 @@
 def runTCP(tcpserver):
     tcpserver.serve_until_stopped()
 
-#----------------------------------------------------------------------------
-# Test 0
-#----------------------------------------------------------------------------
-
-msgcount = 0
-
-def nextmessage():
-    global msgcount
-    rv = "Message %d" % msgcount
-    msgcount = msgcount + 1
-    return rv
+def banner(nm, typ):
+    sep = BANNER % (nm, typ)
+    sys.stdout.write(sep)
+    sys.stdout.flush()
 
 def test0():
     ERR = logging.getLogger("ERR")
@@ -199,202 +2103,70 @@
 
     INF.info(FINISH_UP)
 
-#----------------------------------------------------------------------------
-# Test 1
-#----------------------------------------------------------------------------
-
-#
-#   First, we define our levels. There can be as many as you want - the only
-#     limitations are that they should be integers, the lowest should be > 0 and
-#   larger values mean less information being logged. If you need specific
-#   level values which do not fit into these limitations, you can use a
-#   mapping dictionary to convert between your application levels and the
-#   logging system.
-#
-SILENT      = 10
-TACITURN    = 9
-TERSE       = 8
-EFFUSIVE    = 7
-SOCIABLE    = 6
-VERBOSE     = 5
-TALKATIVE   = 4
-GARRULOUS   = 3
-CHATTERBOX  = 2
-BORING      = 1
-
-LEVEL_RANGE = range(BORING, SILENT + 1)
-
-#
-#   Next, we define names for our levels. You don't need to do this - in which
-#   case the system will use "Level n" to denote the text for the level.
-#
-my_logging_levels = {
-    SILENT      : 'Silent',
-    TACITURN    : 'Taciturn',
-    TERSE       : 'Terse',
-    EFFUSIVE    : 'Effusive',
-    SOCIABLE    : 'Sociable',
-    VERBOSE     : 'Verbose',
-    TALKATIVE   : 'Talkative',
-    GARRULOUS   : 'Garrulous',
-    CHATTERBOX  : 'Chatterbox',
-    BORING      : 'Boring',
-}
-
-#
-#   Now, to demonstrate filtering: suppose for some perverse reason we only
-#   want to print out all except GARRULOUS messages. Let's create a filter for
-#   this purpose...
-#
-class SpecificLevelFilter(logging.Filter):
-    def __init__(self, lvl):
-        self.level = lvl
-
-    def filter(self, record):
-        return self.level != record.levelno
-
-class GarrulousFilter(SpecificLevelFilter):
-    def __init__(self):
-        SpecificLevelFilter.__init__(self, GARRULOUS)
-
-#
-#   Now, let's demonstrate filtering at the logger. This time, use a filter
-#   which excludes SOCIABLE and TACITURN messages. Note that GARRULOUS events
-#   are still excluded.
-#
-class VerySpecificFilter(logging.Filter):
-    def filter(self, record):
-        return record.levelno not in [SOCIABLE, TACITURN]
-
-def message(s):
-    sys.stdout.write("%s\n" % s)
+def test_main_inner():
+    rootLogger = logging.getLogger("")
+    rootLogger.setLevel(logging.DEBUG)
 
-SHOULD1 = "This should only be seen at the '%s' logging level (or lower)"
+    # Find an unused port number
+    port = logging.handlers.DEFAULT_TCP_LOGGING_PORT
+    while port < logging.handlers.DEFAULT_TCP_LOGGING_PORT+100:
+        try:
+            tcpserver = LogRecordSocketReceiver(port=port)
+        except socket.error:
+            port += 1
+        else:
+            break
+    else:
+        raise ImportError, "Could not find unused port"
 
-def test1():
-#
-#   Now, tell the logging system to associate names with our levels.
-#
-    for lvl in my_logging_levels.keys():
-        logging.addLevelName(lvl, my_logging_levels[lvl])
-
-#
-#   Now, define a test function which logs an event at each of our levels.
-#
-
-    def doLog(log):
-        for lvl in LEVEL_RANGE:
-            log.log(lvl, SHOULD1, logging.getLevelName(lvl))
-
-    log = logging.getLogger("")
-    hdlr = log.handlers[0]
-#
-#   Set the logging level to each different value and call the utility
-#   function to log events.
-#   In the output, you should see that each time round the loop, the number of
-#   logging events which are actually output decreases.
-#
-    for lvl in LEVEL_RANGE:
-        message("-- setting logging level to '%s' -----" %
-                        logging.getLevelName(lvl))
-        log.setLevel(lvl)
-        doLog(log)
-  #
-  #   Now, we demonstrate level filtering at the handler level. Tell the
-  #   handler defined above to filter at level 'SOCIABLE', and repeat the
-  #   above loop. Compare the output from the two runs.
-  #
-    hdlr.setLevel(SOCIABLE)
-    message("-- Filtering at handler level to SOCIABLE --")
-    for lvl in LEVEL_RANGE:
-        message("-- setting logging level to '%s' -----" %
-                      logging.getLevelName(lvl))
-        log.setLevel(lvl)
-        doLog(log)
-
-    hdlr.setLevel(0)    #turn off level filtering at the handler
-
-    garr = GarrulousFilter()
-    hdlr.addFilter(garr)
-    message("-- Filtering using GARRULOUS filter --")
-    for lvl in LEVEL_RANGE:
-        message("-- setting logging level to '%s' -----" %
-                        logging.getLevelName(lvl))
-        log.setLevel(lvl)
-        doLog(log)
-    spec = VerySpecificFilter()
-    log.addFilter(spec)
-    message("-- Filtering using specific filter for SOCIABLE, TACITURN --")
-    for lvl in LEVEL_RANGE:
-        message("-- setting logging level to '%s' -----" %
-                      logging.getLevelName(lvl))
-        log.setLevel(lvl)
-        doLog(log)
-
-    log.removeFilter(spec)
-    hdlr.removeFilter(garr)
-    #Undo the one level which clashes...for regression tests
-    logging.addLevelName(logging.DEBUG, "DEBUG")
 
-#----------------------------------------------------------------------------
-# Test 2
-#----------------------------------------------------------------------------
+    #Set up a handler such that all events are sent via a socket to the log
+    #receiver (logrecv).
+    #The handler will only be added to the rootLogger for some of the tests
+    shdlr = logging.handlers.SocketHandler('localhost', port)
+    rootLogger.addHandler(shdlr)
 
-MSG = "-- logging %d at INFO, messages should be seen every 10 events --"
-def test2():
-    logger = logging.getLogger("")
-    sh = logger.handlers[0]
-    sh.close()
-    logger.removeHandler(sh)
-    mh = logging.handlers.MemoryHandler(10,logging.WARNING, sh)
-    logger.setLevel(logging.DEBUG)
-    logger.addHandler(mh)
-    message("-- logging at DEBUG, nothing should be seen yet --")
-    logger.debug("Debug message")
-    message("-- logging at INFO, nothing should be seen yet --")
-    logger.info("Info message")
-    message("-- logging at WARNING, 3 messages should be seen --")
-    logger.warn("Warn message")
-    for i in xrange(102):
-        message(MSG % i)
-        logger.info("Info index = %d", i)
-    mh.close()
-    logger.removeHandler(mh)
-    logger.addHandler(sh)
+    #Configure the logger for logrecv so events do not propagate beyond it.
+    #The sockLogger output is buffered in memory until the end of the test,
+    #and printed at the end.
+    sockOut = cStringIO.StringIO()
+    sockLogger = logging.getLogger("logrecv")
+    sockLogger.setLevel(logging.DEBUG)
+    sockhdlr = logging.StreamHandler(sockOut)
+    sockhdlr.setFormatter(logging.Formatter(
+                                   "%(name)s -> %(levelname)s: %(message)s"))
+    sockLogger.addHandler(sockhdlr)
+    sockLogger.propagate = 0
 
-#----------------------------------------------------------------------------
-# Test 3
-#----------------------------------------------------------------------------
+    #Set up servers
+    threads = []
+    #sys.stdout.write("About to start TCP server...\n")
+    threads.append(threading.Thread(target=runTCP, args=(tcpserver,)))
 
-FILTER = "a.b"
+    for thread in threads:
+        thread.start()
+    try:
+        test0()
 
-def doLog3():
-    logging.getLogger("a").info("Info 1")
-    logging.getLogger("a.b").info("Info 2")
-    logging.getLogger("a.c").info("Info 3")
-    logging.getLogger("a.b.c").info("Info 4")
-    logging.getLogger("a.b.c.d").info("Info 5")
-    logging.getLogger("a.bb.c").info("Info 6")
-    logging.getLogger("b").info("Info 7")
-    logging.getLogger("b.a").info("Info 8")
-    logging.getLogger("c.a.b").info("Info 9")
-    logging.getLogger("a.bb").info("Info 10")
-
-def test3():
-    root = logging.getLogger()
-    root.setLevel(logging.DEBUG)
-    hand = root.handlers[0]
-    message("Unfiltered...")
-    doLog3()
-    message("Filtered with '%s'..." % FILTER)
-    filt = logging.Filter(FILTER)
-    hand.addFilter(filt)
-    doLog3()
-    hand.removeFilter(filt)
+        # XXX(nnorwitz): Try to fix timing related test failures.
+        # This sleep gives us some extra time to read messages.
+        # The test generally only fails on Solaris without this sleep.
+        #time.sleep(2.0)
+        shdlr.close()
+        rootLogger.removeHandler(shdlr)
 
-#----------------------------------------------------------------------------
-# Test 4
-#----------------------------------------------------------------------------
+    finally:
+        #wait for TCP receiver to terminate
+#        socketDataProcessed.wait()
+        # ensure the server dies
+        tcpserver.abort = 1
+        for thread in threads:
+            thread.join(2.0)
+        print(sockOut.getvalue())
+        sockOut.close()
+        sockLogger.removeHandler(sockhdlr)
+        sockhdlr.close()
+        sys.stdout.flush()
 
 # config0 is a standard configuration.
 config0 = """
@@ -454,6 +2226,9 @@
 datefmt=
 """
 
+def message(s):
+    sys.stdout.write("%s\n" % s)
+
 # config2 has a subtle configuration error that should be reported
 config2 = string.replace(config1, "sys.stdout", "sys.stbout")
 
@@ -461,225 +2236,9 @@
 config3 = string.replace(
     config1, "formatter=form1", "formatter=misspelled_name")
 
-def test4():
-    for i in range(4):
-        conf = globals()['config%d' % i]
-        sys.stdout.write('config%d: ' % i)
-        loggerDict = logging.getLogger().manager.loggerDict
-        logging._acquireLock()
-        try:
-            saved_handlers = logging._handlers.copy()
-            saved_handler_list = logging._handlerList[:]
-            saved_loggers = loggerDict.copy()
-        finally:
-            logging._releaseLock()
-        try:
-            fn = tempfile.mktemp(".ini")
-            f = open(fn, "w")
-            f.write(conf)
-            f.close()
-            try:
-                logging.config.fileConfig(fn)
-                #call again to make sure cleanup is correct
-                logging.config.fileConfig(fn)
-            except:
-                t = sys.exc_info()[0]
-                message(str(t))
-            else:
-                message('ok.')
-            os.remove(fn)
-        finally:
-            logging._acquireLock()
-            try:
-                logging._handlers.clear()
-                logging._handlers.update(saved_handlers)
-                logging._handlerList[:] = saved_handler_list
-                loggerDict = logging.getLogger().manager.loggerDict
-                loggerDict.clear()
-                loggerDict.update(saved_loggers)
-            finally:
-                logging._releaseLock()
-
-#----------------------------------------------------------------------------
-# Test 5
-#----------------------------------------------------------------------------
-
-test5_config = """
-[loggers]
-keys=root
-
-[handlers]
-keys=hand1
-
-[formatters]
-keys=form1
-
-[logger_root]
-level=NOTSET
-handlers=hand1
-
-[handler_hand1]
-class=StreamHandler
-level=NOTSET
-formatter=form1
-args=(sys.stdout,)
-
-[formatter_form1]
-class=test.test_logging.FriendlyFormatter
-format=%(levelname)s:%(name)s:%(message)s
-datefmt=
-"""
-
-class FriendlyFormatter (logging.Formatter):
-    def formatException(self, ei):
-        return "%s... Don't panic!" % str(ei[0])
-
-
-def test5():
-    loggerDict = logging.getLogger().manager.loggerDict
-    logging._acquireLock()
-    try:
-        saved_handlers = logging._handlers.copy()
-        saved_handler_list = logging._handlerList[:]
-        saved_loggers = loggerDict.copy()
-    finally:
-        logging._releaseLock()
-    try:
-        fn = tempfile.mktemp(".ini")
-        f = open(fn, "w")
-        f.write(test5_config)
-        f.close()
-        logging.config.fileConfig(fn)
-        try:
-            raise KeyError
-        except KeyError:
-            logging.exception("just testing")
-        os.remove(fn)
-        hdlr = logging.getLogger().handlers[0]
-        logging.getLogger().handlers.remove(hdlr)
-    finally:
-        logging._acquireLock()
-        try:
-            logging._handlers.clear()
-            logging._handlers.update(saved_handlers)
-            logging._handlerList[:] = saved_handler_list
-            loggerDict = logging.getLogger().manager.loggerDict
-            loggerDict.clear()
-            loggerDict.update(saved_loggers)
-        finally:
-            logging._releaseLock()
-
-
-#----------------------------------------------------------------------------
-# Test Harness
-#----------------------------------------------------------------------------
-def banner(nm, typ):
-    sep = BANNER % (nm, typ)
-    sys.stdout.write(sep)
-    sys.stdout.flush()
-
-def test_main_inner():
-    rootLogger = logging.getLogger("")
-    rootLogger.setLevel(logging.DEBUG)
-    hdlr = logging.StreamHandler(sys.stdout)
-    fmt = logging.Formatter(logging.BASIC_FORMAT)
-    hdlr.setFormatter(fmt)
-    rootLogger.addHandler(hdlr)
-
-    # Find an unused port number
-    port = logging.handlers.DEFAULT_TCP_LOGGING_PORT
-    while port < logging.handlers.DEFAULT_TCP_LOGGING_PORT+100:
-        try:
-            tcpserver = LogRecordSocketReceiver(port=port)
-        except socket.error:
-            port += 1
-        else:
-            break
-    else:
-        raise ImportError, "Could not find unused port"
-
-
-    #Set up a handler such that all events are sent via a socket to the log
-    #receiver (logrecv).
-    #The handler will only be added to the rootLogger for some of the tests
-    shdlr = logging.handlers.SocketHandler('localhost', port)
-
-    #Configure the logger for logrecv so events do not propagate beyond it.
-    #The sockLogger output is buffered in memory until the end of the test,
-    #and printed at the end.
-    sockOut = cStringIO.StringIO()
-    sockLogger = logging.getLogger("logrecv")
-    sockLogger.setLevel(logging.DEBUG)
-    sockhdlr = logging.StreamHandler(sockOut)
-    sockhdlr.setFormatter(logging.Formatter(
-                                   "%(name)s -> %(levelname)s: %(message)s"))
-    sockLogger.addHandler(sockhdlr)
-    sockLogger.propagate = 0
-
-    #Set up servers
-    threads = []
-    #sys.stdout.write("About to start TCP server...\n")
-    threads.append(threading.Thread(target=runTCP, args=(tcpserver,)))
-
-    for thread in threads:
-        thread.start()
-    try:
-        banner("log_test0", "begin")
-
-        rootLogger.addHandler(shdlr)
-        test0()
-        # XXX(nnorwitz): Try to fix timing related test failures.
-        # This sleep gives us some extra time to read messages.
-        # The test generally only fails on Solaris without this sleep.
-        time.sleep(2.0)
-        shdlr.close()
-        rootLogger.removeHandler(shdlr)
-
-        banner("log_test0", "end")
-
-        for t in range(1,6):
-            banner("log_test%d" % t, "begin")
-            globals()['test%d' % t]()
-            banner("log_test%d" % t, "end")
-
-    finally:
-        #wait for TCP receiver to terminate
-        socketDataProcessed.wait()
-        # ensure the server dies
-        tcpserver.abort = 1
-        for thread in threads:
-            thread.join(2.0)
-        banner("logrecv output", "begin")
-        sys.stdout.write(sockOut.getvalue())
-        sockOut.close()
-        sockLogger.removeHandler(sockhdlr)
-        sockhdlr.close()
-        banner("logrecv output", "end")
-        sys.stdout.flush()
-        try:
-            hdlr.close()
-        except:
-            pass
-        rootLogger.removeHandler(hdlr)
-
-# Set the locale to the platform-dependent default.  I have no idea
-# why the test does this, but in any case we save the current locale
-# first and restore it at the end.
- at run_with_locale('LC_ALL', '')
 def test_main():
-    # Save and restore the original root logger level across the tests.
-    # Otherwise, e.g., if any test using cookielib runs after test_logging,
-    # cookielib's debug-level logger tries to log messages, leading to
-    # confusing:
-    #    No handlers could be found for logger "cookielib"
-    # output while the tests are running.
-    root_logger = logging.getLogger("")
-    original_logging_level = root_logger.getEffectiveLevel()
-    try:
-        test_main_inner()
-    finally:
-        root_logger.setLevel(original_logging_level)
+    from test import test_support, test_logging
+    test_support.run_doctest(test_logging)
 
-if __name__ == "__main__":
-    sys.stdout.write("test_logging\n")
+if __name__=="__main__":
     test_main()

Modified: python/trunk/Misc/ACKS
==============================================================================
--- python/trunk/Misc/ACKS	(original)
+++ python/trunk/Misc/ACKS	Sun Feb 17 02:59:18 2008
@@ -704,6 +704,7 @@
 Cliff Wells
 Rickard Westman
 Jeff Wheeler
+Christopher White
 Mats Wichmann
 Truida Wiedijk
 Felix Wiemann

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Sun Feb 17 02:59:18 2008
@@ -1341,6 +1341,8 @@
 Tests
 -----
 
+- Refactor test_logging to use doctest.
+
 - Refactor test_profile and test_cprofile to use the same code to profile.
 
 - Make test_runpy reentrant by fixing _check_module to clear out any module


More information about the Python-checkins mailing list