Fix logger verbose level not restored after unpickling - #169
Open
JayeshSuryavanshi wants to merge 1 commit into
Open
Fix logger verbose level not restored after unpickling#169JayeshSuryavanshi wants to merge 1 commit into
JayeshSuryavanshi wants to merge 1 commit into
Conversation
HierarchicalClassifier obtains its logger via logging.getLogger(name), a process-global singleton that pickles by name only, so the verbose level set at fit time is lost on unpickle: the restored logger inherits whatever level the current process's singleton happens to have. Add __setstate__ to recreate the logger from the restored self.verbose for fitted models (guarded on logger_ being present so unfitted models are unaffected). Add a regression test that poisons the shared logger and asserts the level survives a pickle round-trip. Closes scikit-learn-contrib#146
Author
|
Note on the failing |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The logger verbose level is not restored after a
HierarchicalClassifieris pickled and unpickled (issue #146)._create_loggerobtains the logger vialogging.getLogger(self.classifier_abbreviation)(e.g."LCPN"), which is a process-global singleton, and Python pickles alogging.Loggerby name only (restoring it viagetLogger(name), discarding the level). So on unpickle,model.verbosesurvives (a plain attribute) butmodel.logger_.getEffectiveLevel()does not, it inherits whatever level the current process's singleton happens to have. Because every instance of a classifier shares one named logger, any other instance or process that touched it determines the restored level.Fix
Add
__setstate__toHierarchicalClassifierthat recreates the logger from the restoredself.verbose:The
if "logger_" in stateguard means only fitted models rebuild the logger. An unfitted model has nologger_, and creating one would add a trailing-underscore attribute that would makecheck_is_fittedwrongly report it as fitted; I verified an unpickled unfitted model still correctly raisesNotFittedError.Test
Added
test_logger_level_preserved_after_pickle, parametrized over all three local classifiers: fit withverbose=logging.WARNING, pickle, poison the shared global logger toDEBUG, unpickle, then assert bothverboseandlogger_.getEffectiveLevel()are stillWARNING. It fails onmain(assert 10 == 30) and passes with the fix.Closes #146