Repository: pypa/pip

Issue:
"pip freeze -r" returns ValueError() if requirements file contains --find-links
It seems that pip freeze should not pass --find-links or --index-url to distribute/setuptools when inlined in a requirements file. Here is an easy way to repro the problem:

1) echo "--find-links http://foo.bar/" > /tmp/req.txt
2) pip freeze -r /tmp/req.txt

"""
Exception:
Traceback (most recent call last):
  File "/Users/hpfennig/work/pip/pip/basecommand.py", line 95, in main
    self.run(options, args)
  File "/Users/hpfennig/work/pip/pip/commands/freeze.py", line 92, in run
    line_req = InstallRequirement.from_line(line)
  File "/Users/hpfennig/work/pip/pip/req.py", line 105, in from_line
    return cls(req, comes_from, url=url)
  File "/Users/hpfennig/work/pip/pip/req.py", line 39, in **init**
    req = pkg_resources.Requirement.parse(req)
  File "/Users/hpfennig/.virtualenvs/pip-bug-virt-env/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 2510, in parse
    reqs = list(parse_requirements(s))
  File "/Users/hpfennig/.virtualenvs/pip-bug-virt-env/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 2436, in parse_requirements
    line, p, specs = scan_list(VERSION,LINE_END,line,p,(1,2),"version spec")
  File "/Users/hpfennig/.virtualenvs/pip-bug-virt-env/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 2404, in scan_list
    raise ValueError("Expected "+item_name+" in",line,"at",line[p:])
ValueError: ('Expected version spec in', '--find-links http://foo.bar/', 'at', ' http://foo.bar/')

Storing complete log in /Users/hpfennig/.pip/pip.log
"""

I have a fix, but I am not sure this is the correct way to go about it. Would be happy to do an official pull request if needed.

diff --git a/pip/commands/freeze.py b/pip/commands/freeze.py
index 01b5df9..03ac80f 100644
--- a/pip/commands/freeze.py
+++ b/pip/commands/freeze.py
@@ -85,7 +85,9 @@ class FreezeCommand(Command):
                 elif (line.startswith('-r') or line.startswith('--requirement')
                       or line.startswith('-Z') or line.startswith('--always-unzip')
                       or line.startswith('-f') or line.startswith('-i')
-                      or line.startswith('--extra-index-url')):
-                      or line.startswith('--extra-index-url')
-                      or line.startswith('--find-links')
-                      or line.startswith('--index-url')):
                   f.write(line)
                   continue
               else:



Discussion:
Yep, that fix looks correct - thanks for the report! A pull request (with a test; should be easy to follow other examples in test_freeze.py) would be great - otherwise I'll get to it when I can.


Resolving patch:
diff --git a/pip/commands/freeze.py b/pip/commands/freeze.py
--- a/pip/commands/freeze.py
+++ b/pip/commands/freeze.py
@@ -85,7 +85,9 @@ def run(self, options, args):
                 elif (line.startswith('-r') or line.startswith('--requirement')
                       or line.startswith('-Z') or line.startswith('--always-unzip')
                       or line.startswith('-f') or line.startswith('-i')
-                      or line.startswith('--extra-index-url')):
+                      or line.startswith('--extra-index-url')
+                      or line.startswith('--find-links')
+                      or line.startswith('--index-url')):
                     f.write(line)
                     continue
                 else:


Test patch:
diff --git a/tests/test_freeze.py b/tests/test_freeze.py
--- a/tests/test_freeze.py
+++ b/tests/test_freeze.py
@@ -203,3 +203,38 @@ def test_freeze_with_local_option():
         INITools==0.2
         <BLANKLINE>""")
     _check_output(result, expected)
+
+def test_freeze_with_requirement_option():
+    """
+    Test that new requirements are created correctly with --requirement hints
+
+    """
+    reset_env()
+    ignores = textwrap.dedent("""\
+        # Unchanged requirements below this line
+        -r ignore.txt
+        --requirement ignore.txt
+        -Z ignore
+        --always-unzip ignore
+        -f http://ignore
+        -i http://ignore
+        --extra-index-url http://ignore
+        --find-links http://ignore
+        --index-url http://ignore
+        """)
+    write_file('hint.txt', textwrap.dedent("""\
+        INITools==0.1
+        NoExist==4.2
+        """) + ignores)
+    result = run_pip('install', 'initools==0.2')
+    result = run_pip('install', 'MarkupSafe')
+    result = run_pip('freeze', '--requirement', 'hint.txt', expect_stderr=True)
+    expected = textwrap.dedent("""\
+        Script result: pip freeze --requirement hint.txt
+        -- stderr: --------------------
+        Requirement file contains NoExist==4.2, but that package is not installed
+
+        -- stdout: --------------------
+        INITools==0.2
+        """) + ignores + "## The following requirements were added by pip --freeze:..."
+    _check_output(result, expected)