From d83483acbaf858ccfe3d797f3d6455a8683f2b20 Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Mon, 8 Oct 2018 01:04:32 -0400 Subject: [PATCH 1/2] Update requirementslib - fix editable requirements - Fixes #1393 Signed-off-by: Dan Ryan --- news/1393.bugfix | 1 + pipenv/core.py | 10 +++++----- pipenv/utils.py | 6 +++--- pipenv/vendor/requirementslib/__init__.py | 2 +- .../requirementslib/models/requirements.py | 20 ++++++++++++++++--- pipenv/vendor/requirementslib/models/utils.py | 2 +- 6 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 news/1393.bugfix diff --git a/news/1393.bugfix b/news/1393.bugfix new file mode 100644 index 0000000000..3211645a84 --- /dev/null +++ b/news/1393.bugfix @@ -0,0 +1 @@ +Fixed a bug which prevented installation of editable requirements using ``ssh://`` style urls diff --git a/pipenv/core.py b/pipenv/core.py index 3ef6abd36d..b0cd9aa50e 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -661,7 +661,7 @@ def do_install_dependencies( If requirements is True, simply spits out a requirements format to stdout. """ - from .vendor.requirementslib import Requirement + from .vendor.requirementslib.models.requirements import Requirement def cleanup_procs(procs, concurrent): for c in procs: @@ -927,7 +927,7 @@ def parse_download_fname(fname, name): def get_downloads_info(names_map, section): - from .vendor.requirementslib import Requirement + from .vendor.requirementslib.models.requirements import Requirement info = [] p = project.parsed_pipfile @@ -1614,7 +1614,7 @@ def do_py(system=False): def do_outdated(pypi_mirror=None): - from .vendor.requirementslib import Requirement + from .vendor.requirementslib.models.requirements import Requirement packages = {} results = delegator.run("{0} freeze".format(which("pip"))).out.strip().split("\n") @@ -1816,7 +1816,7 @@ def do_install( # We should do this part first to make sure that we actually do selectively upgrade # the items specified if selective_upgrade: - from .vendor.requirementslib import Requirement + from .vendor.requirementslib.models.requirements import Requirement for i, package in enumerate(package_args[:]): section = project.packages if not dev else project.dev_packages @@ -1966,7 +1966,7 @@ def do_uninstall( pypi_mirror=None, ): from .environments import PIPENV_USE_SYSTEM - from .vendor.requirementslib import Requirement + from .vendor.requirementslib.models.requirements import Requirement # Automatically use an activated virtualenv. if PIPENV_USE_SYSTEM: diff --git a/pipenv/utils.py b/pipenv/utils.py index cb5748013f..371a550aba 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -227,7 +227,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 .vendor.requirementslib import Requirement + from .vendor.requirementslib.models.requirements import Requirement from ._compat import TemporaryDirectory, NamedTemporaryFile class PipCommand(basecommand.Command): @@ -524,7 +524,7 @@ def is_pinned(val): def convert_deps_to_pip(deps, project=None, r=True, include_index=True): """"Converts a Pipfile-formatted dependency to a pip-formatted one.""" from ._compat import NamedTemporaryFile - from .vendor.requirementslib import Requirement + from .vendor.requirementslib.models.requirements import Requirement dependencies = [] for dep_name, dep in deps.items(): @@ -1120,7 +1120,7 @@ def get_vcs_deps( ): from ._compat import TemporaryDirectory, Path import atexit - from .vendor.requirementslib import Requirement + from .vendor.requirementslib.models.requirements import Requirement section = "vcs_dev_packages" if dev else "vcs_packages" reqs = [] diff --git a/pipenv/vendor/requirementslib/__init__.py b/pipenv/vendor/requirementslib/__init__.py index ddfbcf98d0..ddb17b6e53 100644 --- a/pipenv/vendor/requirementslib/__init__.py +++ b/pipenv/vendor/requirementslib/__init__.py @@ -1,5 +1,5 @@ # -*- coding=utf-8 -*- -__version__ = '1.1.7' +__version__ = '1.1.9.dev0' from .exceptions import RequirementError diff --git a/pipenv/vendor/requirementslib/models/requirements.py b/pipenv/vendor/requirementslib/models/requirements.py index 73de6d2db5..b7ea4a7e3e 100644 --- a/pipenv/vendor/requirementslib/models/requirements.py +++ b/pipenv/vendor/requirementslib/models/requirements.py @@ -480,6 +480,7 @@ class VCSRequirement(FileRequirement): ref = attr.ib(default=None) subdirectory = attr.ib(default=None) _repo = attr.ib(default=None) + _base_line = attr.ib(default=None) name = attr.ib() link = attr.ib() req = attr.ib() @@ -619,6 +620,13 @@ def locked_vcs_repo(self, src_dir=None): vcsrepo.checkout_ref(self.ref) self.ref = self.get_commit_hash() self.req.revision = self.ref + + # Remove potential ref in the end of uri after ref is parsed + if "@" in self.link.show_url and "@" in self.uri: + uri, ref = self.uri.rsplit("@", 1) + if ref in self.ref: + self.uri = uri + yield vcsrepo self._repo = vcsrepo @@ -681,6 +689,7 @@ def from_line(cls, line, editable=None, extras=None): editable=editable, uri=uri, extras=extras, + base_line=line ) @property @@ -692,8 +701,10 @@ def line_part(self): base_link = self.get_link() final_format = "{{0}}#egg={0}".format(base_link.egg_fragment) if base_link.egg_fragment else "{0}" base = final_format.format(self.vcs_uri) - elif self.req: - base = self.req.line + elif self._base_line: + base = self._base_line + else: + base = self.link.url if base and self.extras and not extras_to_string(self.extras) in base: if self.subdirectory: base = "{0}".format(self.get_link().url) @@ -717,7 +728,9 @@ def _choose_vcs_source(pipfile): @property def pipfile_part(self): - pipfile_dict = attr.asdict(self, filter=lambda k, v: bool(v) is True and k.name != '_repo').copy() + excludes = ["_repo", "_base_line"] + filter_func = lambda k, v: bool(v) is True and k.name not in excludes + pipfile_dict = attr.asdict(self, filter=filter_func).copy() if "vcs" in pipfile_dict: pipfile_dict = self._choose_vcs_source(pipfile_dict) name, _ = _strip_extras(pipfile_dict.pop("name")) @@ -814,6 +827,7 @@ def from_line(cls, line): hashes = line.split(" --hash=") line, hashes = hashes[0], hashes[1:] editable = line.startswith("-e ") + print("Got line: %s" % line) line = line.split(" ", 1)[1] if editable else line line, markers = split_markers_from_line(line) line, extras = _strip_extras(line) diff --git a/pipenv/vendor/requirementslib/models/utils.py b/pipenv/vendor/requirementslib/models/utils.py index de9acb53e6..cba63295ac 100644 --- a/pipenv/vendor/requirementslib/models/utils.py +++ b/pipenv/vendor/requirementslib/models/utils.py @@ -117,7 +117,7 @@ def strip_ssh_from_git_uri(uri): def add_ssh_scheme_to_git_uri(uri): - """Cleans VCS uris from pipenv.patched.notpip format""" + """Cleans VCS uris from pip format""" if isinstance(uri, six.string_types): # Add scheme for parsing purposes, this is also what pip does if uri.startswith("git+") and "://" not in uri: From f1769e186b7c8d5a36e94fa5ab0ef976819e7740 Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Mon, 8 Oct 2018 01:13:14 -0400 Subject: [PATCH 2/2] Remove debug line --- pipenv/vendor/requirementslib/models/requirements.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pipenv/vendor/requirementslib/models/requirements.py b/pipenv/vendor/requirementslib/models/requirements.py index b7ea4a7e3e..cc8e683113 100644 --- a/pipenv/vendor/requirementslib/models/requirements.py +++ b/pipenv/vendor/requirementslib/models/requirements.py @@ -827,7 +827,6 @@ def from_line(cls, line): hashes = line.split(" --hash=") line, hashes = hashes[0], hashes[1:] editable = line.startswith("-e ") - print("Got line: %s" % line) line = line.split(" ", 1)[1] if editable else line line, markers = split_markers_from_line(line) line, extras = _strip_extras(line)