Repository: pypa/pipenv

Issue:
pipenv doesn't support compatible release version specifier
https://www.python.org/dev/peps/pep-0440/#version-specifiers

```
$ pipenv install --dev 'pytest~=3.2'
Did you mean pytest? [Y/n]: n
Installing pytest~=3.2…
Requirement already satisfied: pytest~=3.2 in /home/ionasal/.local/share/virtualenvs/mir.protology-Didwf7Vs/lib/python3.6/site-packages
Requirement already satisfied: py>=1.4.33 in /home/ionasal/.local/share/virtualenvs/mir.protology-Didwf7Vs/lib/python3.6/site-packages (from pytest~=3.2)
Requirement already satisfied: setuptools in /home/ionasal/.local/share/virtualenvs/mir.protology-Didwf7Vs/lib/python3.6/site-packages (from pytest~=3.2)

Adding pytest~=3.2 to Pipfile's [dev-packages]…
Locking [dev-packages] dependencies…
Traceback (most recent call last):
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/_vendor/packaging/requirements.py", line 92, in __init__
    req = REQUIREMENT.parseString(requirement_string)
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/_vendor/pyparsing.py", line 1617, in parseString
    raise exc
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/_vendor/pyparsing.py", line 1607, in parseString
    loc, tokens = self._parse( instring, 0 )
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/_vendor/pyparsing.py", line 1379, in _parseNoCache
    loc,tokens = self.parseImpl( instring, preloc, doActions )
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/_vendor/pyparsing.py", line 3376, in parseImpl
    loc, exprtokens = e._parse( instring, loc, doActions )
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/_vendor/pyparsing.py", line 1383, in _parseNoCache
    loc,tokens = self.parseImpl( instring, preloc, doActions )
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/_vendor/pyparsing.py", line 3164, in parseImpl
    raise ParseException(instring, loc, self.errmsg, self)
pip._vendor.pyparsing.ParseException: Expected stringEnd (at char 6), (line:1, col:7)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/req/req_install.py", line 81, in __init__
    req = Requirement(req)
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/_vendor/packaging/requirements.py", line 96, in __init__
    requirement_string[e.loc:e.loc + 8]))
pip._vendor.packaging.requirements.InvalidRequirement: Invalid requirement, parse error at "'=3.2'"

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ionasal/.local/bin/pipenv", line 11, in <module>
    sys.exit(cli())
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/vendor/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/cli.py", line 1852, in install
    do_lock(system=system, pre=pre)
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/cli.py", line 1027, in do_lock
    pre=pre
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/utils.py", line 386, in resolve_deps
    constraint = [c for c in pip.req.parse_requirements(t, session=pip._vendor.requests)][0]
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/utils.py", line 386, in <listcomp>
    constraint = [c for c in pip.req.parse_requirements(t, session=pip._vendor.requests)][0]
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/req/req_file.py", line 93, in parse_requirements
    for req in req_iter:
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/req/req_file.py", line 158, in process_line
    isolated=isolated, options=req_options, wheel_cache=wheel_cache
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/req/req_install.py", line 234, in from_line
    wheel_cache=wheel_cache, constraint=constraint)
  File "/home/ionasal/.local/lib/python3.6/site-packages/pipenv/patched/pip/req/req_install.py", line 90, in __init__
    "Invalid requirement: '%s'\n%s" % (req, add_msg))
pip.exceptions.InstallationError: Invalid requirement: 'pytest=3.2'
= is not a valid operator. Did you mean == ?
```


Discussion:
I can't tell at a glance if the bug is in pipenv, pip, or what appears to be pipenv's vendored version of pip.
Manually adding this to Pipfile works; thus the issue seems like is in pipenv's code for inserting this into the Pipefile

```
[dev-packages]
pytest = "~=3.2"
```
Hi @darkfeline!  Thanks for using pipenv, I'm looking into this and will see if we can get a fix in the works!

Resolving patch:
diff --git a/pipenv/cli.py b/pipenv/cli.py
--- a/pipenv/cli.py
+++ b/pipenv/cli.py
@@ -1762,11 +1762,7 @@ def install(
         if package_names[0]:
             if not package_names[0].startswith('-e '):
                 if not is_file(package_names[0]):
-                    if not (
-                        ('==' in package_names[0]) or
-                        ('>=' in package_names[0]) or
-                        ('<=' in package_names[0])
-                    ):
+                    if not any(op in package_names[0] for op in '!=<>~'):
                         suggested_package = suggest_package(package_names[0])
                         if suggested_package:
                             if str(package_names[0].lower()) != str(suggested_package.lower()):
diff --git a/pipenv/utils.py b/pipenv/utils.py
--- a/pipenv/utils.py
+++ b/pipenv/utils.py
@@ -587,7 +587,7 @@ def convert_deps_from_pip(dep):
         specs = None
         # Comparison operators: e.g. Django>1.10
         if req.specs:
-            r = multi_split(dep, '!=<>')
+            r = multi_split(dep, '!=<>~')
             specs = dep[len(r[0]):]
             dependency[req.name] = specs
 


Test patch: