mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-01 23:08:43 +01:00
try to reset log-level after setting it (#10800)
This commit is contained in:
+6
-5
@@ -157,6 +157,8 @@ def main(argv=None): # noqa: C901, PLR0912, PLR0915
|
|||||||
Returns:
|
Returns:
|
||||||
int: command's return code.
|
int: command's return code.
|
||||||
"""
|
"""
|
||||||
|
from contextlib import ExitStack
|
||||||
|
|
||||||
from dvc._debug import debugtools
|
from dvc._debug import debugtools
|
||||||
from dvc.config import ConfigError
|
from dvc.config import ConfigError
|
||||||
from dvc.exceptions import DvcException, NotDvcRepoError
|
from dvc.exceptions import DvcException, NotDvcRepoError
|
||||||
@@ -173,12 +175,11 @@ def main(argv=None): # noqa: C901, PLR0912, PLR0915
|
|||||||
logging.disable(logging.INFO)
|
logging.disable(logging.INFO)
|
||||||
|
|
||||||
args = None
|
args = None
|
||||||
|
stack = ExitStack()
|
||||||
outer_log_level = logger.level
|
|
||||||
level = None
|
|
||||||
try:
|
try:
|
||||||
args = parse_args(argv)
|
args = parse_args(argv)
|
||||||
|
|
||||||
|
level = None
|
||||||
if args.quiet:
|
if args.quiet:
|
||||||
level = logging.CRITICAL
|
level = logging.CRITICAL
|
||||||
elif args.verbose == 1:
|
elif args.verbose == 1:
|
||||||
@@ -187,7 +188,7 @@ def main(argv=None): # noqa: C901, PLR0912, PLR0915
|
|||||||
level = logging.TRACE # type: ignore[attr-defined]
|
level = logging.TRACE # type: ignore[attr-defined]
|
||||||
|
|
||||||
if level is not None:
|
if level is not None:
|
||||||
set_loggers_level(level)
|
stack.enter_context(set_loggers_level(level))
|
||||||
|
|
||||||
if level and level <= logging.DEBUG:
|
if level and level <= logging.DEBUG:
|
||||||
from platform import platform, python_implementation, python_version
|
from platform import platform, python_implementation, python_version
|
||||||
@@ -247,7 +248,7 @@ def main(argv=None): # noqa: C901, PLR0912, PLR0915
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
finally:
|
finally:
|
||||||
logger.setLevel(outer_log_level)
|
stack.close()
|
||||||
|
|
||||||
from dvc.repo.open_repo import clean_repos
|
from dvc.repo.open_repo import clean_repos
|
||||||
|
|
||||||
|
|||||||
+14
-2
@@ -5,6 +5,8 @@ import logging.config
|
|||||||
import logging.handlers
|
import logging.handlers
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from collections.abc import Iterator
|
||||||
|
from contextlib import contextmanager
|
||||||
from typing import ClassVar
|
from typing import ClassVar
|
||||||
|
|
||||||
import colorama
|
import colorama
|
||||||
@@ -174,9 +176,19 @@ def _iter_causes(exc):
|
|||||||
exc = exc.__cause__
|
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"]:
|
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:
|
def setup(level: int = logging.INFO, log_colors: bool = True) -> None:
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
import shutil
|
import shutil
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from collections.abc import Iterable, Iterator
|
from collections.abc import Iterable, Iterator
|
||||||
from contextlib import contextmanager
|
from contextlib import AbstractContextManager, contextmanager
|
||||||
from dataclasses import asdict, dataclass
|
from dataclasses import asdict, dataclass
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import TYPE_CHECKING, Any, Callable, NamedTuple, Optional, Union
|
from typing import TYPE_CHECKING, Any, Callable, NamedTuple, Optional, Union
|
||||||
|
|
||||||
|
from funcy import nullcontext
|
||||||
from scmrepo.exceptions import SCMError
|
from scmrepo.exceptions import SCMError
|
||||||
|
|
||||||
from dvc.env import DVC_EXP_AUTO_PUSH, DVC_EXP_GIT_REMOTE
|
from dvc.env import DVC_EXP_AUTO_PUSH, DVC_EXP_GIT_REMOTE
|
||||||
from dvc.exceptions import DvcException
|
from dvc.exceptions import DvcException
|
||||||
from dvc.log import logger
|
from dvc.log import logger
|
||||||
|
from dvc.logger import set_loggers_level
|
||||||
from dvc.repo.experiments.exceptions import ExperimentExistsError
|
from dvc.repo.experiments.exceptions import ExperimentExistsError
|
||||||
from dvc.repo.experiments.refs import EXEC_BASELINE, EXEC_BRANCH, ExpRefInfo
|
from dvc.repo.experiments.refs import EXEC_BASELINE, EXEC_BRANCH, ExpRefInfo
|
||||||
from dvc.repo.experiments.utils import to_studio_params
|
from dvc.repo.experiments.utils import to_studio_params
|
||||||
@@ -466,8 +467,8 @@ class BaseExecutor(ABC):
|
|||||||
|
|
||||||
if queue is not None:
|
if queue is not None:
|
||||||
queue.put((rev, os.getpid()))
|
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_hash: Optional[str] = None
|
||||||
exp_ref: Optional[ExpRefInfo] = None
|
exp_ref: Optional[ExpRefInfo] = None
|
||||||
@@ -476,14 +477,17 @@ class BaseExecutor(ABC):
|
|||||||
if info.name:
|
if info.name:
|
||||||
ui.write(f"Reproducing experiment '{info.name}'")
|
ui.write(f"Reproducing experiment '{info.name}'")
|
||||||
|
|
||||||
with cls._repro_dvc(
|
with (
|
||||||
info,
|
log_ctx,
|
||||||
infofile,
|
cls._repro_dvc(
|
||||||
log_errors=log_errors,
|
info,
|
||||||
copy_paths=copy_paths,
|
infofile,
|
||||||
message=message,
|
log_errors=log_errors,
|
||||||
**kwargs,
|
copy_paths=copy_paths,
|
||||||
) as dvc:
|
message=message,
|
||||||
|
**kwargs,
|
||||||
|
) as dvc,
|
||||||
|
):
|
||||||
args, kwargs = cls._repro_args(dvc)
|
args, kwargs = cls._repro_args(dvc)
|
||||||
if args:
|
if args:
|
||||||
targets: Optional[Union[list, str]] = args[0]
|
targets: Optional[Union[list, str]] = args[0]
|
||||||
@@ -786,13 +790,10 @@ class BaseExecutor(ABC):
|
|||||||
return orig_rev
|
return orig_rev
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _set_log_level(level):
|
def _set_log_level(level: Optional[int]) -> AbstractContextManager[None]:
|
||||||
# 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")
|
|
||||||
if level is not None:
|
if level is not None:
|
||||||
dvc_logger.setLevel(level)
|
return set_loggers_level(level)
|
||||||
|
return nullcontext()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _copy_path(src, dst):
|
def _copy_path(src, dst):
|
||||||
|
|||||||
@@ -175,7 +175,6 @@ filterwarnings = [
|
|||||||
"ignore:unclosed database.*sqlite3.Connection:ResourceWarning",
|
"ignore:unclosed database.*sqlite3.Connection:ResourceWarning",
|
||||||
"ignore:unclosed.*<socket.socket:ResourceWarning",
|
"ignore:unclosed.*<socket.socket:ResourceWarning",
|
||||||
]
|
]
|
||||||
log_level = "debug"
|
|
||||||
markers = [
|
markers = [
|
||||||
"needs_internet: Might need network access for the tests",
|
"needs_internet: Might need network access for the tests",
|
||||||
"studio: Tests verifying contract between DVC and Studio",
|
"studio: Tests verifying contract between DVC and Studio",
|
||||||
|
|||||||
+5
-5
@@ -1,7 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from contextlib import suppress
|
from contextlib import ExitStack, suppress
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -46,10 +46,10 @@ def reset_loglevel(request, caplog):
|
|||||||
ini_opt = request.config.getini("log_level")
|
ini_opt = request.config.getini("log_level")
|
||||||
|
|
||||||
level = request.config.getoption("--log-level") or ini_opt
|
level = request.config.getoption("--log-level") or ini_opt
|
||||||
if level:
|
with ExitStack() as stack:
|
||||||
with caplog.at_level(level.upper(), logger="dvc"):
|
if level:
|
||||||
yield
|
for name in ["dvc", "dvc_data", "dvc_objects"]:
|
||||||
else:
|
stack.enter_context(caplog.at_level(level.upper(), logger=name))
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from copy import deepcopy
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from dvc import env
|
||||||
from dvc.annotations import Artifact
|
from dvc.annotations import Artifact
|
||||||
from dvc.exceptions import ArtifactNotFoundError, InvalidArgumentError
|
from dvc.exceptions import ArtifactNotFoundError, InvalidArgumentError
|
||||||
from dvc.repo.artifacts import Artifacts, check_name_format
|
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
|
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:
|
with dvc.config.edit("global") as conf:
|
||||||
conf["studio"]["token"] = "mytoken"
|
conf["studio"]["token"] = "mytoken"
|
||||||
|
|
||||||
|
|||||||
@@ -238,9 +238,9 @@ def test_push_pull_unsupported(tmp_dir, dvc, mocker, run_copy, local_remote, cap
|
|||||||
mocker.patch.object(
|
mocker.patch.object(
|
||||||
dvc.cloud, "get_remote_odb", side_effect=RunCacheNotSupported("foo")
|
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)
|
dvc.push(run_cache=True)
|
||||||
assert "failed to push run cache" in caplog.text
|
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)
|
dvc.pull(run_cache=True)
|
||||||
assert "failed to pull run cache" in caplog.text
|
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_REPO_URL, "STUDIO_REPO_URL")
|
||||||
monkeypatch.setenv(DVC_STUDIO_TOKEN, "STUDIO_TOKEN")
|
monkeypatch.setenv(DVC_STUDIO_TOKEN, "STUDIO_TOKEN")
|
||||||
monkeypatch.setenv(DVC_STUDIO_URL, "https://0.0.0.0")
|
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:
|
if dvc_exp_git_remote:
|
||||||
monkeypatch.setenv(DVC_EXP_GIT_REMOTE, dvc_exp_git_remote)
|
monkeypatch.setenv(DVC_EXP_GIT_REMOTE, dvc_exp_git_remote)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user