This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: distutils2: logging handler not properly initialized
Type: Stage: resolved
Components: Distutils2 Versions: Python 3.3, 3rd party
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: eric.araujo Nosy List: alexis, eric.araujo, tarek, techtonik, vinay.sajip
Priority: normal Keywords:

Created on 2012-03-12 22:56 by tarek, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (11)
msg155509 - (view) Author: Tarek Ziadé (tarek) * (Python committer) Date: 2012-03-12 22:56
$ ./pysetup dwqqwddwq
No handlers could be found for logger "distutils2"
msg155510 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2012-03-12 22:58
I’ve seen that too when running “python -m packaging.run”, but I don’t understand why the behavior is different when running pysetup vs. ./pysetup vs. python -m: all of these run the same code.
msg155584 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-03-13 09:11
I cannot reproduce this, and in fact couldn't find anywhere in packaging in the default branch where a "distutils2" logger is set up. I used grep to look for "getLogger.*(distutils2|__name__)", could some other logic be in use to construct the logger name?

Looking at packaging.run.main() - it calls Dispatcher(args), and any exception in Dispatcher.__init__() before the call to _set_logger could lead to a logging call being made before a handler is set up.

Suggestion: set the handler as early as possible, perhaps in main() where the other handlers logic is, and just set the level later (as that is the only thing that depends on verbosity settings passed in via command line flags).

A couple of things I don't quite understand:

1. Why are the packaging logger's handlers are saved and restored en masse - all that is happening is that a handler is being added in Dispatcher._set_logger, so it would seem to be enough to call removeHandler().

2. There should normally be no need to set both the logger's *and* and handler's level to the same value - if the event fails the logger's level test, it will not be passed to handlers anyway. In packaging code I found no reference to any other loggers than "packaging" - i.e. no child loggers whose events might need to be blocked at the handler level.
msg155614 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2012-03-13 14:18
We didn’t give enough info, sorry.  This bug is not reproducible with packaging, it only shows when using the distutils2 repository with Python 2.5, 2.6 or 3.1.  I think it’s related to the absence of built-in handler of last resort.

(packaging’s logger is named “packaging” and d2’s is “distutils2”, that’s why your grep did not find it.  This is one of the few differences between both codebases that I will fix before the betas.)

> Looking at packaging.run.main() - it calls Dispatcher(args), and any exception in Dispatcher.__init__()
> before the call to _set_logger could lead to a logging call being made before a handler is set up.
> Suggestion: set the handler as early as possible, perhaps in main() where the other handlers logic is, and
> just set the level later (as that is the only thing that depends on verbosity settings passed in via
> command line flags).
Thanks, I will try that!

> 1. Why are the packaging logger's handlers are saved and restored en masse - all that is happening is that
> a handler is being added in Dispatcher._set_logger, so it would seem to be enough to call removeHandler().
Tarek added that in d53e813ffe58 to fix regrtest warnings about test_packaging modifying logging._handlers.

> 2. There should normally be no need to set both the logger's *and* and handler's level to the same value -
> if the event fails the logger's level test, it will not be passed to handlers anyway. In packaging code I
> found no reference to any other loggers than "packaging" - i.e. no child loggers whose events might need to
> be blocked at the handler level.
Yes, the whole package only uses one logger, and we don’t want to stop messages: the application (pysetup, pip, etc.) must be able to set the level.  I’ll remove the code that sets a level on the logger and write a test to make sure that a client can get all messages.
msg155621 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-03-13 15:08
> Yes, the whole package only uses one logger, and we don’t want to stop messages: 

> the application (pysetup, pip, etc.) must be able to set the level.  I’ll remove 
> the code that sets a level on the logger and write a test to make sure that a 
> client can get all messages.

I think you might mean "sets a level on the handler" - the logger should still have the level set, I think.
msg155623 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2012-03-13 15:16
> I think you might mean "sets a level on the handler" - the logger should still have the level set
IIUC the logger should be set to DEBUG, otherwise even if e.g. pip wants to get INFO messages it won’t see them.  Is that right?
msg155739 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-03-14 09:38
>
> IIUC the logger should be set to DEBUG, otherwise even if e.g. pip wants to get 

> INFO messages it won’t see them.  Is that right?

Well, you could set the level to INFO to get INFO and higher messages. DEBUG should only be set for messages of interest to developers/support staff/system admins, and which might confuse end users.
msg163897 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2012-06-25 05:51
> DEBUG should only be set for messages of interest to developers/support staff/system admins,
> and which might confuse end users.
The thing is that all logging messages from distutils2 should be sent to handlers, and client code such as pysetup or pip2 can choose the level.  The library code however should not filter out DEBUG messages at the logger level—that would make them useless :)
msg163915 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-06-25 08:38
It's been a while since I looked at this issue, so it would be helpful if you summarised exactly what sort of events are logged at INFO or DEBUG level, and why adding a handler early doesn't work. You said in msg155614 that you would try adding the handler earlier as per my suggestion in msg155584, but I see no feedback on how that changed things.
msg163916 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-06-25 08:39
One more thing (referring to the opening comment by Tarek): if you add a NullHandler to the top-level logger as recommended in the library docs for libraries, you won't get the "No handlers could be found" message.
msg176174 - (view) Author: anatoly techtonik (techtonik) Date: 2012-11-23 14:36
More specifically, you need to copy NullHandler code if you want to run it with Python 2.x < 2.7
History
Date User Action Args
2022-04-11 14:57:27adminsetgithub: 58481
2014-03-13 04:19:40eric.araujosetstatus: open -> closed
resolution: out of date
stage: resolved
2012-11-23 14:36:16techtoniksetnosy: + techtonik
messages: + msg176174
2012-06-25 08:39:33vinay.sajipsetmessages: + msg163916
2012-06-25 08:38:11vinay.sajipsetmessages: + msg163915
2012-06-25 05:51:54eric.araujosetmessages: + msg163897
2012-03-14 09:38:24vinay.sajipsetmessages: + msg155739
2012-03-13 15:16:16eric.araujosetmessages: + msg155623
2012-03-13 15:08:16vinay.sajipsetmessages: + msg155621
2012-03-13 14:18:11eric.araujosetpriority: high -> normal

messages: + msg155614
2012-03-13 09:11:52vinay.sajipsetmessages: + msg155584
2012-03-12 22:58:13eric.araujosetnosy: + vinay.sajip
title: handler not properly initialized -> distutils2: logging handler not properly initialized
messages: + msg155510

versions: + 3rd party, - Python 3.4
2012-03-12 22:56:18tarekcreate