try to reset log-level after setting it (#10800)

This commit is contained in:
skshetry
2025-07-11 20:17:29 +05:45
committed by GitHub
parent be1b529bdf
commit 1b9b1f870a
8 changed files with 55 additions and 35 deletions
+6 -5
View File
@@ -157,6 +157,8 @@ def main(argv=None): # noqa: C901, PLR0912, PLR0915
Returns:
int: command's return code.
"""
from contextlib import ExitStack
from dvc._debug import debugtools
from dvc.config import ConfigError
from dvc.exceptions import DvcException, NotDvcRepoError
@@ -173,12 +175,11 @@ def main(argv=None): # noqa: C901, PLR0912, PLR0915
logging.disable(logging.INFO)
args = None
outer_log_level = logger.level
level = None
stack = ExitStack()
try:
args = parse_args(argv)
level = None
if args.quiet:
level = logging.CRITICAL
elif args.verbose == 1:
@@ -187,7 +188,7 @@ def main(argv=None): # noqa: C901, PLR0912, PLR0915
level = logging.TRACE # type: ignore[attr-defined]
if level is not None:
set_loggers_level(level)
stack.enter_context(set_loggers_level(level))
if level and level <= logging.DEBUG:
from platform import platform, python_implementation, python_version
@@ -247,7 +248,7 @@ def main(argv=None): # noqa: C901, PLR0912, PLR0915
return ret
finally:
logger.setLevel(outer_log_level)
stack.close()
from dvc.repo.open_repo import clean_repos
+14 -2
View File
@@ -5,6 +5,8 @@ import logging.config
import logging.handlers
import os
import sys
from collections.abc import Iterator
from contextlib import contextmanager
from typing import ClassVar
import colorama
@@ -174,9 +176,19 @@ def _iter_causes(exc):
exc = exc.__cause__
def set_loggers_level(level: int = logging.INFO) -> None:
@contextmanager
def set_loggers_level(level: int = logging.INFO) -> Iterator[None]:
ret: dict[logging.Logger, int] = {}
for name in ["dvc", "dvc_objects", "dvc_data"]:
logging.getLogger(name).setLevel(level)
_logger = logging.getLogger(name)
ret[_logger] = _logger.getEffectiveLevel()
_logger.setLevel(level)
try:
yield
finally:
for _logger, old_lvl in ret.items():
_logger.setLevel(old_lvl)
def setup(level: int = logging.INFO, log_colors: bool = True) -> None:
+13 -12
View File
@@ -1,20 +1,21 @@
import logging
import os
import pickle
import shutil
from abc import ABC, abstractmethod
from collections.abc import Iterable, Iterator
from contextlib import contextmanager
from contextlib import AbstractContextManager, contextmanager
from dataclasses import asdict, dataclass
from enum import IntEnum
from itertools import chain
from typing import TYPE_CHECKING, Any, Callable, NamedTuple, Optional, Union
from funcy import nullcontext
from scmrepo.exceptions import SCMError
from dvc.env import DVC_EXP_AUTO_PUSH, DVC_EXP_GIT_REMOTE
from dvc.exceptions import DvcException
from dvc.log import logger
from dvc.logger import set_loggers_level
from dvc.repo.experiments.exceptions import ExperimentExistsError
from dvc.repo.experiments.refs import EXEC_BASELINE, EXEC_BRANCH, ExpRefInfo
from dvc.repo.experiments.utils import to_studio_params
@@ -466,8 +467,8 @@ class BaseExecutor(ABC):
if queue is not None:
queue.put((rev, os.getpid()))
if log_errors and log_level is not None:
cls._set_log_level(log_level)
log_ctx = cls._set_log_level(log_level) if log_errors else nullcontext()
exp_hash: Optional[str] = None
exp_ref: Optional[ExpRefInfo] = None
@@ -476,14 +477,17 @@ class BaseExecutor(ABC):
if info.name:
ui.write(f"Reproducing experiment '{info.name}'")
with cls._repro_dvc(
with (
log_ctx,
cls._repro_dvc(
info,
infofile,
log_errors=log_errors,
copy_paths=copy_paths,
message=message,
**kwargs,
) as dvc:
) as dvc,
):
args, kwargs = cls._repro_args(dvc)
if args:
targets: Optional[Union[list, str]] = args[0]
@@ -786,13 +790,10 @@ class BaseExecutor(ABC):
return orig_rev
@staticmethod
def _set_log_level(level):
# When executor.reproduce is run in a multiprocessing child process,
# dvc.cli.main will not be called for that child process so we need to
# setup logging ourselves
dvc_logger = logging.getLogger("dvc")
def _set_log_level(level: Optional[int]) -> AbstractContextManager[None]:
if level is not None:
dvc_logger.setLevel(level)
return set_loggers_level(level)
return nullcontext()
@staticmethod
def _copy_path(src, dst):
-1
View File
@@ -175,7 +175,6 @@ filterwarnings = [
"ignore:unclosed database.*sqlite3.Connection:ResourceWarning",
"ignore:unclosed.*<socket.socket:ResourceWarning",
]
log_level = "debug"
markers = [
"needs_internet: Might need network access for the tests",
"studio: Tests verifying contract between DVC and Studio",
+4 -4
View File
@@ -1,7 +1,7 @@
import json
import os
import sys
from contextlib import suppress
from contextlib import ExitStack, suppress
import pytest
@@ -46,10 +46,10 @@ def reset_loglevel(request, caplog):
ini_opt = request.config.getini("log_level")
level = request.config.getoption("--log-level") or ini_opt
with ExitStack() as stack:
if level:
with caplog.at_level(level.upper(), logger="dvc"):
yield
else:
for name in ["dvc", "dvc_data", "dvc_objects"]:
stack.enter_context(caplog.at_level(level.upper(), logger=name))
yield
+8 -1
View File
@@ -4,6 +4,7 @@ from copy import deepcopy
import pytest
from dvc import env
from dvc.annotations import Artifact
from dvc.exceptions import ArtifactNotFoundError, InvalidArgumentError
from dvc.repo.artifacts import Artifacts, check_name_format
@@ -283,7 +284,13 @@ def test_artifacts_download_subrepo(tmp_dir, scm, sub):
assert Artifacts.get(".", name, force=True) == result
def test_artifacts_download_studio(tmp_dir, dvc, mocker):
def test_artifacts_download_studio(monkeypatch, tmp_dir, dvc, mocker, tmp_path_factory):
global_config_dir = tmp_path_factory.mktemp("global_config")
monkeypatch.setenv(env.DVC_GLOBAL_CONFIG_DIR, str(global_config_dir))
# reset config to ensure it picks up the new global config
dvc.__dict__.pop("config")
assert dvc.config.files["global"] == os.fspath(global_config_dir / "config")
with dvc.config.edit("global") as conf:
conf["studio"]["token"] = "mytoken"
+2 -2
View File
@@ -238,9 +238,9 @@ def test_push_pull_unsupported(tmp_dir, dvc, mocker, run_copy, local_remote, cap
mocker.patch.object(
dvc.cloud, "get_remote_odb", side_effect=RunCacheNotSupported("foo")
)
with caplog.at_level(logging.DEBUG):
with caplog.at_level(logging.DEBUG, logger="dvc"):
dvc.push(run_cache=True)
assert "failed to push run cache" in caplog.text
with caplog.at_level(logging.DEBUG):
with caplog.at_level(logging.DEBUG, logger="dvc"):
dvc.pull(run_cache=True)
assert "failed to pull run cache" in caplog.text
@@ -29,7 +29,7 @@ def test_post_to_studio(
monkeypatch.setenv(DVC_STUDIO_REPO_URL, "STUDIO_REPO_URL")
monkeypatch.setenv(DVC_STUDIO_TOKEN, "STUDIO_TOKEN")
monkeypatch.setenv(DVC_STUDIO_URL, "https://0.0.0.0")
monkeypatch.setenv(DVC_STUDIO_OFFLINE, offline)
monkeypatch.setenv(DVC_STUDIO_OFFLINE, str(offline))
if dvc_exp_git_remote:
monkeypatch.setenv(DVC_EXP_GIT_REMOTE, dvc_exp_git_remote)