From 103623c2f2a01bc417232c205aa9ef94c47f4ad5 Mon Sep 17 00:00:00 2001 From: Andy Kluger Date: Wed, 9 Feb 2022 01:08:32 -0500 Subject: [PATCH 1/4] Also treat --upgrade-packages as '-c constraints.txt' style constraints Ensure temporary constraints file gets cleaned up in a way that avoids Windows file handling complications --- piptools/scripts/compile.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/piptools/scripts/compile.py b/piptools/scripts/compile.py index 9424968ac..723a5c8ba 100755 --- a/piptools/scripts/compile.py +++ b/piptools/scripts/compile.py @@ -452,6 +452,27 @@ def cli( ) ) + if upgrade_packages: + constraints_file = tempfile.NamedTemporaryFile(mode="wt", delete=False) + constraints_file.write("\n".join(upgrade_packages)) + constraints_file.flush() + try: + reqs = list( + parse_requirements( + constraints_file.name, + finder=repository.finder, + session=repository.session, + options=repository.options, + constraint=True, + ) + ) + finally: + constraints_file.close() + os.unlink(constraints_file.name) + for req in reqs: + req.comes_from = None + constraints.extend(reqs) + extras = tuple(itertools.chain.from_iterable(ex.split(",") for ex in extras)) if extras and not setup_file_found: From 10808bfd15063f9dde5d7eddee3f8f975645371b Mon Sep 17 00:00:00 2001 From: Andy Kluger Date: Wed, 9 Feb 2022 01:45:08 -0500 Subject: [PATCH 2/4] Don't add upgrade pkgs which are also existing pins as regular reqs Remove leftovers of now unused existing_pins_to_upgrade set --- piptools/scripts/compile.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/piptools/scripts/compile.py b/piptools/scripts/compile.py index 723a5c8ba..3c321dc25 100755 --- a/piptools/scripts/compile.py +++ b/piptools/scripts/compile.py @@ -368,10 +368,7 @@ def cli( key_from_ireq(install_req): install_req for install_req in upgrade_reqs_gen } - existing_pins_to_upgrade = set() - - # Exclude packages from --upgrade-package/-P from the existing - # constraints, and separately gather pins to be upgraded + # Exclude packages from --upgrade-package/-P from the existing constraints existing_pins = {} # Proxy with a LocalRequirementsRepository if --upgrade is not specified @@ -389,9 +386,7 @@ def cli( for ireq in filter(is_pinned_requirement, ireqs): key = key_from_ireq(ireq) - if key in upgrade_install_reqs: - existing_pins_to_upgrade.add(key) - else: + if key not in upgrade_install_reqs: existing_pins[key] = ireq repository = LocalRequirementsRepository( existing_pins, repository, reuse_hashes=reuse_hashes @@ -483,9 +478,8 @@ def cli( key_from_ireq(ireq) for ireq in constraints if not ireq.constraint } - allowed_upgrades = primary_packages | existing_pins_to_upgrade constraints.extend( - ireq for key, ireq in upgrade_install_reqs.items() if key in allowed_upgrades + ireq for key, ireq in upgrade_install_reqs.items() if key in primary_packages ) constraints = [req for req in constraints if req.match_markers(extras)] From 051c72c761c902b5914a606fba219064df1b9adb Mon Sep 17 00:00:00 2001 From: Andy Kluger Date: Wed, 9 Feb 2022 22:49:03 -0500 Subject: [PATCH 3/4] Parametrize test_upgrade_packages_option_subdependency ... to cover when the subdependency is not already pinned --- tests/test_cli_compile.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_cli_compile.py b/tests/test_cli_compile.py index 72acd52fe..ce8532022 100644 --- a/tests/test_cli_compile.py +++ b/tests/test_cli_compile.py @@ -1592,6 +1592,7 @@ def test_unreachable_index_urls(runner, cli_options, expected_message): assert expected_message in stderr_lines +@pytest.mark.parametrize("subdep_already_pinned", (True, False)) @pytest.mark.parametrize( ("current_package", "upgraded_package"), ( @@ -1600,7 +1601,7 @@ def test_unreachable_index_urls(runner, cli_options, expected_message): ), ) def test_upgrade_packages_option_subdependency( - pip_conf, runner, current_package, upgraded_package + pip_conf, runner, current_package, upgraded_package, subdep_already_pinned ): """ Test that pip-compile --upgrade-package/-P upgrades/downgrades subdependencies. @@ -1611,7 +1612,8 @@ def test_upgrade_packages_option_subdependency( with open("requirements.txt", "w") as reqs: reqs.write("small-fake-a==0.1\n") - reqs.write(current_package + "\n") + if subdep_already_pinned: + reqs.write(current_package + "\n") reqs.write("small-fake-with-unpinned-deps==0.1\n") out = runner.invoke( From 91a1c0e5a96de36dbee18e0c5568d3d4eca89c7d Mon Sep 17 00:00:00 2001 From: Andy Kluger Date: Wed, 9 Feb 2022 23:53:12 -0500 Subject: [PATCH 4/4] Parametrize combined --upgrade and -P test ... to cover when the -P pkgs are only subdependencies --- tests/test_cli_compile.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/test_cli_compile.py b/tests/test_cli_compile.py index ce8532022..87bca2693 100644 --- a/tests/test_cli_compile.py +++ b/tests/test_cli_compile.py @@ -803,13 +803,20 @@ def test_upgrade_packages_version_option_no_existing_file(pip_conf, runner): assert "small-fake-b==0.2" in out.stderr -def test_upgrade_packages_version_option_and_upgrade(pip_conf, runner): +@pytest.mark.parametrize( + "reqs_in", + ( + pytest.param("small-fake-a\nsmall-fake-b", id="direct reqs"), + pytest.param("small-fake-with-unpinned-deps", id="parent req"), + ), +) +def test_upgrade_packages_version_option_and_upgrade(pip_conf, runner, reqs_in): """ piptools respects --upgrade-package/-P inline list with specified versions whilst also doing --upgrade. """ with open("requirements.in", "w") as req_in: - req_in.write("small-fake-a\nsmall-fake-b") + req_in.write(reqs_in) with open("requirements.txt", "w") as req_in: req_in.write("small-fake-a==0.1\nsmall-fake-b==0.1")