py2: add unicode literals

Fix #1512
This commit is contained in:
Mr. Outis
2019-01-27 20:40:21 -06:00
parent 9c73814805
commit 0d46921ec7
82 changed files with 299 additions and 74 deletions
+3
View File
@@ -3,6 +3,9 @@ DVC
----
Make your data science projects reproducible and shareable.
"""
from __future__ import unicode_literals
import os
import warnings
+2
View File
@@ -1,5 +1,7 @@
"""Main entry point for dvc command line tool."""
from __future__ import unicode_literals
import sys
from dvc.main import main
+4
View File
@@ -1,5 +1,9 @@
"""Collect and send usage analytics"""
from __future__ import unicode_literals
from dvc.utils.compat import str
import os
import json
import errno
+2
View File
@@ -1,5 +1,7 @@
"""Manages cache of a dvc project."""
from __future__ import unicode_literals
import os
from dvc.config import Config
+1
View File
@@ -1,6 +1,7 @@
"""Command line interface for dvc."""
from __future__ import print_function
from __future__ import unicode_literals
import sys
import argparse
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import dvc.logger as logger
from dvc.exceptions import DvcException
from dvc.command.base import CmdBase
+4 -2
View File
@@ -1,4 +1,4 @@
import sys
from __future__ import unicode_literals
import dvc.logger as logger
@@ -11,7 +11,9 @@ def fix_subparsers(subparsers):
Args:
subparsers: subparsers to fix.
"""
if sys.version_info[0] == 3: # pragma: no cover
from dvc.utils.compat import is_py3
if is_py3: # pragma: no cover
subparsers.required = True
subparsers.dest = 'cmd'
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import argparse
from dvc.command.base import fix_subparsers
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.command.base import CmdBase
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import argparse
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.command.base import CmdBase, fix_subparsers
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import argparse
import dvc.logger as logger
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import dvc.prompt as prompt
import dvc.logger as logger
from dvc.command.base import CmdBase
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import dvc.prompt as prompt
import dvc.logger as logger
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import dvc.logger as logger
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import dvc.logger as logger
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import dvc.logger as logger
from dvc.command.base import CmdBase
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import dvc.logger as logger
from dvc.exceptions import DvcException
from dvc.command.base import CmdBase
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import dvc.logger as logger
from dvc.exceptions import DvcException
from dvc.command.base import CmdBase, fix_subparsers
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import dvc.logger as logger
from dvc.exceptions import DvcException
from dvc.command.base import CmdBase
+4
View File
@@ -1,3 +1,7 @@
from __future__ import unicode_literals
from dvc.utils.compat import str
import os
import dvc.logger as logger
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import re
+5 -3
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import dvc.prompt as prompt
import dvc.logger as logger
from dvc.exceptions import DvcException
@@ -13,7 +15,7 @@ class CmdRemove(CmdBase):
return False
msg = (
u'Are you sure you want to remove {} with its outputs?'
'Are you sure you want to remove {} with its outputs?'
.format(target)
)
@@ -21,8 +23,8 @@ class CmdRemove(CmdBase):
return False
raise DvcException(
u'Cannot purge without a confirmation from the user.'
u" Use '-f' to force."
'Cannot purge without a confirmation from the user.'
" Use '-f' to force."
)
def run(self):
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import dvc.logger as logger
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import dvc.logger as logger
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import argparse
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import dvc.logger as logger
from dvc.command.data_sync import CmdDataBase
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import dvc.logger as logger
from dvc.exceptions import DvcException
from dvc.command.base import CmdBase
+10 -6
View File
@@ -1,6 +1,9 @@
"""
DVC config objects.
"""
"""DVC config objects."""
from __future__ import unicode_literals
from dvc.utils.compat import str
import os
import errno
import configobj
@@ -18,8 +21,9 @@ class ConfigError(DvcException):
ex (Exception): optional exception that has caused this error.
"""
def __init__(self, msg, ex=None):
super(ConfigError, self).__init__('config file error: {}'.format(msg),
ex)
super(ConfigError, self).__init__(
'config file error: {}'.format(msg), ex
)
def supported_cache_type(types):
@@ -531,6 +535,6 @@ class Config(object): # pylint: disable=too-many-instance-attributes
for s_key, s_value in config.items():
new_s = {}
for key, value in s_value.items():
new_s[key.lower()] = value
new_s[key.lower()] = str(value)
new_config[s_key.lower()] = new_s
return new_config
+2
View File
@@ -1,5 +1,7 @@
"""Launch `dvc daemon` command in a separate detached process."""
from __future__ import unicode_literals
import os
import sys
import inspect
+4
View File
@@ -1,4 +1,8 @@
"""Draws DAG in ASCII."""
from __future__ import unicode_literals
from __future__ import print_function
import sys
import math
+2
View File
@@ -1,5 +1,7 @@
"""Manages dvc remotes that user can use with push/pull/status comamnds."""
from __future__ import unicode_literals
import dvc.logger as logger
from dvc.config import Config, ConfigError
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import schema
from dvc.config import Config
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.exceptions import DvcException
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.output.gs import OutputGS
from dvc.dependency.base import DependencyBase
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.output.hdfs import OutputHDFS
from dvc.dependency.base import DependencyBase
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.utils.compat import urlparse, urljoin
from dvc.output.base import OutputBase
from dvc.remote.http import RemoteHTTP
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.dependency.base import DependencyBase
from dvc.output.local import OutputLOCAL
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.output.s3 import OutputS3
from dvc.dependency.base import DependencyBase
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.output.ssh import OutputSSH
from dvc.dependency.base import DependencyBase
+15 -6
View File
@@ -1,5 +1,9 @@
"""Exceptions raised by the dvc."""
from __future__ import unicode_literals
from dvc.utils.compat import str, builtin_str
import traceback
@@ -32,9 +36,12 @@ class OutputDuplicationError(DvcException):
stages (list): list of paths to stages.
"""
def __init__(self, output, stages):
assert isinstance(output, str)
assert isinstance(output, str) or isinstance(output, builtin_str)
assert isinstance(stages, list)
assert all(isinstance(stage, str) for stage in stages)
assert all(
isinstance(stage, str) or isinstance(stage, builtin_str)
for stage in stages
)
msg = ("file/directory '{}' is specified as an output in more than one"
"stage: {}").format(output, "\n ".join(stages))
super(OutputDuplicationError, self).__init__(msg)
@@ -50,8 +57,8 @@ class WorkingDirectoryAsOutputError(DvcException):
output.
"""
def __init__(self, cwd, fname):
assert isinstance(cwd, str)
assert isinstance(fname, str)
assert isinstance(cwd, str) or isinstance(cwd, builtin_str)
assert isinstance(fname, str) or isinstance(fname, builtin_str)
msg = (
"current working directory '{cwd}' is specified as an output in"
" '{fname}'. Use another CWD to prevent any data removal."
@@ -68,7 +75,9 @@ class CircularDependencyError(DvcException):
dependency (str): path to the dependency.
"""
def __init__(self, dependency):
assert isinstance(dependency, str)
assert (isinstance(dependency, str) or
isinstance(dependency, builtin_str))
msg = ("file/directory '{}' is specified as an output and as a "
"dependency.")
super(CircularDependencyError, self).__init__(msg.format(dependency))
@@ -82,7 +91,7 @@ class ArgumentDuplicationError(DvcException):
path (str): path to the file/directory.
"""
def __init__(self, path):
assert isinstance(path, str)
assert isinstance(path, str) or isinstance(path, builtin_str)
msg = "file '{}' is specified more than once."
super(ArgumentDuplicationError, self).__init__(msg.format(path))
+5 -4
View File
@@ -1,18 +1,19 @@
"""Use heuristics to guess if it is a text file or a binary file."""
from __future__ import unicode_literals
from dvc.utils.compat import is_py3
# Based on https://eli.thegreenplace.net/2011/10/19/
# perls-guess-if-file-is-text-or-binary-implemented-in-python
import sys
PY3 = sys.version_info[0] == 3
# A function that takes an integer in the 8-bit range and returns
# a single-character byte object in py3 / a single-character string
# in py2.
#
def _int2byte(i):
if PY3:
if is_py3:
return bytes((i,))
return chr(i)
+2
View File
@@ -1,5 +1,7 @@
"""Manages dvc lock file."""
from __future__ import unicode_literals
import os
import time
import zc.lockfile
+5 -1
View File
@@ -1,5 +1,9 @@
"""Manages logger for dvc project."""
from __future__ import unicode_literals
from dvc.utils.compat import str
import re
import sys
import logging
@@ -184,7 +188,7 @@ def colorize(message, color=None):
'red': colorama.Fore.RED,
}
return u'{color}{message}{nc}'.format(
return '{color}{message}{nc}'.format(
color=colors.get(color, ''),
message=message,
nc=colorama.Fore.RESET,
+2
View File
@@ -1,5 +1,7 @@
"""Main entry point for dvc CLI."""
from __future__ import unicode_literals
import dvc.logger as logger
from dvc.cli import parse_args
from dvc.command.base import CmdBase
+3 -1
View File
@@ -1,7 +1,9 @@
from __future__ import unicode_literals
import schema
from dvc.config import Config
from dvc.utils.compat import urlparse
from dvc.utils.compat import urlparse, str
from dvc.output.base import OutputBase
from dvc.output.s3 import OutputS3
+3
View File
@@ -1,3 +1,6 @@
from __future__ import unicode_literals
from dvc.utils.compat import str
import re
from schema import Or, Optional
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.remote.gs import RemoteGS
from dvc.output.s3 import OutputS3
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import posixpath
from dvc.utils.compat import urlparse
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import dvc.logger as logger
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import posixpath
from dvc.remote.s3 import RemoteS3
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import getpass
import posixpath
+4
View File
@@ -1,6 +1,10 @@
"""Manages progress bars for dvc project."""
from __future__ import print_function
from __future__ import unicode_literals
from dvc.utils.compat import str
import sys
import threading
import dvc.logger as logger
+6 -2
View File
@@ -1,3 +1,7 @@
from __future__ import unicode_literals
from dvc.utils.compat import str, builtin_str
import collections
import os
import dvc.prompt as prompt
@@ -1001,7 +1005,7 @@ class Project(object):
col, row = hxsv_path.split(',')
row = int(row)
reader = list(csv.DictReader(fd, delimiter=delimiter))
reader = list(csv.DictReader(fd, delimiter=builtin_str(delimiter)))
return self._do_read_metric_xsv(reader, row, col)
def _read_metric_xsv(self, fd, xsv_path, delimiter):
@@ -1010,7 +1014,7 @@ class Project(object):
col, row = xsv_path.split(',')
row = int(row)
col = int(col)
reader = list(csv.reader(fd, delimiter=delimiter))
reader = list(csv.reader(fd, delimiter=builtin_str(delimiter)))
return self._do_read_metric_xsv(reader, row, col)
def _read_metric(self, path, typ=None, xpath=None):
+4 -5
View File
@@ -1,13 +1,12 @@
"""Manages user prompts."""
from __future__ import unicode_literals
from __future__ import print_function
import sys
from getpass import getpass
try:
# NOTE: in Python3 raw_input() was renamed to input()
input = raw_input # pylint: disable=redefined-builtin, invalid-name
except NameError:
pass
from dvc.utils.compat import input
def _ask(prompt, limited_to=None):
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from dvc.remote.azure import RemoteAzure
from dvc.remote.gs import RemoteGS
from dvc.remote.hdfs import RemoteHDFS
+2
View File
@@ -1,4 +1,6 @@
from __future__ import absolute_import
from __future__ import unicode_literals
import os
import re
+4
View File
@@ -1,3 +1,7 @@
from __future__ import unicode_literals
from dvc.utils.compat import str
import os
import re
import errno
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
try:
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import re
import getpass
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import threading
import requests
+6 -2
View File
@@ -1,3 +1,7 @@
from __future__ import unicode_literals
from dvc.utils.compat import str
import os
import stat
import uuid
@@ -239,12 +243,12 @@ class RemoteLOCAL(RemoteBase):
with open(path, 'r') as fd:
d = json.load(fd)
except Exception:
msg = u"Failed to load dir cache '{}'"
msg = "Failed to load dir cache '{}'"
logger.error(msg.format(os.path.relpath(path)))
return []
if not isinstance(d, list):
msg = u"dir cache file format error '{}' [skipping the file]"
msg = "dir cache file format error '{}' [skipping the file]"
logger.error(msg.format(os.path.relpath(path)))
return []
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import threading
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import getpass
import posixpath
+2
View File
@@ -1,5 +1,7 @@
"""Manages source control systems(e.g. Git)."""
from __future__ import unicode_literals
from dvc.scm.base import Base
from dvc.scm.git import Git
+2
View File
@@ -1,5 +1,7 @@
"""Manages source control systems(e.g. Git) in dvc."""
from __future__ import unicode_literals
import os
from dvc.exceptions import DvcException
+4
View File
@@ -1,9 +1,13 @@
"""Manages Git."""
from __future__ import unicode_literals
# NOTE: need this one because python 2 would re-import this module
# (called git.py) instead of importing gitpython's git module.
from __future__ import absolute_import
from dvc.utils.compat import str
import os
import dvc.logger as logger
+12 -6
View File
@@ -1,3 +1,7 @@
from __future__ import unicode_literals
from dvc.utils.compat import str
import os
import yaml
import posixpath
@@ -14,7 +18,7 @@ from dvc.utils import dict_md5, fix_env
class StageCmdFailedError(DvcException):
def __init__(self, stage):
msg = u"stage '{}' cmd {} failed".format(stage.relpath, stage.cmd)
msg = "stage '{}' cmd {} failed".format(stage.relpath, stage.cmd)
super(StageCmdFailedError, self).__init__(msg)
@@ -72,7 +76,7 @@ class MissingDep(DvcException):
else:
dep = 'dependency'
msg = u'missing {}: {}'.format(dep, ', '.join(map(str, deps)))
msg = 'missing {}: {}'.format(dep, ', '.join(map(str, deps)))
super(MissingDep, self).__init__(msg)
@@ -84,7 +88,7 @@ class MissingDataSource(DvcException):
if len(missing_files) > 1:
source += 's'
msg = u'missing data {}: {}'.format(source, ', '.join(missing_files))
msg = 'missing data {}: {}'.format(source, ', '.join(missing_files))
super(MissingDataSource, self).__init__(msg)
@@ -251,7 +255,7 @@ class Stage(object):
if interactive and not prompt.confirm(msg):
raise DvcException('reproduction aborted by the user')
logger.info(u"Reproducing '{stage}'".format(stage=self.relpath))
logger.info("Reproducing '{stage}'".format(stage=self.relpath))
self.run(dry=dry)
@@ -261,8 +265,10 @@ class Stage(object):
@staticmethod
def validate(d, fname=None):
from dvc.utils import convert_to_unicode
try:
Schema(Stage.SCHEMA).validate(d)
Schema(Stage.SCHEMA).validate(convert_to_unicode(d))
except SchemaError as exc:
raise StageFileFormatError(fname, exc)
@@ -556,7 +562,7 @@ class Stage(object):
self.deps[0].download(self.outs[0].path_info)
elif self.is_data_source:
msg = u"Verifying data sources in '{}'".format(self.relpath)
msg = "Verifying data sources in '{}'".format(self.relpath)
logger.info(msg)
if not dry:
self.check_missing_outputs()
+4
View File
@@ -1,5 +1,9 @@
"""Manages state database used for checksum caching."""
from __future__ import unicode_literals
from dvc.utils.compat import str
import os
import time
import sqlite3
+4
View File
@@ -1,3 +1,7 @@
from __future__ import unicode_literals
from dvc.utils.compat import str
import os
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import sys
import os
import time
+29 -10
View File
@@ -1,6 +1,8 @@
"""
Helpers for other modules.
"""
"""Helpers for other modules."""
from __future__ import unicode_literals
from dvc.utils.compat import str, builtin_str
import os
import sys
import stat
@@ -9,11 +11,6 @@ import json
import shutil
import hashlib
import dvc.logger as logger
from dvc.progress import progress
from dvc.istextfile import istextfile
LOCAL_CHUNK_SIZE = 1024*1024
LARGE_FILE_SIZE = 1024*1024*1024
LARGE_DIR_SIZE = 100
@@ -25,6 +22,10 @@ def dos2unix(data):
def file_md5(fname):
""" get the (md5 hexdigest, md5 digest) of a file """
import dvc.logger as logger
from dvc.progress import progress
from dvc.istextfile import istextfile
if os.path.exists(fname):
hash_md5 = hashlib.md5()
binary = not istextfile(fname)
@@ -81,6 +82,9 @@ def dict_filter(d, exclude=[]):
elif isinstance(d, dict):
ret = {}
for k, v in d.items():
if isinstance(k, builtin_str):
k = str(k)
assert isinstance(k, str)
if k in exclude:
continue
@@ -97,7 +101,9 @@ def dict_md5(d, exclude=[]):
def copyfile(src, dest, no_progress_bar=False, name=None):
'''Copy file with progress bar'''
"""Copy file with progress bar"""
from dvc.progress import progress
copied = 0
name = name if name else os.path.basename(dest)
total = os.stat(src).st_size
@@ -140,10 +146,12 @@ def move(src, dst):
def remove(path):
import dvc.logger as logger
if not os.path.exists(path):
return
logger.debug(u"Removing '{}'".format(os.path.relpath(path)))
logger.debug("Removing '{}'".format(os.path.relpath(path)))
def _chmod(func, p, excinfo):
perm = os.stat(p).st_mode
@@ -192,3 +200,14 @@ def fix_env(env=None):
env.pop(lp_key, None)
return env
def convert_to_unicode(data):
if isinstance(data, builtin_str):
return str(data)
elif isinstance(data, dict):
return dict(map(convert_to_unicode, data.items()))
elif isinstance(data, list) or isinstance(data, tuple):
return type(data)(map(convert_to_unicode, data))
else:
return data
+42 -3
View File
@@ -1,6 +1,45 @@
"""Handle import compatibility between Python 2 and Python 3"""
try:
from urlparse import urlparse, urljoin # noqa: F401
except ImportError:
import sys
# Syntax sugar.
_ver = sys.version_info
#: Python 2.x?
is_py2 = (_ver[0] == 2)
#: Python 3.x?
is_py3 = (_ver[0] == 3)
if is_py2:
from urlparse import urlparse, urljoin # noqa: F401
from StringIO import StringIO # noqa: F401
from BaseHTTPServer import HTTPServer # noqa: F401
from SimpleHTTPServer import SimpleHTTPRequestHandler # noqa: F401
import ConfigParser # 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
elif is_py3:
from urllib.parse import urlparse, urljoin # noqa: F401
from io import StringIO # noqa: F401
from http.server import ( # noqa: F401
HTTPServer, # noqa: F401
SimpleHTTPRequestHandler # noqa: F401
) # noqa: F401
import configparser as ConfigParser # 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
+1 -5
View File
@@ -1,10 +1,6 @@
# This script generates config.ini for setup.iss script
from dvc import VERSION
try:
import configparser as ConfigParser
except ImportError:
import ConfigParser
from dvc.utils.compat import ConfigParser
config = ConfigParser.ConfigParser()
config.add_section('Version')
+2
View File
@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import yaml
import time
+2 -4
View File
@@ -11,6 +11,7 @@ from dvc.state import State
from mock import patch
import dvc.logger as logger
from dvc.utils.compat import str
from dvc.main import main
from dvc.config import Config
from dvc.data_cloud import (DataCloud, RemoteS3, RemoteGS, RemoteAzure,
@@ -21,10 +22,7 @@ from dvc.utils import file_md5
from tests.basic_env import TestDvc
from tests.utils import spy
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
from dvc.utils.compat import StringIO
TEST_REMOTE = 'upstream'
TEST_SECTION = 'remote "{}"'.format(TEST_REMOTE)
+3 -4
View File
@@ -1,3 +1,5 @@
from dvc.utils.compat import str
import os
from uuid import uuid4
@@ -7,10 +9,7 @@ from dvc.main import main
from mock import patch
from tests.basic_env import TestDvc
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
from dvc.utils.compat import StringIO
class TestCmdImport(TestDvc):
+1 -5
View File
@@ -2,15 +2,11 @@ import traceback
from mock import patch
from unittest import TestCase
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import logging
import dvc.logger as logger
from dvc.command.base import CmdBase
from dvc.exceptions import DvcException
from dvc.utils.compat import StringIO
class TestLogger(TestCase):
+2
View File
@@ -1,3 +1,5 @@
from dvc.utils.compat import str
import os
import yaml
import shutil
+2
View File
@@ -1,5 +1,7 @@
import os
from dvc.utils.compat import str
from dvc.state import State
from dvc.utils import file_md5
from dvc.main import main
+2
View File
@@ -1,3 +1,5 @@
from dvc.utils.compat import str
import os
from dvc.state import State
+1 -5
View File
@@ -2,11 +2,7 @@ import hashlib
import os
import threading
try:
from http.server import HTTPServer, SimpleHTTPRequestHandler
except ImportError:
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
from dvc.utils.compat import HTTPServer, SimpleHTTPRequestHandler
class ETagHandler(SimpleHTTPRequestHandler):