Repository: pypa/pipenv

Issue:
pipenv 2020.4.1b1: Invalid fragment string
I installed pipenv 2020.4.1b1 on my local machine by running:

    pip install --upgrade --pre pipenv

Then I updated my dependencies on my local machine by running:

    pipenv update

The Pipfile.lock got updated of course. Here is the relevant diff in Pipfile.lock:

```diff
         "robohash": {
             "git": "https://github.com/e1ven/Robohash.git",
-            "ref": "03ade66998c15735740ec4111b5da8d4383a7577"
+            "ref": "03ade66998c15735740ec4111b5da8d4383a7577",
+            "version": "==1.0"
         },

```

As you can see, this dependency is installed from GitHub, not from PyPI. Using the newer pipenv caused a new key-value to be added, which is `"version": "==1.0"`.

I committed these changes and launched them to a server. The server has Pipenv 2018.5.18 installed. When the server tried to install the dependencies from this Pipfile.lock, I got this error:

```
remote:        WARNING: Invalid fragment string egg=robohash==1.0
remote:        ABORTING INSTALL... You will have to reinstall any packages that failed to install.
remote:        You may have to manually run pipenv lock when you are finished.
```

It looks like the new key-value pair `version` is incompatible with pipenv 2018.5.18, when it applies to packages installed from a Git repo. Is that correct? Is it meant to be that way? If it is, it would be useful to include this compatibility notice in the change log. If not, then maybe the `version` key-value shouldn't be included in packages that are installed from a Git repo.


Discussion:
Thanks for filing this and for testing out the prerelease, and sorry for the issue :| It definitely is not the intention to cause a backwards compatibility problem here so we will definitely need to get a fix committed for this ASAP
Of course. No need to apologise, I installed a pre-release version fully expecting that there might be bugs :)

Resolving patch:
diff --git a/pipenv/patched/piptools/utils.py b/pipenv/patched/piptools/utils.py
--- a/pipenv/patched/piptools/utils.py
+++ b/pipenv/patched/piptools/utils.py
@@ -181,6 +181,8 @@ def format_requirement(ireq, marker=None, hashes=None):
     """
     if ireq.editable:
         line = "-e {}".format(ireq.link.url)
+    elif ireq.link and ireq.link.is_vcs:
+        line = str(ireq.req)
     elif is_url_requirement(ireq):
         line = ireq.link.url
     else:
diff --git a/pipenv/utils.py b/pipenv/utils.py
--- a/pipenv/utils.py
+++ b/pipenv/utils.py
@@ -741,6 +741,10 @@ def pip_options(self):
         if self._pip_options is None:
             pip_options, _ = self.pip_command.parser.parse_args(self.pip_args)
             pip_options.cache_dir = environments.PIPENV_CACHE_DIR
+            pip_options.no_python_version_warning = True
+            pip_options.no_input = True
+            pip_options.progress_bar = "off"
+            pip_options.ignore_requires_python = True
             self._pip_options = pip_options
         return self._pip_options
 
@@ -1047,13 +1051,17 @@ def format_requirement_for_lockfile(req, markers_lookup, index_lookup, hashes=No
     if hashes:
         entry["hashes"] = sorted(set(hashes))
     entry["name"] = name
-    if index:  # and index != next(iter(project.sources), {}).get("name"):
+    if index:
         entry.update({"index": index})
     if markers:
         entry.update({"markers": markers})
     entry = translate_markers(entry)
-    if req.vcs or req.editable and entry.get("index"):
-        del entry["index"]
+    if req.vcs or req.editable:
+        for key in ("index", "version"):
+            try:
+                del entry[key]
+            except KeyError:
+                pass
     return name, entry
 
 


Test patch:
diff --git a/tests/integration/test_lock.py b/tests/integration/test_lock.py
--- a/tests/integration/test_lock.py
+++ b/tests/integration/test_lock.py
@@ -494,6 +494,9 @@ def test_lock_editable_vcs_with_extras_without_install(PipenvInstance):
         assert "socks" in p.lockfile["default"]["requests"]["extras"]
         c = p.pipenv('install')
         assert c.return_code == 0
+        assert "requests" in p.lockfile["default"]
+        # For backward compatibility we want to make sure not to include the 'version' key
+        assert "version" not in p.lockfile["default"]["requests"]
 
 
 @pytest.mark.vcs
@@ -658,4 +661,19 @@ def test_lock_after_update_source_name(PipenvInstance):
         c = p.pipenv("lock --clear")
         assert c.return_code == 0
         assert "index" in p.lockfile["default"]["six"]
-        assert p.lockfile["default"]["six"]["index"] == "custom", Path(p.lockfile_path).read_text()  # p.lockfile["default"]["six"]
+        assert p.lockfile["default"]["six"]["index"] == "custom", Path(p.lockfile_path).read_text()
+
+
+@pytest.mark.lock
+def test_lock_nested_direct_url(PipenvInstance):
+    """
+    The dependency 'test_package' has a declared dependency on
+    a PEP508 style VCS URL. This ensures that we capture the dependency
+    here along with its own dependencies.
+    """
+    with PipenvInstance(chdir=True) as p:
+        c = p.pipenv("install test_package")
+        assert c.return_code == 0
+        assert "vistir" in p.lockfile["default"]
+        assert "colorama" in p.lockfile["default"]
+        assert "six" in p.lockfile["default"]
diff --git a/tests/pypi b/tests/pypi
--- a/tests/pypi
+++ b/tests/pypi
@@ -1 +1 @@
-Subproject commit 6faddf97c2a0220870da0a1409a196667b06c9cc
+Subproject commit 59882cf2000f36a6644a883430df9dfeb35d2106