From 086acf640449c63b3d57ea47f8b1aa1cec81f660 Mon Sep 17 00:00:00 2001 From: "Mr. Outis" Date: Tue, 31 Dec 2019 23:42:00 -0600 Subject: [PATCH] py3: dvc/utils/compat.py -> dvc/compat.py --- dvc/compat.py | 42 ++++++++++++ dvc/output/local.py | 2 +- dvc/remote/local.py | 2 +- dvc/repo/__init__.py | 2 +- dvc/scm/tree.py | 2 +- dvc/state.py | 2 +- dvc/system.py | 2 +- dvc/utils/__init__.py | 4 +- dvc/utils/compat.py | 129 ----------------------------------- tests/dir_helpers.py | 2 +- tests/func/test_add.py | 2 +- tests/func/test_analytics.py | 2 +- tests/func/test_api.py | 2 +- tests/func/test_get.py | 2 +- tests/func/test_ignore.py | 3 +- tests/func/test_import.py | 2 +- tests/func/test_remote.py | 2 +- tests/func/test_repo.py | 2 +- tests/unit/test_rwlock.py | 2 +- 19 files changed, 60 insertions(+), 148 deletions(-) create mode 100644 dvc/compat.py delete mode 100644 dvc/utils/compat.py diff --git a/dvc/compat.py b/dvc/compat.py new file mode 100644 index 000000000..1c5b77f40 --- /dev/null +++ b/dvc/compat.py @@ -0,0 +1,42 @@ +"""Python version compatibility code""" + +# Backport os.fspath() from Python 3.6 +try: + from os import fspath # noqa: F821 + + fspath_py35 = lambda s: s # noqa: E731 +except ImportError: + + def fspath(path): + """Return the path representation of a path-like object. + + If str or bytes is passed in, it is returned unchanged. Otherwise the + os.PathLike interface is used to get the path representation. If the + path representation is not str or bytes, TypeError is raised. If the + provided path is not str, bytes, or os.PathLike, TypeError is raised. + """ + if isinstance(path, (str, bytes)): + return path + + # Work from the object's type to match method resolution of other magic + # methods. + path_type = type(path) + try: + path_repr = path_type.__fspath__(path) + except AttributeError: + if hasattr(path_type, "__fspath__"): + raise + else: + raise TypeError( + "expected str, bytes or os.PathLike object, " + "not " + path_type.__name__ + ) + if isinstance(path_repr, (str, bytes)): + return path_repr + else: + raise TypeError( + "expected {}.__fspath__() to return str or bytes, " + "not {}".format(path_type.__name__, type(path_repr).__name__) + ) + + fspath_py35 = fspath diff --git a/dvc/output/local.py b/dvc/output/local.py index 64e2e3388..a5585a052 100644 --- a/dvc/output/local.py +++ b/dvc/output/local.py @@ -7,7 +7,7 @@ from dvc.istextfile import istextfile from dvc.output.base import OutputBase from dvc.remote.local import RemoteLOCAL from dvc.utils import relpath -from dvc.utils.compat import fspath_py35 +from dvc.compat import fspath_py35 from dvc.utils.fs import path_isin diff --git a/dvc/remote/local.py b/dvc/remote/local.py index a454b800b..54de5f495 100644 --- a/dvc/remote/local.py +++ b/dvc/remote/local.py @@ -28,7 +28,7 @@ from dvc.utils import makedirs from dvc.utils import relpath from dvc.utils import tmp_fname from dvc.utils import walk_files -from dvc.utils.compat import fspath_py35 +from dvc.compat import fspath_py35 from dvc.utils.fs import move from dvc.utils.fs import remove diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py index fe59db124..0535df033 100644 --- a/dvc/repo/__init__.py +++ b/dvc/repo/__init__.py @@ -5,7 +5,7 @@ from functools import wraps from itertools import chain from dvc.ignore import CleanTree -from dvc.utils.compat import fspath_py35 +from dvc.compat import fspath_py35 from funcy import cached_property diff --git a/dvc/scm/tree.py b/dvc/scm/tree.py index 519cb4159..3187e300a 100644 --- a/dvc/scm/tree.py +++ b/dvc/scm/tree.py @@ -1,6 +1,6 @@ import os -from dvc.utils.compat import fspath +from dvc.compat import fspath class BaseTree(object): diff --git a/dvc/state.py b/dvc/state.py index 26ff2f70d..619740f55 100644 --- a/dvc/state.py +++ b/dvc/state.py @@ -11,7 +11,7 @@ from dvc.exceptions import DvcException from dvc.utils import current_timestamp from dvc.utils import relpath from dvc.utils import to_chunks -from dvc.utils.compat import fspath_py35 +from dvc.compat import fspath_py35 from dvc.utils.fs import get_inode from dvc.utils.fs import get_mtime_and_size from dvc.utils.fs import remove diff --git a/dvc/system.py b/dvc/system.py index 181b1b13d..59b609236 100644 --- a/dvc/system.py +++ b/dvc/system.py @@ -3,7 +3,7 @@ import logging import os import shutil -from dvc.utils.compat import fspath +from dvc.compat import fspath logger = logging.getLogger(__name__) diff --git a/dvc/utils/__init__.py b/dvc/utils/__init__.py index 4078de00e..cca9ebebe 100644 --- a/dvc/utils/__init__.py +++ b/dvc/utils/__init__.py @@ -15,7 +15,7 @@ import nanotime from ruamel.yaml import YAML from shortuuid import uuid -from dvc.utils.compat import fspath, fspath_py35 +from dvc.compat import fspath, fspath_py35 logger = logging.getLogger(__name__) @@ -387,7 +387,7 @@ def env2bool(var, undefined=False): def resolve_output(inp, out): - from dvc.utils.compat import urlparse + from urllib.parse import urlparse name = os.path.basename(urlparse(inp).path) if not out: diff --git a/dvc/utils/compat.py b/dvc/utils/compat.py deleted file mode 100644 index 8c0711ace..000000000 --- a/dvc/utils/compat.py +++ /dev/null @@ -1,129 +0,0 @@ -"""Handle import compatibility between Python 2 and Python 3""" - -import errno -import sys -from contextlib import contextmanager - -# Syntax sugar. -_ver = sys.version_info - -#: Python 2.x? -is_py2 = _ver[0] == 2 - -#: Python 3.x? -is_py3 = _ver[0] == 3 - - -@contextmanager -def ignore_file_not_found(): - try: - yield - except IOError as exc: - if exc.errno != errno.ENOENT: - raise - - -if is_py2: - from urlparse import urlparse, urlunparse, urljoin # noqa: F401 - from urllib import urlencode # noqa: F401 - import ConfigParser # noqa: F401 - from io import open # noqa: F401 - import pathlib2 as pathlib # noqa: F401 - from collections import Mapping # noqa: F401 - from contextlib2 import ExitStack # noqa: F401 - - builtin_str = str # noqa: F821 - bytes = str # noqa: F821 - str = unicode # noqa: F821 - basestring = basestring # noqa: F821 - numeric_types = (int, long, float) # noqa: F821 - integer_types = (int, long) # noqa: F821 - input = raw_input # noqa: F821 - range = xrange # noqa: F821 - FileNotFoundError = IOError - JSONDecodeError = ValueError - - import StringIO - import io - - class StringIO(StringIO.StringIO): - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - class BytesIO(io.BytesIO): - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - -elif is_py3: - import pathlib # noqa: F401 - from urllib.parse import ( # noqa: F401 - urlparse, # noqa: F401 - urlunparse, # noqa: F401 - urlencode, # noqa: F401 - urljoin, # noqa: F401 - ) - from io import StringIO, BytesIO # noqa: F401 - import configparser as ConfigParser # noqa: F401 - from collections.abc import Mapping # noqa: F401 - from contextlib import ExitStack # noqa: F401 - from json.decoder import JSONDecodeError # noqa: F401 - - builtin_str = str # noqa: F821 - str = str # noqa: F821 - bytes = bytes # noqa: F821 - basestring = (str, bytes) # noqa: F821 - numeric_types = (int, float) # noqa: F821 - integer_types = (int,) # noqa: F821 - input = input # noqa: F821 - open = open # noqa: F821 - range = range # noqa: F821 - FileNotFoundError = FileNotFoundError - - -# Backport os.fspath() from Python 3.6 -try: - from os import fspath # noqa: F821 - - fspath_py35 = lambda s: s # noqa: E731 -except ImportError: - - def fspath(path): - """Return the path representation of a path-like object. - - If str or bytes is passed in, it is returned unchanged. Otherwise the - os.PathLike interface is used to get the path representation. If the - path representation is not str or bytes, TypeError is raised. If the - provided path is not str, bytes, or os.PathLike, TypeError is raised. - """ - if isinstance(path, (str, bytes)): - return path - - # Work from the object's type to match method resolution of other magic - # methods. - path_type = type(path) - try: - path_repr = path_type.__fspath__(path) - except AttributeError: - if hasattr(path_type, "__fspath__"): - raise - else: - raise TypeError( - "expected str, bytes or os.PathLike object, " - "not " + path_type.__name__ - ) - if isinstance(path_repr, (str, bytes)): - return path_repr - else: - raise TypeError( - "expected {}.__fspath__() to return str or bytes, " - "not {}".format(path_type.__name__, type(path_repr).__name__) - ) - - fspath_py35 = fspath diff --git a/tests/dir_helpers.py b/tests/dir_helpers.py index 058c498f6..29dca8fc0 100644 --- a/tests/dir_helpers.py +++ b/tests/dir_helpers.py @@ -50,7 +50,7 @@ import pytest from funcy.py3 import lmap, retry from dvc.utils import makedirs -from dvc.utils.compat import fspath, fspath_py35 +from dvc.compat import fspath, fspath_py35 __all__ = ["tmp_dir", "scm", "dvc", "repo_template", "run_copy", "erepo_dir"] diff --git a/tests/func/test_add.py b/tests/func/test_add.py index fd1853809..1c885ead7 100644 --- a/tests/func/test_add.py +++ b/tests/func/test_add.py @@ -23,7 +23,7 @@ from dvc.system import System from dvc.utils import file_md5 from dvc.utils import LARGE_DIR_SIZE from dvc.utils import relpath -from dvc.utils.compat import fspath +from dvc.compat import fspath from dvc.utils.fs import path_isin from dvc.utils.stage import load_stage_file from tests.basic_env import TestDvc diff --git a/tests/func/test_analytics.py b/tests/func/test_analytics.py index 4279d493b..2e0a18498 100644 --- a/tests/func/test_analytics.py +++ b/tests/func/test_analytics.py @@ -1,7 +1,7 @@ import mock from dvc.main import main -from dvc.utils.compat import fspath +from dvc.compat import fspath @mock.patch("dvc.analytics.send") diff --git a/tests/func/test_api.py b/tests/func/test_api.py index 393e94edf..b8b4f670d 100644 --- a/tests/func/test_api.py +++ b/tests/func/test_api.py @@ -11,7 +11,7 @@ from dvc.exceptions import FileMissingError from dvc.main import main from dvc.path_info import URLInfo from dvc.remote.config import RemoteConfig -from dvc.utils.compat import fspath +from dvc.compat import fspath from tests.remotes import Azure, GCP, HDFS, Local, OSS, S3, SSH diff --git a/tests/func/test_get.py b/tests/func/test_get.py index 4236c4409..b69f99851 100644 --- a/tests/func/test_get.py +++ b/tests/func/test_get.py @@ -10,7 +10,7 @@ from dvc.repo.get import GetDVCFileError, PathMissingError from dvc.repo import Repo from dvc.system import System from dvc.utils import makedirs -from dvc.utils.compat import fspath +from dvc.compat import fspath from tests.utils import trees_equal diff --git a/tests/func/test_ignore.py b/tests/func/test_ignore.py index 3074ef05c..ff722d5db 100644 --- a/tests/func/test_ignore.py +++ b/tests/func/test_ignore.py @@ -7,8 +7,7 @@ from dvc.exceptions import DvcIgnoreInCollectedDirError from dvc.ignore import DvcIgnore, DvcIgnoreDirs, DvcIgnorePatterns, CleanTree from dvc.scm.tree import WorkingTree from dvc.utils import relpath -from dvc.utils.compat import fspath_py35 -from dvc.utils.compat import fspath +from dvc.compat import fspath_py35, fspath from dvc.utils.fs import get_mtime_and_size from dvc.remote import RemoteLOCAL diff --git a/tests/func/test_import.py b/tests/func/test_import.py index 99da2df89..45b1441df 100644 --- a/tests/func/test_import.py +++ b/tests/func/test_import.py @@ -13,7 +13,7 @@ from dvc.exceptions import NoOutputInExternalRepoError from dvc.stage import Stage from dvc.system import System from dvc.utils import makedirs -from dvc.utils.compat import fspath +from dvc.compat import fspath from tests.utils import trees_equal diff --git a/tests/func/test_remote.py b/tests/func/test_remote.py index f3140b5f3..958686c87 100644 --- a/tests/func/test_remote.py +++ b/tests/func/test_remote.py @@ -11,7 +11,7 @@ from dvc.main import main from dvc.path_info import PathInfo from dvc.remote import RemoteLOCAL, RemoteConfig from dvc.remote.base import RemoteBASE -from dvc.utils.compat import fspath +from dvc.compat import fspath from tests.basic_env import TestDvc from tests.remotes import get_local_url, get_local_storagepath diff --git a/tests/func/test_repo.py b/tests/func/test_repo.py index 51f3a8754..26cdf15b2 100644 --- a/tests/func/test_repo.py +++ b/tests/func/test_repo.py @@ -4,7 +4,7 @@ from dvc.scm.git.tree import GitTree from dvc.cache import Cache from dvc.repo import Repo from dvc.system import System -from dvc.utils.compat import fspath +from dvc.compat import fspath def test_destroy(tmp_dir, dvc): diff --git a/tests/unit/test_rwlock.py b/tests/unit/test_rwlock.py index 410624404..f44e0303f 100644 --- a/tests/unit/test_rwlock.py +++ b/tests/unit/test_rwlock.py @@ -9,7 +9,7 @@ from dvc.rwlock import ( RWLockFileCorruptedError, ) from dvc.lock import LockError -from dvc.utils.compat import fspath +from dvc.compat import fspath from dvc.path_info import PathInfo