From 24743f77d394d83c9e80b181cda8f1d0bc04f436 Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Wed, 27 Jun 2018 21:15:43 -0400 Subject: [PATCH 1/3] Switch to using pathlib2 for python<3.5 - Fixes #2438 Signed-off-by: Dan Ryan --- news/2454.bugfix | 1 + pipenv/_compat.py | 11 +++++++---- pipenv/project.py | 5 +---- pipenv/utils.py | 10 ++-------- 4 files changed, 11 insertions(+), 16 deletions(-) create mode 100644 news/2454.bugfix diff --git a/news/2454.bugfix b/news/2454.bugfix new file mode 100644 index 0000000000..d60b047f42 --- /dev/null +++ b/news/2454.bugfix @@ -0,0 +1 @@ +Pipenv will now always use ``pathlib2`` for ``Path`` based filesystem interactions by default on ``python<3.5``. diff --git a/pipenv/_compat.py b/pipenv/_compat.py index 68d8069d5e..07e7507228 100644 --- a/pipenv/_compat.py +++ b/pipenv/_compat.py @@ -29,10 +29,13 @@ def _infer_return_type(*args): _types.add(type(arg)) return _types.pop() -try: - from pathlib import Path -except ImportError: - from pathlib2 import Path +if sys.version_info[:2] >= (3, 5): + try: + from pathlib import Path + except ImportError: + from .vendor.pathlib2 import Path +else: + from .vendor.pathlib2 import Path try: diff --git a/pipenv/project.py b/pipenv/project.py index d13f649103..9c8901e8c0 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -14,10 +14,7 @@ import toml import json as simplejson -try: - from pathlib import Path -except ImportError: - from pathlib2 import Path +from ._compat import Path from .cmdparse import Script from .vendor.requirementslib import Requirement diff --git a/pipenv/utils.py b/pipenv/utils.py index a19f7ed0f6..12cd8283f7 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -36,13 +36,7 @@ def detach(self): from urllib.parse import urlparse except ImportError: from urlparse import urlparse -try: - from pathlib import Path -except ImportError: - try: - from .vendor.pathlib2 import Path - except ImportError: - pass + from distutils.spawn import find_executable from contextlib import contextmanager from .pep508checker import lookup @@ -231,7 +225,7 @@ def actually_resolve_deps( from pipenv.patched.piptools.scripts.compile import get_pip_command from pipenv.patched.piptools import logging as piptools_logging from pipenv.patched.piptools.exceptions import NoCandidateFound - from ._compat import TemporaryDirectory, NamedTemporaryFile + from ._compat import TemporaryDirectory, NamedTemporaryFile, Path class PipCommand(basecommand.Command): """Needed for pip-tools.""" From 39a363b780308fb83644fdecbb406fa34c8fc9a2 Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Wed, 27 Jun 2018 22:28:31 -0400 Subject: [PATCH 2/3] Update references to `Path` Signed-off-by: Dan Ryan --- tests/integration/conftest.py | 8 +------- tests/integration/test_install_basic.py | 6 +----- tests/integration/test_install_twists.py | 7 ++----- tests/integration/test_install_uri.py | 5 +---- tests/integration/test_pipenv.py | 8 ++------ tests/integration/test_windows.py | 6 +++--- 6 files changed, 10 insertions(+), 30 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 6141eeac2f..d71f0f89eb 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -4,18 +4,12 @@ import pytest -from pipenv._compat import TemporaryDirectory +from pipenv._compat import TemporaryDirectory, Path from pipenv.vendor import delegator from pipenv.vendor import requests from pipenv.vendor import six from pipenv.vendor import toml -try: - from pathlib import Path -except ImportError: - from pipenv.vendor.pathlib2 import Path - - if six.PY2: class ResourceWarning(Warning): pass diff --git a/tests/integration/test_install_basic.py b/tests/integration/test_install_basic.py index 71e3ed5d1d..d4e967d4d1 100644 --- a/tests/integration/test_install_basic.py +++ b/tests/integration/test_install_basic.py @@ -2,13 +2,9 @@ import os from pipenv.utils import temp_environ -from pipenv._compat import TemporaryDirectory +from pipenv._compat import TemporaryDirectory, Path from pipenv.vendor import delegator from pipenv.project import Project -try: - from pathlib import Path -except ImportError: - from pipenv.vendor.pathlib2 import Path import pytest diff --git a/tests/integration/test_install_twists.py b/tests/integration/test_install_twists.py index 8750d46342..95d67dafe2 100644 --- a/tests/integration/test_install_twists.py +++ b/tests/integration/test_install_twists.py @@ -1,10 +1,7 @@ import os import shutil from pipenv.project import Project -try: - import pathlib -except ImportError: - import pathlib2 as pathlib +from pipenv._compat import Path from pipenv.utils import mkdir_p, temp_environ @@ -223,7 +220,7 @@ def test_relative_paths(PipenvInstance, pypi, testsroot): dep = p.pipfile['packages'][key] assert 'path' in dep - assert pathlib.Path('.', artifact_dir, file_name) == pathlib.Path(dep['path']) + assert Path('.', artifact_dir, file_name) == Path(dep['path']) assert c.return_code == 0 diff --git a/tests/integration/test_install_uri.py b/tests/integration/test_install_uri.py index 709ba8eb04..df2d44d839 100644 --- a/tests/integration/test_install_uri.py +++ b/tests/integration/test_install_uri.py @@ -2,10 +2,7 @@ import os from flaky import flaky import delegator -try: - from pathlib import Path -except ImportError: - from pathlib2 import Path +from pipenv._compat import Path @pytest.mark.vcs diff --git a/tests/integration/test_pipenv.py b/tests/integration/test_pipenv.py index 7077d6e7e6..89ee793ebb 100644 --- a/tests/integration/test_pipenv.py +++ b/tests/integration/test_pipenv.py @@ -11,11 +11,7 @@ from pipenv.core import activate_virtualenv from pipenv.project import Project from pipenv.vendor import delegator - -try: - from pathlib import Path -except ImportError: - from pipenv.vendor.pathlib2 import Path +from pipenv._compat import Path @pytest.mark.code @@ -123,4 +119,4 @@ def mocked_mkdtemp(suffix, prefix, dir): assert os.path.isdir(venv_path) # Manually clean up environment, since PipenvInstance assumes that # the virutalenv is in the project directory. - p.pipenv('--rm') \ No newline at end of file + p.pipenv('--rm') diff --git a/tests/integration/test_windows.py b/tests/integration/test_windows.py index 91b4f99578..bd6eaf1911 100644 --- a/tests/integration/test_windows.py +++ b/tests/integration/test_windows.py @@ -1,7 +1,7 @@ import os from pipenv.project import Project -from pipenv.vendor import pathlib2 as pathlib +from pipenv._compat import Path import pytest @@ -33,7 +33,7 @@ def test_case_changes_windows(PipenvInstance, pypi): @pytest.mark.files def test_local_path_windows(PipenvInstance, pypi): whl = ( - pathlib.Path(__file__).parent.parent + Path(__file__).parent.parent .joinpath('pypi', 'six', 'six-1.11.0-py2.py3-none-any.whl') ) try: @@ -48,7 +48,7 @@ def test_local_path_windows(PipenvInstance, pypi): @pytest.mark.files def test_local_path_windows_forward_slash(PipenvInstance, pypi): whl = ( - pathlib.Path(__file__).parent.parent + Path(__file__).parent.parent .joinpath('pypi', 'six', 'six-1.11.0-py2.py3-none-any.whl') ) try: From 7a014feb0d49d6ff8e27c84dc280053709a573c0 Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Wed, 27 Jun 2018 22:36:26 -0400 Subject: [PATCH 3/3] Fix utils Signed-off-by: Dan Ryan --- pipenv/utils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 12cd8283f7..2068a227b4 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -14,7 +14,6 @@ from click import echo as click_echo from first import first - try: from weakref import finalize except ImportError: @@ -225,7 +224,7 @@ def actually_resolve_deps( from pipenv.patched.piptools.scripts.compile import get_pip_command from pipenv.patched.piptools import logging as piptools_logging from pipenv.patched.piptools.exceptions import NoCandidateFound - from ._compat import TemporaryDirectory, NamedTemporaryFile, Path + from ._compat import TemporaryDirectory, NamedTemporaryFile class PipCommand(basecommand.Command): """Needed for pip-tools.""" @@ -603,6 +602,7 @@ def is_installable_file(path): from .patched.notpip._internal.utils.misc import is_installable_dir from .patched.notpip._internal.utils.packaging import specifiers from .patched.notpip._internal.download import is_archive_file + from ._compat import Path if hasattr(path, 'keys') and any( key for key in path.keys() if key in ['file', 'path'] @@ -847,6 +847,7 @@ def find_windows_executable(bin_path, exe_name): def path_to_url(path): + from ._compat import Path return Path(normalize_drive(os.path.abspath(path))).as_uri() @@ -1152,7 +1153,7 @@ def get_vcs_deps( pypi_mirror=None, ): from .patched.notpip._internal.vcs import VcsSupport - from ._compat import TemporaryDirectory + from ._compat import TemporaryDirectory, Path section = "vcs_dev_packages" if dev else "vcs_packages" reqs = []