Repository: pypa/pipenv

Issue:
pip-tools stack trace if VCS doesn't include -e
```sql
$ pipenv install 'git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa'
Courtesy Notice: Pipenv found itself running within a virtual environment, so it will automatically use that environment, instead of creating its own for any project.
Installing git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa…
Collecting django-medusa from git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa
  Cloning http://github.com/alsoicode/django-medusa.git (to v0.3.2) to /private/var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pip-build-mtemz9re/django-medusa
Requirement already satisfied: django in /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python3.6/site-packages (from django-medusa)
Requirement already satisfied: pytz in /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python3.6/site-packages (from django->django-medusa)
Installing collected packages: django-medusa
  Running setup.py install for django-medusa: started
    Running setup.py install for django-medusa: finished with status 'done'
Successfully installed django-medusa-0.3.2

Adding git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa to Pipfile's [packages]…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Traceback (most recent call last):
  File "/Users/christian/.pyenv/versions/3.6.2/bin/pipenv", line 11, in <module>
    load_entry_point('pipenv==8.2.6', 'console_scripts', 'pipenv')()
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/cli.py", line 1852, in install
    do_lock(system=system, pre=pre)
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/cli.py", line 1083, in do_lock
    pre=pre
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/utils.py", line 421, in resolve_deps
    resolved_tree.update(resolver.resolve(max_rounds=PIPENV_MAX_ROUNDS))
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/patched/piptools/resolver.py", line 88, in resolve
    self.their_constraints))
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/patched/piptools/resolver.py", line 125, in check_constraints
    raise UnsupportedConstraint(msg, constraint)
piptools.exceptions.UnsupportedConstraint: pip-compile does not support URLs as packages, unless they are editable. Perhaps add -e option? (constraint was: django-medusa from git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa (from -r /var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pipenv-ttscode_-requirement.txt (line 1)))
```

pipenv should probably display this as a nicely formatted error message rather than a pip-tools stack trace


Discussion:
It is supposed to.  Can you please provide `pipenv --version` and the output of your installation command with the `--verbose` flag
```shell
$ pipenv --version
pipenv, version 8.2.6

$ pipenv install --verbose "git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa"
Courtesy Notice: Pipenv found itself running within a virtual environment, so it will automatically use that environment, instead of creating its own for any project.
Installing git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa…
⠋Installing 'git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa'
$ "/Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/bin/pip" install   --verbose   "git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa" -i https://pypi.python.org/simple --exists-action w                                                                                                                           Collecting django-medusa from git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa
  Cloning http://github.com/alsoicode/django-medusa.git (to v0.3.2) to /private/var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pip-build-p0V3b2/django-medusa
  Running command git clone -q http://github.com/alsoicode/django-medusa.git /private/var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pip-build-p0V3b2/django-medusa
  Running command git show-ref
  2b777e916f30a92ee00277e6c8350823ab4fe5fc refs/heads/master
  2b777e916f30a92ee00277e6c8350823ab4fe5fc refs/remotes/origin/HEAD
  2b777e916f30a92ee00277e6c8350823ab4fe5fc refs/remotes/origin/master
  b1b3edf1ba49a24b9deda5cab208b3598952a1da refs/tags/v0.2.0
  68f785820da860f081edace52c00b29c2cbe6c93 refs/tags/v0.3.0
  5ebd24cd41c96ff747f0c0b0156a689504a4c0ed refs/tags/v0.3.1
  1daafbc3b79c0db677b436c82c3941c19ec4b630 refs/tags/v0.3.2
  Running command git rev-parse HEAD
  2b777e916f30a92ee00277e6c8350823ab4fe5fc
  Running command git checkout -q 1daafbc3b79c0db677b436c82c3941c19ec4b630
  Running setup.py (path:/private/var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pip-build-p0V3b2/django-medusa/setup.py) egg_info for package django-medusa
    Running command python setup.py egg_info
    running egg_info
    creating pip-egg-info/django_medusa.egg-info
    writing requirements to pip-egg-info/django_medusa.egg-info/requires.txt
    writing pip-egg-info/django_medusa.egg-info/PKG-INFO
    writing top-level names to pip-egg-info/django_medusa.egg-info/top_level.txt
    writing dependency_links to pip-egg-info/django_medusa.egg-info/dependency_links.txt
    writing manifest file 'pip-egg-info/django_medusa.egg-info/SOURCES.txt'
    reading manifest file 'pip-egg-info/django_medusa.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    writing manifest file 'pip-egg-info/django_medusa.egg-info/SOURCES.txt'
  Source in /private/var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pip-build-p0V3b2/django-medusa has version 0.3.2, which satisfies requirement django-medusa from git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa
Requirement already satisfied: django in /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages (from django-medusa)
Requirement already satisfied: pytz in /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages (from django->django-medusa)
Installing collected packages: django-medusa
  Running setup.py install for django-medusa: started
    Running command /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/bin/python2.7 -u -c "import setuptools, tokenize;__file__='/private/var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pip-build-p0V3b2/django-medusa/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pip-quxxSB-record/install-record.txt --single-version-externally-managed --compile --install-headers /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/include/site/python2.7/django-medusa
    running install
    running build
    running build_py
    creating build
    creating build/lib
    creating build/lib/django_medusa
    copying django_medusa/__init__.py -> build/lib/django_medusa
    copying django_medusa/utils.py -> build/lib/django_medusa
    copying django_medusa/settings.py -> build/lib/django_medusa
    creating build/lib/django_medusa/renderers
    copying django_medusa/renderers/disk.py -> build/lib/django_medusa/renderers
    copying django_medusa/renderers/__init__.py -> build/lib/django_medusa/renderers
    copying django_medusa/renderers/s3.py -> build/lib/django_medusa/renderers
    copying django_medusa/renderers/appengine.py -> build/lib/django_medusa/renderers
    copying django_medusa/renderers/base.py -> build/lib/django_medusa/renderers
    creating build/lib/django_medusa/management
    copying django_medusa/management/__init__.py -> build/lib/django_medusa/management
    creating build/lib/django_medusa/management/commands
    copying django_medusa/management/commands/__init__.py -> build/lib/django_medusa/management/commands
    copying django_medusa/management/commands/staticsitegen.py -> build/lib/django_medusa/management/commands
    running egg_info
    creating django_medusa.egg-info
    writing requirements to django_medusa.egg-info/requires.txt
    writing django_medusa.egg-info/PKG-INFO
    writing top-level names to django_medusa.egg-info/top_level.txt
    writing dependency_links to django_medusa.egg-info/dependency_links.txt
    writing manifest file 'django_medusa.egg-info/SOURCES.txt'
    reading manifest file 'django_medusa.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    writing manifest file 'django_medusa.egg-info/SOURCES.txt'
    running install_lib
    creating /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa
    creating /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers
    copying build/lib/django_medusa/renderers/disk.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers
    copying build/lib/django_medusa/renderers/__init__.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers
    copying build/lib/django_medusa/renderers/s3.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers
    copying build/lib/django_medusa/renderers/appengine.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers
    copying build/lib/django_medusa/renderers/base.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers
    creating /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/management
    copying build/lib/django_medusa/management/__init__.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/management
    creating /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/management/commands
    copying build/lib/django_medusa/management/commands/__init__.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/management/commands
    copying build/lib/django_medusa/management/commands/staticsitegen.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/management/commands
    copying build/lib/django_medusa/__init__.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa
    copying build/lib/django_medusa/utils.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa
    copying build/lib/django_medusa/settings.py -> /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers/disk.py to disk.pyc
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers/__init__.py to __init__.pyc
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers/s3.py to s3.pyc
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers/appengine.py to appengine.pyc
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/renderers/base.py to base.pyc
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/management/__init__.py to __init__.pyc
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/management/commands/__init__.py to __init__.pyc
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/management/commands/staticsitegen.py to staticsitegen.pyc
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/__init__.py to __init__.pyc
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/utils.py to utils.pyc
    byte-compiling /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa/settings.py to settings.pyc
    running install_egg_info
    Copying django_medusa.egg-info to /Users/christian/.virtualenvs/hnhiring-HX-OrkMQ/lib/python2.7/site-packages/django_medusa-0.3.2-py2.7.egg-info
    running install_scripts
    writing list of installed files to '/var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pip-quxxSB-record/install-record.txt'
    Running setup.py install for django-medusa: finished with status 'done'
  Removing source in /private/var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pip-build-p0V3b2/django-medusa
Successfully installed django-medusa-0.3.2
Cleaning up...

Adding git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa to Pipfile's [packages]…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Traceback (most recent call last):
  File "/Users/christian/.pyenv/versions/3.6.2/bin/pipenv", line 11, in <module>
    load_entry_point('pipenv==8.2.6', 'console_scripts', 'pipenv')()
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/cli.py", line 1852, in install
    do_lock(system=system, pre=pre)
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/cli.py", line 1083, in do_lock
    pre=pre
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/utils.py", line 421, in resolve_deps
    resolved_tree.update(resolver.resolve(max_rounds=PIPENV_MAX_ROUNDS))
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/patched/piptools/resolver.py", line 88, in resolve
    self.their_constraints))
  File "/Users/christian/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pipenv/patched/piptools/resolver.py", line 125, in check_constraints
    raise UnsupportedConstraint(msg, constraint)
piptools.exceptions.UnsupportedConstraint: pip-compile does not support URLs as packages, unless they are editable. Perhaps add -e option? (constraint was: django-medusa from git+http://github.com/alsoicode/django-medusa.git@v0.3.2#egg=django-medusa (from -r /var/folders/b4/4mq3zd1x5ds1wbzd00z0xpmm0000gn/T/pipenv-46xpsm16-requirement.txt (line 1)))

```

Resolving patch:
diff --git a/pipenv/cli.py b/pipenv/cli.py
--- a/pipenv/cli.py
+++ b/pipenv/cli.py
@@ -1800,7 +1800,7 @@ def install(
             # Warn if --editable wasn't passed.
             converted = convert_deps_from_pip(package_name)
             key = [k for k in converted.keys()][0]
-            if is_vcs(converted[key]) and not converted[key].get('editable'):
+            if is_vcs(key) or is_vcs(converted[key]) and not converted[key].get('editable'):
                 click.echo(
                     '{0}: You installed a VCS dependency in non–editable mode. '
                     'This will work fine, but sub-depdendencies will not be resolved by {1}.'
diff --git a/pipenv/project.py b/pipenv/project.py
--- a/pipenv/project.py
+++ b/pipenv/project.py
@@ -51,6 +51,26 @@ def path_to(self, p):
 
         return os.sep.join([self._original_dir, p])
 
+    def _build_package_list(self, package_section):
+        """Returns a list of packages for pip-tools to consume."""
+        ps = {}
+        for k, v in self.parsed_pipfile.get(package_section, {}).items():
+            # Skip editable VCS deps.
+            if hasattr(v, 'keys'):
+                # When a vcs url is gven without editable it only appears as a key
+                if is_vcs(v) or is_vcs(k):
+                    if 'editable' not in v:
+                        continue
+                    else:
+                        ps.update({k: v})
+                else:
+                    if 'file' not in v and not is_vcs(v) and not is_vcs(k):
+                        ps.update({k: v})
+            else:
+                if not is_vcs(k):
+                    ps.update({k: v})
+        return ps
+
     @property
     def name(self):
         if self._name is None:
@@ -301,7 +321,7 @@ def vcs_packages(self):
         """Returns a list of VCS packages, for not pip-tools to consume."""
         ps = {}
         for k, v in self.parsed_pipfile.get('packages', {}).items():
-            if is_vcs(v):
+            if is_vcs(v) or is_vcs(k):
                 ps.update({k: v})
         return ps
 
@@ -310,7 +330,7 @@ def vcs_dev_packages(self):
         """Returns a list of VCS packages, for not pip-tools to consume."""
         ps = {}
         for k, v in self.parsed_pipfile.get('dev-packages', {}).items():
-            if is_vcs(v):
+            if is_vcs(v) or is_vcs(k):
                 ps.update({k: v})
         return ps
 
@@ -324,40 +344,12 @@ def all_packages(self):
     @property
     def packages(self):
         """Returns a list of packages, for pip-tools to consume."""
-        ps = {}
-        for k, v in self.parsed_pipfile.get('packages', {}).items():
-            # Skip editable VCS deps.
-            if hasattr(v, 'keys'):
-                if is_vcs(v):
-                    if 'editable' not in v:
-                        continue
-                    else:
-                        ps.update({k: v})
-                else:
-                    if 'file' not in v:
-                        ps.update({k: v})
-            else:
-                ps.update({k: v})
-        return ps
+        return self._build_package_list('packages')
 
     @property
     def dev_packages(self):
         """Returns a list of dev-packages, for pip-tools to consume."""
-        ps = {}
-        for k, v in self.parsed_pipfile.get('dev-packages', {}).items():
-            # Skip editable VCS deps.
-            if hasattr(v, 'keys'):
-                if is_vcs(v):
-                    if 'editable' not in v:
-                        continue
-                    else:
-                        ps.update({k: v})
-                else:
-                    if 'file' not in v:
-                        ps.update({k: v})
-            else:
-                ps.update({k: v})
-        return ps
+        return self._build_package_list('dev-packages')
 
     def touch_pipfile(self):
         """Simply touches the Pipfile, for later use."""
diff --git a/pipenv/utils.py b/pipenv/utils.py
--- a/pipenv/utils.py
+++ b/pipenv/utils.py
@@ -714,6 +714,8 @@ def is_vcs(pipfile_entry):
 
     if hasattr(pipfile_entry, 'keys'):
         return any(key for key in pipfile_entry.keys() if key in VCS_LIST)
+    elif isinstance(pipfile_entry, six.string_types):
+        return pipfile_entry.startswith(VCS_LIST)
     return False
 
 


Test patch: