diff --git a/dvc/dependency/param.py b/dvc/dependency/param.py index a83ad9448..6fc4d60de 100644 --- a/dvc/dependency/param.py +++ b/dvc/dependency/param.py @@ -2,7 +2,7 @@ import logging import os import typing from collections import defaultdict -from typing import Dict, cast +from typing import Dict import dpath.util from voluptuous import Any @@ -111,7 +111,8 @@ class ParamsDependency(Dependency): from funcy import ldistinct status: Dict[str, Any] = defaultdict(dict) - info = cast(dict, self.hash_info.value) if self.hash_info else {} + assert isinstance(self.hash_info.value, dict) + info = self.hash_info.value if self.hash_info else {} actual = self.read_params() # NOTE: we want to preserve the order of params as specified in the diff --git a/dvc/fs/callbacks.py b/dvc/fs/callbacks.py index 024aa9f0c..6b0bbbb99 100644 --- a/dvc/fs/callbacks.py +++ b/dvc/fs/callbacks.py @@ -1,6 +1,6 @@ # pylint: disable=unused-import from contextlib import ExitStack -from typing import TYPE_CHECKING, Any, BinaryIO, Dict, Optional, Union, cast +from typing import TYPE_CHECKING, Any, BinaryIO, Dict, Optional, Union from dvc.utils.objects import cached_property from dvc_objects.fs.callbacks import ( # noqa: F401 @@ -54,7 +54,8 @@ class RichCallback(Callback): disable=self.disable, console=ui.error_console, ) - return cast(RichTransferProgress, self._stack.enter_context(progress)) + self._stack.enter_context(progress) + return progress @cached_property def task(self) -> "TaskID": diff --git a/dvc/output.py b/dvc/output.py index c74524d53..9d53927b5 100644 --- a/dvc/output.py +++ b/dvc/output.py @@ -3,7 +3,7 @@ import os import posixpath from collections import defaultdict from operator import itemgetter -from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Type, cast +from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Type from urllib.parse import urlparse from funcy import collecting, first, project @@ -20,7 +20,6 @@ from dvc.exceptions import ( RemoteCacheRequiredError, ) from dvc.utils.objects import cached_property -from dvc_data.hashfile import Tree from dvc_data.hashfile import check as ocheck from dvc_data.hashfile import load as oload from dvc_data.hashfile.build import build @@ -29,6 +28,7 @@ from dvc_data.hashfile.hash_info import HashInfo from dvc_data.hashfile.istextfile import istextfile from dvc_data.hashfile.meta import Meta from dvc_data.hashfile.transfer import transfer as otransfer +from dvc_data.hashfile.tree import Tree from dvc_objects.errors import ObjectFormatError from .annotations import ANNOTATION_FIELDS, ANNOTATION_SCHEMA, Annotation @@ -753,15 +753,16 @@ class Output: def _commit_granular_dir(self, filter_info, hardlink) -> Optional["HashFile"]: prefix = self.fs.path.parts(self.fs.path.relpath(filter_info, self.fs_path)) - staging, _, save_obj = build( + staging, _, obj = build( self.cache, self.fs_path, self.fs, self.hash_name, ignore=self.dvcignore, ) - save_obj = cast(Tree, save_obj) - save_obj = cast(Tree, save_obj.filter(prefix)) + assert isinstance(obj, Tree) + save_obj = obj.filter(prefix) + assert isinstance(save_obj, Tree) checkout_obj = save_obj.get_obj(self.cache, prefix) otransfer( staging, @@ -826,7 +827,7 @@ class Output: if with_files: obj = self.obj or self.get_obj() if obj: - obj = cast("Tree", obj) + assert isinstance(obj, Tree) ret[self.PARAM_FILES] = [ split_file_meta_from_cloud(f) for f in _serialize_tree_obj_to_files(obj) @@ -874,7 +875,7 @@ class Output: fs_path = self.fs.path if filter_info and filter_info != self.fs_path: prefix = fs_path.relparts(filter_info, self.fs_path) - obj = cast(Tree, obj) + assert isinstance(obj, Tree) obj = obj.get_obj(self.cache, prefix) return obj @@ -1056,12 +1057,12 @@ class Output: return None obj = self.get_obj() + assert obj is None or isinstance(obj, Tree) if filter_info and filter_info != self.fs_path: assert obj prefix = self.fs.path.parts(self.fs.path.relpath(filter_info, self.fs_path)) - obj = cast(Tree, obj) return obj.filter(prefix) - return cast(Tree, obj) + return obj def get_used_objs( # noqa: C901, PLR0911 self, **kwargs diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py index bd89fbd8e..bf1aa5907 100644 --- a/dvc/repo/__init__.py +++ b/dvc/repo/__init__.py @@ -3,7 +3,7 @@ import os from collections import defaultdict from contextlib import contextmanager from functools import wraps -from typing import TYPE_CHECKING, Callable, Iterable, List, Optional, Tuple, Union, cast +from typing import TYPE_CHECKING, Callable, Iterable, List, Optional, Tuple, Union from dvc.exceptions import FileMissingError from dvc.exceptions import IsADirectoryError as DvcIsADirectoryError @@ -14,7 +14,7 @@ from dvc.utils.fs import path_isin from dvc.utils.objects import cached_property if TYPE_CHECKING: - from dvc.fs import FileSystem, GitFileSystem + from dvc.fs import FileSystem from dvc.fs.data import DataFileSystem from dvc.fs.dvc import DVCFileSystem from dvc.lock import LockBase @@ -223,7 +223,8 @@ class Repo: self.cache = CacheManager(self) else: if isinstance(self.fs, LocalFileSystem): - self.fs.makedirs(cast(str, self.tmp_dir), exist_ok=True) + assert self.tmp_dir + self.fs.makedirs(self.tmp_dir, exist_ok=True) self.lock = make_lock( self.fs.path.join(self.tmp_dir, "lock"), @@ -348,7 +349,7 @@ class Repo: return DvcIgnoreFilter(self.fs, self.root_dir) def get_rev(self): - from dvc.fs import LocalFileSystem + from dvc.fs import GitFileSystem, LocalFileSystem assert self.scm if isinstance(self.fs, LocalFileSystem): @@ -356,7 +357,8 @@ class Repo: with map_scm_exception(): return self.scm.get_rev() - return cast("GitFileSystem", self.fs).rev + assert isinstance(self.fs, GitFileSystem) + return self.fs.rev @cached_property def experiments(self) -> "Experiments": diff --git a/dvc/repo/imports.py b/dvc/repo/imports.py index 3405cfa09..0ec11e065 100644 --- a/dvc/repo/imports.py +++ b/dvc/repo/imports.py @@ -1,7 +1,7 @@ import logging import os from tempfile import TemporaryDirectory -from typing import TYPE_CHECKING, List, Set, Tuple, Union, cast +from typing import TYPE_CHECKING, List, Set, Tuple, Union if TYPE_CHECKING: from dvc.dependency.base import Dependency @@ -9,7 +9,8 @@ if TYPE_CHECKING: from dvc.repo.index import Index, IndexView from dvc.stage import Stage from dvc.types import TargetType - from dvc_data.hashfile import HashInfo + from dvc_data.hashfile.hash_info import HashInfo + logger = logging.getLogger(__name__) @@ -63,6 +64,8 @@ def unpartial_imports(index: Union["Index", "IndexView"]) -> int: Returns: Total number of files which were unpartialed. """ + from dvc_data.hashfile.hash_info import HashInfo + updated = 0 for out in index.outs: # we need to use view[key] here and since the out fields have not been @@ -75,7 +78,8 @@ def unpartial_imports(index: Union["Index", "IndexView"]) -> int: out.hash_info = dep.get_obj().hash_info out.meta = dep.get_meta() else: - out.hash_info = cast("HashInfo", entry.hash_info) + assert isinstance(entry.hash_info, HashInfo) + out.hash_info = entry.hash_info out.meta = entry.meta out.stage.md5 = out.stage.compute_md5() out.stage.dump() diff --git a/dvc/repo/index.py b/dvc/repo/index.py index 217b2278e..361b5796d 100644 --- a/dvc/repo/index.py +++ b/dvc/repo/index.py @@ -337,7 +337,7 @@ class Index: @cached_property def data_tree(self): - from dvc_data.hashfile import Tree + from dvc_data.hashfile.tree import Tree tree = Tree() for out in self.outs: diff --git a/dvc/repo/worktree.py b/dvc/repo/worktree.py index 668640044..6caf14cb1 100644 --- a/dvc/repo/worktree.py +++ b/dvc/repo/worktree.py @@ -1,6 +1,6 @@ import logging from functools import partial -from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional, Set, Tuple, Union, cast +from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional, Set, Tuple, Union from funcy import first @@ -17,7 +17,6 @@ if TYPE_CHECKING: from dvc.stage import Stage from dvc.types import TargetType from dvc_data.hashfile.meta import Meta - from dvc_data.hashfile.tree import Tree from dvc_data.index import DataIndex, DataIndexView from dvc_objects.fs.base import FileSystem @@ -29,7 +28,8 @@ logger = logging.getLogger(__name__) def _meta_checksum(fs: "FileSystem", meta: "Meta") -> Any: if not meta or meta.isdir: return meta - return getattr(meta, cast(str, fs.PARAM_CHECKSUM)) + assert fs.PARAM_CHECKSUM + return getattr(meta, fs.PARAM_CHECKSUM) def worktree_view_by_remotes( @@ -216,13 +216,15 @@ def _merge_push_meta( conflicts (i.e. the DVC output's version ID may not match the pushed/latest version ID as long when the file content of both versions is the same). """ + from dvc_data.hashfile.tree import Tree from dvc_data.index.save import build_tree _, key = out.index_key entry = index[key] repo = out.stage.repo if out.isdir(): - old_tree = cast("Tree", out.get_obj()) + old_tree = out.get_obj() + assert isinstance(old_tree, Tree) entry.hash_info = old_tree.hash_info entry.meta = out.meta for subkey, entry in index.iteritems(key): @@ -419,6 +421,7 @@ def _get_update_diff_index( remote_index: Union["DataIndex", "DataIndexView"], remote: "Remote", ) -> "DataIndex": + from dvc_data.hashfile.tree import Tree from dvc_data.index import DataIndex from dvc_data.index.diff import ADD, MODIFY, UNCHANGED, diff @@ -438,7 +441,8 @@ def _get_update_diff_index( if out.isdir(): if not entry.meta.isdir: fs_path = repo.fs.path.join(repo.root_dir, *entry.key) - tree = cast("Tree", out.obj) + tree = out.obj + assert isinstance(tree, Tree) _, entry.hash_info = tree.get( # type: ignore[misc] repo.fs.path.relparts(fs_path, out.fs_path) ) diff --git a/dvc/stage/serialize.py b/dvc/stage/serialize.py index 23c665603..8c6a7de2e 100644 --- a/dvc/stage/serialize.py +++ b/dvc/stage/serialize.py @@ -8,7 +8,6 @@ from typing import ( List, Optional, Union, - cast, no_type_check, ) @@ -24,7 +23,6 @@ from .utils import resolve_wdir, split_params_deps if TYPE_CHECKING: from dvc.stage import PipelineStage, Stage - from dvc_data.hashfile.tree import Tree PARAM_PARAMS = ParamsDependency.PARAM_PARAMS PARAM_PATH = ParamsDependency.PARAM_PATH @@ -155,6 +153,7 @@ def to_pipeline_file(stage: "PipelineStage"): def to_single_stage_lockfile(stage: "Stage", **kwargs) -> dict: from dvc.output import _serialize_tree_obj_to_files, split_file_meta_from_cloud + from dvc_data.hashfile.tree import Tree assert stage.cmd @@ -163,7 +162,7 @@ def to_single_stage_lockfile(stage: "Stage", **kwargs) -> dict: if item.hash_info.isdir and kwargs.get("with_files"): obj = item.obj or item.get_obj() if obj: - obj = cast("Tree", obj) + assert isinstance(obj, Tree) ret[item.PARAM_FILES] = [ split_file_meta_from_cloud(f) for f in _serialize_tree_obj_to_files(obj) diff --git a/dvc/utils/serialize/_common.py b/dvc/utils/serialize/_common.py index 7ab6a30ef..3b715d90a 100644 --- a/dvc/utils/serialize/_common.py +++ b/dvc/utils/serialize/_common.py @@ -11,7 +11,6 @@ from typing import ( Protocol, TextIO, Union, - cast, ) from funcy import reraise @@ -97,8 +96,7 @@ def _modify_data( dumper: DumpersFn, fs: Optional["FileSystem"] = None, ): - exists_fn = cast(Callable[["StrPath"], bool], fs.exists if fs else os.path.exists) - file_exists = exists_fn(cast(str, path)) + file_exists = fs.exists(os.fspath(path)) if fs else os.path.exists(path) data = _load_data(path, parser=parser, fs=fs) if file_exists else {} yield data _dump_data(path, data, dumper=dumper, fs=fs)