Author xtreak
Recipients eamanu, mark.dickinson, porton, steven.daprano, vinay.sajip, xtreak
Date 2018-12-19.12:01:33
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1545220893.83.0.788709270274.issue35530@psf.upfronthosting.co.za>
In-reply-to
Content
> If you have 3.8 installed, feel free to test the code yourself and report what happens.

I tested it on master and it's the same as per the original report.

➜  cpython git:(master) cat ../backups/bpo35530_1.py
import logging
logger = logging.getLogger(name='main')
logger.setLevel(logging.INFO)
logger.error('XXX')
logging.error('ZZZ')
logger.error('XXX')
➜  cpython git:(master) ./python.exe
Python 3.8.0a0 (heads/master:1dd035954b, Dec 18 2018, 10:12:34)
[Clang 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> ^D
➜  cpython git:(master) ./python.exe ../backups/bpo35530_1.py
XXX
ERROR:root:ZZZ
ERROR:main:XXX


root is parent for all logger objects created down the inheritance chain. When there is no root handler for logger then it resorts to lastResort handler (As per name called on last resort when there is no handler even for root) whose format is "%(message)s". Calling logging.error sets the root's handler (like doing logging.basicConfig). When there is a root with handler then subsequent logger calls the root's handler but lastResort is not called since it has found the root handler. I agree with Mark that this could affect downstream and is very hard to debug when libraries have wrong configuration.

import logging
logger = logging.getLogger(name='main')
logger.setLevel(logging.INFO)
logger.error('XXX')
print("logger parent ", logger.parent) # Root is always the parent by default
print("logger parent handlers ", logger.parent.handlers) # No root handler since root is not configured which logging error does below
print("logger handler ", logger.handlers) # Empty and no parent (root) handler so calls lastResort
logging.error('ZZZ') # Sets the root handler
print("logger parent after logging ", logger.parent) # Root is parent
print("logger parent handlers after logging ", logger.parent.handlers) # Root handler is set
print("logger handler after logging ", logger.handlers) # Empty but has parent (root) handler so lastResort is not called
logger.error('XXX')

Output : 

XXX
logger parent  <RootLogger root (WARNING)>
logger parent handlers  []
logger handler  []
ERROR:root:ZZZ
logger parent after logging  <RootLogger root (WARNING)>
logger parent handlers after logging  [<StreamHandler <stderr> (NOTSET)>]
logger handler after logging  []
ERROR:main:XXX
History
Date User Action Args
2018-12-19 12:01:33xtreaksetrecipients: + xtreak, vinay.sajip, mark.dickinson, steven.daprano, porton, eamanu
2018-12-19 12:01:33xtreaksetmessageid: <1545220893.83.0.788709270274.issue35530@psf.upfronthosting.co.za>
2018-12-19 12:01:33xtreaklinkissue35530 messages
2018-12-19 12:01:33xtreakcreate