Repository: jazzband/pip-tools

Issue:
Update a specific package does not work.
Update a specific package  --upgrade-package or -P flag does not work.

##### Environment Versions

1. MacOS Sierra
2. Python version: 3.5.3
3. pip version:  9.0.1
4. pip-tools version: 1.8.0

##### Steps to replicate

1. 
_req.in_
 ```
jinja2
markupsafe
werkzeug
```

_req.txt_
```
#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile --output-file requirements/req.txt requirements/req.in
#
jinja2==2.7.3
markupsafe==0.23
werkzeug==0.6
```
2. Trying to update only jinja2: `pip-compile -P jinja2 requirements/req.in`

##### Expected result
_req.txt_
```
#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile --output-file requirements/req.txt requirements/req.in
#
jinja2==2.9.5
markupsafe==0.23
werkzeug==0.6
```
##### Actual result
_req.txt_
```
#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile --output-file requirements/req.txt requirements/req.in
#
jinja2==2.9.5
markupsafe==0.23
werkzeug==0.11.15
```
As you can see, werkzeug was updated as well.



Discussion:

Resolving patch:
diff --git a/piptools/scripts/compile.py b/piptools/scripts/compile.py
--- a/piptools/scripts/compile.py
+++ b/piptools/scripts/compile.py
@@ -126,16 +126,15 @@ def cli(verbose, dry_run, pre, rebuild, find_links, index_url, extra_index_url,
     session = pip_command._build_session(pip_options)
     repository = PyPIRepository(pip_options, session)
 
-    # Pre-parse the inline package upgrade specs: they should take precedence
-    # over the stuff in the requirements files
-    upgrade_packages = [InstallRequirement.from_line(pkg)
-                        for pkg in upgrade_packages]
-
     # Proxy with a LocalRequirementsRepository if --upgrade is not specified
     # (= default invocation)
-    if not (upgrade or upgrade_packages) and os.path.exists(dst_file):
+    if not upgrade and os.path.exists(dst_file):
         ireqs = parse_requirements(dst_file, finder=repository.finder, session=repository.session, options=pip_options)
-        existing_pins = {key_from_req(ireq.req): ireq for ireq in ireqs if is_pinned_requirement(ireq)}
+        # Exclude packages from --upgrade-package/-P from the existing pins: We want to upgrade.
+        upgrade_pkgs_key = {key_from_req(InstallRequirement.from_line(pkg).req) for pkg in upgrade_packages}
+        existing_pins = {key_from_req(ireq.req): ireq
+                         for ireq in ireqs
+                         if is_pinned_requirement(ireq) and key_from_req(ireq.req) not in upgrade_pkgs_key}
         repository = LocalRequirementsRepository(existing_pins, repository)
 
     log.debug('Using indexes:')


Test patch:
diff --git a/tests/fixtures/minimal_wheels/small_fake_a-0.1-py2.py3-none-any.whl b/tests/fixtures/minimal_wheels/small_fake_a-0.1-py2.py3-none-any.whl
new file mode 100644
Binary files /dev/null and b/tests/fixtures/minimal_wheels/small_fake_a-0.1-py2.py3-none-any.whl differ
diff --git a/tests/fixtures/minimal_wheels/small_fake_a-0.2-py2.py3-none-any.whl b/tests/fixtures/minimal_wheels/small_fake_a-0.2-py2.py3-none-any.whl
new file mode 100644
Binary files /dev/null and b/tests/fixtures/minimal_wheels/small_fake_a-0.2-py2.py3-none-any.whl differ
diff --git a/tests/fixtures/minimal_wheels/small_fake_b-0.1-py2.py3-none-any.whl b/tests/fixtures/minimal_wheels/small_fake_b-0.1-py2.py3-none-any.whl
new file mode 100644
Binary files /dev/null and b/tests/fixtures/minimal_wheels/small_fake_b-0.1-py2.py3-none-any.whl differ
diff --git a/tests/fixtures/minimal_wheels/small_fake_b-0.2-py2.py3-none-any.whl b/tests/fixtures/minimal_wheels/small_fake_b-0.2-py2.py3-none-any.whl
new file mode 100644
Binary files /dev/null and b/tests/fixtures/minimal_wheels/small_fake_b-0.2-py2.py3-none-any.whl differ
diff --git a/tests/test_cli.py b/tests/test_cli.py
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -237,3 +237,26 @@ def test_input_file_without_extension(tmpdir):
         assert out.exit_code == 0
         assert '--output-file requirements.txt' in out.output
         assert 'six==1.10.0' in out.output
+
+
+def test_upgrade_packages_option(tmpdir):
+    """
+    piptools respects --upgrade-package/-P inline list.
+    """
+    fake_package_dir = os.path.join(os.path.split(__file__)[0], 'fixtures', 'minimal_wheels')
+    runner = CliRunner()
+    with runner.isolated_filesystem():
+        with open('requirements.in', 'w') as req_in:
+            req_in.write('small-fake-a\nsmall-fake-b')
+        with open('requirements.txt', 'w') as req_in:
+            req_in.write('small-fake-a==0.1\nsmall-fake-b==0.1')
+
+        out = runner.invoke(cli, [
+            '-P', 'small_fake_b',
+            '-f', fake_package_dir,
+        ])
+
+        print(out.output)
+        assert out.exit_code == 0
+        assert 'small-fake-a==0.1' in out.output
+        assert 'small-fake-b==0.2' in out.output