Repository: pypa/pipenv

Issue:
Trailing comments cause parse error in `pipenv install -r requirements.txt`
Running `pipenv install -r requirements.txt` on a file with trailing comments (such as those generated by `pip-compile`) gives the following error:

```
$ pipenv install -r requirements.txt
Installing amqp==2.1.4               # via kombu...

Error:  An error occured while installing amqp==2.1.4               # via kombu
Invalid requirement: 'amqp==2.1.4               # via kombu'
Traceback (most recent call last):
  File "/Users/paul/qwil/backend/.venv/lib/python3.4/site-packages/pip/_vendor/packaging/requirements.py", line 92, in __init__
    req = REQUIREMENT.parseString(requirement_string)
  File "/Users/paul/qwil/backend/.venv/lib/python3.4/site-packages/pip/_vendor/pyparsing.py", line 1617, in parseString
    raise exc
  File "/Users/paul/qwil/backend/.venv/lib/python3.4/site-packages/pip/_vendor/pyparsing.py", line 1607, in parseString
    loc, tokens = self._parse( instring, 0 )
  File "/Users/paul/qwil/backend/.venv/lib/python3.4/site-packages/pip/_vendor/pyparsing.py", line 1379, in _parseNoCache
    loc,tokens = self.parseImpl( instring, preloc, doActions )
  File "/Users/paul/qwil/backend/.venv/lib/python3.4/site-packages/pip/_vendor/pyparsing.py", line 3376, in parseImpl
    loc, exprtokens = e._parse( instring, loc, doActions )
  File "/Users/paul/qwil/backend/.venv/lib/python3.4/site-packages/pip/_vendor/pyparsing.py", line 1383, in _parseNoCache
    loc,tokens = self.parseImpl( instring, preloc, doActions )
  File "/Users/paul/qwil/backend/.venv/lib/python3.4/site-packages/pip/_vendor/pyparsing.py", line 3164, in parseImpl
    raise ParseException(instring, loc, self.errmsg, self)
pip._vendor.pyparsing.ParseException: Expected stringEnd (at char 26), (line:1, col:27)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/paul/qwil/backend/.venv/lib/python3.4/site-packages/pip/req/req_install.py", line 82, in __init__
    req = Requirement(req)
  File "/Users/paul/qwil/backend/.venv/lib/python3.4/site-packages/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 "'# via ko'"
```

Looks like the requirements parser is just skipping lines which `startwith('#')` but looks like we need to be a bit more cunning to pluck out trailing comments.


Discussion:
open to a PR! Should be an easy fix. 
Related: #25 

Resolving patch:
diff --git a/pipenv/cli.py b/pipenv/cli.py
--- a/pipenv/cli.py
+++ b/pipenv/cli.py
@@ -330,7 +330,7 @@ def cli(ctx, where=False, bare=False, three=False):
 @click.argument('package_name', default=False)
 @click.argument('more_packages', nargs=-1)
 @click.option('--dev','-d', is_flag=True, default=False, help="Install package(s) in [dev-packages].")
-@click.option('-r', type=click.File('rb'), default=None, help="Use requirements.txt file.")
+@click.option('-r', type=click.File('r'), default=None, help="Use requirements.txt file.")
 @click.option('--system', is_flag=True, default=False, help="System pip management.")
 def install(package_name=False, more_packages=False, r=False, dev=False, system=False):
 


Test patch:
diff --git a/test_pipenv.py b/test_pipenv.py
--- a/test_pipenv.py
+++ b/test_pipenv.py
@@ -1,5 +1,6 @@
 import pytest
 
+from pipenv.cli import from_requirements_file
 import pipenv.utils
 
 
@@ -58,3 +59,19 @@ def test_convert_from_pip():
     assert dep == {u'MyProject': {u'svn': u'svn://svn.myproject.org/svn/MyProject', 'editable': True}}
 
 
+def test_install_from_requirements_file():
+
+    # requests
+    r = open('tests/requirements_requests.txt')
+    dep = from_requirements_file(r)
+    assert dep == ['requests']
+
+    # Django>1.10
+    r = open('tests/requirements_django.txt')
+    dep = from_requirements_file(r)
+    assert dep == ['Django>1.10']
+
+    # requests[sock]
+    r = open('tests/requirements_requests_socks.txt')
+    dep = from_requirements_file(r)
+    assert dep == ['requests[socks]']
diff --git a/tests/requirements_django.txt b/tests/requirements_django.txt
new file mode 100644
--- /dev/null
+++ b/tests/requirements_django.txt
@@ -0,0 +1 @@
+Django>1.10
diff --git a/tests/requirements_requests.txt b/tests/requirements_requests.txt
new file mode 100644
--- /dev/null
+++ b/tests/requirements_requests.txt
@@ -0,0 +1 @@
+requests
diff --git a/tests/requirements_requests_socks.txt b/tests/requirements_requests_socks.txt
new file mode 100644
--- /dev/null
+++ b/tests/requirements_requests_socks.txt
@@ -0,0 +1 @@
+requests[socks]