Make imports on dvc.repo and dvc.repo.plots lazy (#5227)

This commit is contained in:
Saugat Pachhai
2021-01-07 15:02:31 +05:45
committed by GitHub
parent 40122cefa5
commit 66fc988ebf
7 changed files with 45 additions and 24 deletions
+2 -2
View File
@@ -6,12 +6,10 @@ from typing import TYPE_CHECKING
from funcy import cached_property, cat
from dvc.config import Config
from dvc.exceptions import FileMissingError
from dvc.exceptions import IsADirectoryError as DvcIsADirectoryError
from dvc.exceptions import NotDvcRepoError, OutputNotFoundError
from dvc.path_info import PathInfo
from dvc.scm.base import SCMError
from dvc.utils.fs import path_isin
from .graph import build_graph, build_outs_graph, get_pipelines
@@ -94,6 +92,7 @@ class Repo:
assert bool(scm) == bool(rev)
from dvc.scm import SCM
from dvc.scm.base import SCMError
from dvc.scm.git import Git
from dvc.utils.fs import makedirs
@@ -131,6 +130,7 @@ class Repo:
config=None,
):
from dvc.cache import Cache
from dvc.config import Config
from dvc.data_cloud import DataCloud
from dvc.lock import LockNoop, make_lock
from dvc.repo.live import Live
+1 -1
View File
@@ -2,7 +2,6 @@ import logging
from dvc.config import NoRemoteError
from dvc.exceptions import DownloadError
from dvc.scm.base import CloneError
from . import locked
@@ -81,6 +80,7 @@ def fetch(
def _fetch_external(self, repo_url, repo_rev, files, jobs):
from dvc.external_repo import external_repo
from dvc.scm.base import CloneError
failed, downloaded = 0, 0
cache = self.cache.local
+2 -2
View File
@@ -1,8 +1,6 @@
import logging
import os
import shortuuid
from dvc.exceptions import DvcException
from dvc.utils import resolve_output
from dvc.utils.fs import remove
@@ -19,6 +17,8 @@ class GetDVCFileError(DvcException):
def get(url, path, out=None, rev=None):
import shortuuid
from dvc.dvcfile import is_valid_filename
from dvc.external_repo import external_repo
+10 -6
View File
@@ -1,14 +1,18 @@
import contextlib
import os
from typing import List
from typing import TYPE_CHECKING, List, Optional
from dvc.exceptions import MetricDoesNotExistError, MetricsError
from dvc.output import BaseOutput
from dvc.path_info import PathInfo
from dvc.repo import Repo
if TYPE_CHECKING:
from dvc.output import BaseOutput
from dvc.path_info import PathInfo
from dvc.repo import Repo
def summary_path_info(out: BaseOutput) -> PathInfo:
def summary_path_info(out: "BaseOutput") -> Optional["PathInfo"]:
from dvc.output import BaseOutput
assert out.live
has_summary = True
if isinstance(out.live, dict):
@@ -19,7 +23,7 @@ def summary_path_info(out: BaseOutput) -> PathInfo:
class Live:
def __init__(self, repo: Repo):
def __init__(self, repo: "Repo"):
self.repo = repo
def show(self, target: str, revs: List[str] = None):
+4 -2
View File
@@ -9,8 +9,6 @@ from dvc.exceptions import (
NoMetricsFoundError,
NoMetricsParsedError,
)
from dvc.repo.collect import collect
from dvc.repo.plots.data import PlotParsingError
from dvc.utils import relpath
if TYPE_CHECKING:
@@ -95,6 +93,8 @@ class Plots:
@staticmethod
def render(data, revs=None, props=None, templates=None):
"""Renders plots"""
from dvc.repo.plots.data import PlotParsingError
props = props or {}
# Merge data by plot file and apply overriding props
@@ -213,6 +213,8 @@ def _collect_plots(
rev: str = None,
recursive: bool = False,
) -> Dict[str, Dict]:
from dvc.repo.collect import collect
plots, path_infos = collect(
repo,
output_filter=_is_plot,
+6 -8
View File
@@ -3,14 +3,6 @@ from contextlib import suppress
from funcy import concat, first, lfilter, without
from dvc.exceptions import InvalidArgumentError
from dvc.stage.exceptions import (
DuplicateStageName,
InvalidStageName,
StageFileAlreadyExistsError,
)
from ..exceptions import OutputDuplicationError
from . import locked
from .scm_context import scm_context
@@ -61,6 +53,10 @@ def _get_file_path(kwargs):
def _check_stage_exists(dvcfile, stage):
from dvc.stage import PipelineStage
from dvc.stage.exceptions import (
DuplicateStageName,
StageFileAlreadyExistsError,
)
if not dvcfile.exists():
return
@@ -80,7 +76,9 @@ def _check_stage_exists(dvcfile, stage):
@scm_context
def run(self, fname=None, no_exec=False, single_stage=False, **kwargs):
from dvc.dvcfile import PIPELINE_FILE, Dvcfile
from dvc.exceptions import InvalidArgumentError, OutputDuplicationError
from dvc.stage import PipelineStage, Stage, create_stage, restore_meta
from dvc.stage.exceptions import InvalidStageName
if not kwargs.get("cmd"):
raise InvalidArgumentError("command is not specified")
+20 -3
View File
@@ -5,15 +5,12 @@ import typing
from contextlib import suppress
from typing import Iterable, List, NamedTuple, Optional, Set, Tuple
from dvc.dvcfile import PIPELINE_FILE, Dvcfile, is_valid_filename
from dvc.exceptions import (
DvcException,
NoOutputOrStageError,
OutputNotFoundError,
)
from dvc.path_info import PathInfo
from dvc.repo.graph import collect_inside_path, collect_pipeline
from dvc.stage.exceptions import StageFileDoesNotExistError, StageNotFound
from dvc.utils import parse_target, relpath
logger = logging.getLogger(__name__)
@@ -26,6 +23,8 @@ if typing.TYPE_CHECKING:
from dvc.stage.loader import StageLoader
from dvc.types import OptStr
PIPELINE_FILE = "dvc.yaml"
class StageInfo(NamedTuple):
stage: "Stage"
@@ -38,6 +37,8 @@ StageSet = Set["Stage"]
def _collect_with_deps(stages: StageList, graph: "DiGraph") -> StageSet:
from dvc.repo.graph import collect_pipeline
res: StageSet = set()
for stage in stages:
res.update(collect_pipeline(stage, graph=graph))
@@ -47,6 +48,7 @@ def _collect_with_deps(stages: StageList, graph: "DiGraph") -> StageSet:
def _maybe_collect_from_dvc_yaml(
loader: "StageLoad", target, with_deps: bool, **load_kwargs,
) -> StageIter:
from dvc.stage.exceptions import StageNotFound
stages: StageList = []
if loader.tree.exists(PIPELINE_FILE):
@@ -62,6 +64,8 @@ def _collect_specific_target(
recursive: bool,
accept_group: bool,
) -> Tuple[StageIter, "OptStr", "OptStr"]:
from dvc.dvcfile import is_valid_filename
# Optimization: do not collect the graph for a specific target
file, name = parse_target(target)
@@ -163,6 +167,7 @@ class StageLoad:
glob: if true, `name` is considered as a glob, which is
used to filter list of stages from the given `path`.
"""
from dvc.dvcfile import Dvcfile
from dvc.stage.loader import SingleStageLoader, StageLoader
path = self._get_filepath(path, name)
@@ -185,6 +190,8 @@ class StageLoad:
path: if not provided, default `dvc.yaml` is assumed.
name: required for `dvc.yaml` files, ignored for `.dvc` files.
"""
from dvc.dvcfile import Dvcfile
path = self._get_filepath(path, name)
dvcfile = Dvcfile(self.repo, path)
@@ -251,6 +258,8 @@ class StageLoad:
return list(graph) if graph else self.repo.stages
if recursive and self.repo.tree.isdir(target):
from dvc.repo.graph import collect_inside_path
path = os.path.abspath(target)
return collect_inside_path(path, graph or self.graph)
@@ -301,6 +310,12 @@ class StageLoad:
except OutputNotFoundError:
pass
from dvc.dvcfile import is_valid_filename
from dvc.stage.exceptions import (
StageFileDoesNotExistError,
StageNotFound,
)
try:
stages = self.collect(
target,
@@ -331,6 +346,8 @@ class StageLoad:
Otherwise, the file will be skipped, and dvc will partially
load the stages.
"""
from dvc.dvcfile import is_valid_filename
stages = []
outs = set()
for root, dirs, files in self.tree.walk(self.repo.root_dir):