bpo-37857: Invalidate cache when log level changed directly#15286
bpo-37857: Invalidate cache when log level changed directly#15286zaneb wants to merge 5 commits intopython:masterfrom
Conversation
While the logging level of a Logger should really be changed only by calling the setLevel() method, there exists code in the wild that changes it by setting the public 'level' attribute directly. Prior to Python 3.7, this worked correctly. The addition of caching to Logger.isEnabledFor() by the fix for bpo-30962, 78c18a9, means that direct changes to the level now leave the cache in a state inconsistent with the Logger - an extraordinarily difficult thing to debug. Make 'level' a property that invalidates the cache when set. This ensures that existing application code will continue to work as it did with previous versions of Python.
|
Please see my comments on the issue. |
|
@vsajip what if we added a DeprecationWarning to the setter? That would help people find and fix their old code, and avoid encouraging more folks to try using the wrong interface. |
|
I'm not sure if this is needed or not, but there are a couple things I don't like about the approach. Primarily because it's inconstant. I would suggest changing all Since I think a reasonable compromise might be to change One could argue a deprecation period is needed and a setter could be used to do that. I wouldn't object to that, but I also would argue it isn't needed since it's not documented and already doesn't work in 3.7+. If you did want to introduce a functioning setter for |
Never set the level attribute directly.
Don't try to set the level attribute directly; use the setLevel() method.
The level attribute of a Logger instance should never be set directly; the setLevel() method should be used instead. Deprecate the setter to warn anyone with code doing it incorrectly to change it.
|
You're still using |
Although getEffectiveLevel() is only called from isEnabledFor() in the slow path when there is a cache miss, using the new _level attribute directly means that the change to make the level attribute a property is be completely performance neutral for the stdlib code itself. (User code accessing the level propertly directly will still be slightly slower.)
|
Based on the discussion on the bug tracker, it looks like @vsajip wasn't in favor of this change. I'm going to close this PR for now with the understanding that it can be revived if this becomes the path forward in the future. Thank you. |
bpo-37857
While the logging level of a Logger should really be changed only by calling the
setLevel()method, there exists code in the wild that changes it by setting the publiclevelattribute directly. Prior toPython 3.7, this worked correctly.
The addition of caching to
Logger.isEnabledFor()by the fix for bpo-30962, #2752, means that direct changes to the level now leave the cache in a state inconsistent with the Logger - an extraordinarily difficult thing to debug.Make
levela property that invalidates the cache when set. This ensures that existing application code will continue to work as it did with previous versions of Python.https://bugs.python.org/issue37857