From c4254063cc467f1ae684b178085228589dcb97f0 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 16 Apr 2026 13:53:33 +1000 Subject: [PATCH 1/5] Clean up config logging --- source/config/__init__.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/source/config/__init__.py b/source/config/__init__.py index 16dcbbf98d6..48fd756abb1 100644 --- a/source/config/__init__.py +++ b/source/config/__init__.py @@ -25,7 +25,6 @@ from configobj.validate import Validator from logHandler import log import logging -from logging import DEBUG from utils.caseInsensitiveCollections import CaseInsensitiveSet import winBindings.shell32 from shlobj import FolderId, SHGetKnownFolderPath @@ -589,31 +588,41 @@ def _initBaseConf(self, factoryDefaults=False): self.profiles.append(profile) self._handleProfileSwitch() - def _loadConfig(self, fn, fileError=False): + def _loadConfig(self, fn: str | None, fileError: bool = False) -> ConfigObj: + """Load a configuration from a file. + + :param fn: The filename of the configuration file to load. + :param fileError: Whether to raise an error if the file cannot be read, defaults to False + :raises e: Re-raises any exception that occurs during the profile upgrade process. + :return: The loaded configuration object. + """ log.info("Loading config: {0}".format(fn)) profile = ConfigObj(fn, indent_type="\t", encoding="UTF-8", file_error=fileError) # Python converts \r\n to \n when reading files in Windows, so ConfigObj can't determine the true line ending. profile.newlines = "\r\n" profileCopy = deepcopy(profile) + if NVDAState.shouldWriteToDisk() and profile.filename is not None: + writeProfileFunc = self._writeProfileToFile + else: + writeProfileFunc = None try: - if NVDAState.shouldWriteToDisk() and profile.filename is not None: - writeProfileFunc = self._writeProfileToFile - else: - writeProfileFunc = None profileUpgrader.upgrade(profile, self.validator, writeProfileFunc) except Exception as e: - # Log at level info to ensure that the profile is logged. - log.info("Config before schema update:\n%s" % profileCopy, exc_info=False) + # Log at level debug to ensure that the profile isn't logged by default. + log.debug("Config before schema update:\n%s" % profileCopy, exc_info=False) raise e # since profile settings are not yet imported we have to "peek" to see # if debug level logging is enabled. try: - logLevelName = profile["general"]["loggingLevel"] + logLevelName: str = profile["general"]["loggingLevel"] except KeyError: logLevelName = None - if log.isEnabledFor(log.DEBUG) or (logLevelName and DEBUG >= logging.getLevelName(logLevelName)): - # Log at level info to ensure that the profile is logged. - log.info( + if log.isEnabledFor(log.DEBUG) or ( + logLevelName + and logging.getLevelNamesMapping().get(logLevelName, log.INFO) <= logging.DEBUG + ): + # Log at level debug to ensure that the profile isn't logged by default. + log.debug( "Config loaded (after upgrade, and in the state it will be used by NVDA):\n{0}".format( profile, ), From 19595442435c0b6dcbe414ea31d60735def57cf1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 03:59:21 +0000 Subject: [PATCH 2/5] Pre-commit auto-fix --- source/config/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/config/__init__.py b/source/config/__init__.py index 48fd756abb1..30863083f19 100644 --- a/source/config/__init__.py +++ b/source/config/__init__.py @@ -614,12 +614,11 @@ def _loadConfig(self, fn: str | None, fileError: bool = False) -> ConfigObj: # since profile settings are not yet imported we have to "peek" to see # if debug level logging is enabled. try: - logLevelName: str = profile["general"]["loggingLevel"] + logLevelName: str = profile["general"]["loggingLevel"] except KeyError: logLevelName = None if log.isEnabledFor(log.DEBUG) or ( - logLevelName - and logging.getLevelNamesMapping().get(logLevelName, log.INFO) <= logging.DEBUG + logLevelName and logging.getLevelNamesMapping().get(logLevelName, log.INFO) <= logging.DEBUG ): # Log at level debug to ensure that the profile isn't logged by default. log.debug( From 2b6a73229a93196d57554e26387a419a84b674e6 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Thu, 16 Apr 2026 14:00:30 +1000 Subject: [PATCH 3/5] Update source/config/__init__.py --- source/config/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/config/__init__.py b/source/config/__init__.py index 30863083f19..edadf4df661 100644 --- a/source/config/__init__.py +++ b/source/config/__init__.py @@ -620,8 +620,8 @@ def _loadConfig(self, fn: str | None, fileError: bool = False) -> ConfigObj: if log.isEnabledFor(log.DEBUG) or ( logLevelName and logging.getLevelNamesMapping().get(logLevelName, log.INFO) <= logging.DEBUG ): - # Log at level debug to ensure that the profile isn't logged by default. - log.debug( + # We must log at info level here as the logHandler hasn't been set to log at debug level yet. + log.info( "Config loaded (after upgrade, and in the state it will be used by NVDA):\n{0}".format( profile, ), From d0831590c05ea1ca2e6c9c2b100f061f29e35744 Mon Sep 17 00:00:00 2001 From: Sean Budd Date: Tue, 21 Apr 2026 11:50:53 +1000 Subject: [PATCH 4/5] peek both --- source/config/__init__.py | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/source/config/__init__.py b/source/config/__init__.py index edadf4df661..281dd721dd1 100644 --- a/source/config/__init__.py +++ b/source/config/__init__.py @@ -588,6 +588,25 @@ def _initBaseConf(self, factoryDefaults=False): self.profiles.append(profile) self._handleProfileSwitch() + @staticmethod + def _shouldLogConfigAtStartup(profile: ConfigObj) -> bool: + """since profile settings are not yet imported we have to "peek" to see + if debug level logging is enabled. + + :param profile: The profile to check for logging settings. + :return: True if debug level logging is enabled, False otherwise. + """ + # + try: + logLevelName: str = profile["general"]["loggingLevel"] + if not logLevelName: + level = None + else: + level = logging.getLevelNamesMapping().get(logLevelName) + except KeyError: + level = None + return log.isEnabledFor(log.DEBUG) or (level and logging.DEBUG >= level) + def _loadConfig(self, fn: str | None, fileError: bool = False) -> ConfigObj: """Load a configuration from a file. @@ -608,23 +627,15 @@ def _loadConfig(self, fn: str | None, fileError: bool = False) -> ConfigObj: try: profileUpgrader.upgrade(profile, self.validator, writeProfileFunc) except Exception as e: - # Log at level debug to ensure that the profile isn't logged by default. - log.debug("Config before schema update:\n%s" % profileCopy, exc_info=False) + if self._shouldLogConfigAtStartup(profileCopy): + # We must log at info level here as the logHandler hasn't been set to log at debug level yet. + log.info(f"Config before schema update:\n{profileCopy}") raise e - # since profile settings are not yet imported we have to "peek" to see - # if debug level logging is enabled. - try: - logLevelName: str = profile["general"]["loggingLevel"] - except KeyError: - logLevelName = None - if log.isEnabledFor(log.DEBUG) or ( - logLevelName and logging.getLevelNamesMapping().get(logLevelName, log.INFO) <= logging.DEBUG - ): + + if self._shouldLogConfigAtStartup(profile): # We must log at info level here as the logHandler hasn't been set to log at debug level yet. log.info( - "Config loaded (after upgrade, and in the state it will be used by NVDA):\n{0}".format( - profile, - ), + f"Config loaded (after upgrade, and in the state it will be used by NVDA):\n{profile}" ) return profile From 7416866d382415ffd04425493248bfe61c75b809 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 01:52:08 +0000 Subject: [PATCH 5/5] Pre-commit auto-fix --- source/config/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/config/__init__.py b/source/config/__init__.py index 281dd721dd1..42ba4922779 100644 --- a/source/config/__init__.py +++ b/source/config/__init__.py @@ -635,7 +635,7 @@ def _loadConfig(self, fn: str | None, fileError: bool = False) -> ConfigObj: if self._shouldLogConfigAtStartup(profile): # We must log at info level here as the logHandler hasn't been set to log at debug level yet. log.info( - f"Config loaded (after upgrade, and in the state it will be used by NVDA):\n{profile}" + f"Config loaded (after upgrade, and in the state it will be used by NVDA):\n{profile}", ) return profile