Skip to content

Commit

Permalink
Fix missing vias when more than two input files are used (#1890)
Browse files Browse the repository at this point in the history
  • Loading branch information
lpulley authored Jul 1, 2023
1 parent 51d9e1c commit 7958a71
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 5 deletions.
26 changes: 21 additions & 5 deletions piptools/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,18 @@ def __init__(
self.unsafe_constraints: set[InstallRequirement] = set()

self.existing_constraints = existing_constraints
self._constraints_map = {key_from_ireq(ireq): ireq for ireq in constraints}

# Categorize InstallRequirements into sets by key
constraints_sets: DefaultDict[
str, set[InstallRequirement]
] = collections.defaultdict(set)
for ireq in constraints:
constraints_sets[key_from_ireq(ireq)].add(ireq)
# Collapse each set of InstallRequirements using combine_install_requirements
self._constraints_map = {
ireq_key: combine_install_requirements(ireqs)
for ireq_key, ireqs in constraints_sets.items()
}

# Make sure there is no enabled legacy resolver
options.deprecated_features_enabled = omit_list_value(
Expand Down Expand Up @@ -759,9 +770,14 @@ def _get_install_requirement_from_candidate(
ireq_key = key_from_ireq(ireq)
pinned_ireq._required_by = reverse_dependencies.get(ireq_key, set())

# Save source for annotation
source_ireq = self._constraints_map.get(ireq_key)
if source_ireq is not None:
pinned_ireq._source_ireqs = [source_ireq]
# Save sources for annotation
constraint_ireq = self._constraints_map.get(ireq_key)
if constraint_ireq is not None:
if hasattr(constraint_ireq, "_source_ireqs"):
# If the constraint is combined (has _source_ireqs), use those
pinned_ireq._source_ireqs = constraint_ireq._source_ireqs
else:
# Otherwise (the constraint is not combined) it is the source
pinned_ireq._source_ireqs = [constraint_ireq]

return pinned_ireq
36 changes: 36 additions & 0 deletions tests/test_cli_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -1909,6 +1909,42 @@ def test_upgrade_package_doesnt_remove_annotation(pip_conf, runner):
)


@pytest.mark.parametrize(("num_inputs"), (2, 3, 10))
def test_many_inputs_includes_all_annotations(pip_conf, runner, tmp_path, num_inputs):
"""
Tests that an entry required by multiple input files is attributed to all of them in the
annotation.
See: https://github.com/jazzband/pip-tools/issues/1853
"""
req_ins = [tmp_path / f"requirements{n:02d}.in" for n in range(num_inputs)]
for req_in in req_ins:
req_in.write_text("small-fake-a==0.1\n")

out = runner.invoke(
cli,
[
"--output-file",
"-",
"--quiet",
"--no-header",
"--no-emit-find-links",
]
+ [str(r) for r in req_ins],
)
assert out.exit_code == 0, out.stderr
assert (
out.stdout
== "\n".join(
[
"small-fake-a==0.1",
" # via",
]
+ [f" # -r {req_in}" for req_in in req_ins]
)
+ "\n"
)


@pytest.mark.parametrize(
"options",
(
Expand Down

0 comments on commit 7958a71

Please sign in to comment.