Skip to content

Commit

Permalink
Fix for sync error when the ireqs being merged have no names (#1802)
Browse files Browse the repository at this point in the history
* Fix for sync error when the ireqs being merged have no names

When no name was provided, the ireqs would have no underlying req
attribute. Calling ireq.specifier would raise an AttributeError.

* Integration test for merging requirements without names
  • Loading branch information
richafrank committed Feb 2, 2023
1 parent 83042a0 commit 9134115
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
6 changes: 5 additions & 1 deletion piptools/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ def merge(
if existing_ireq:
# NOTE: We check equality here since we can assume that the
# requirements are all pinned
if ireq.specifier != existing_ireq.specifier:
if (
ireq.req
and existing_ireq.req
and ireq.specifier != existing_ireq.specifier
):
raise IncompatibleRequirements(ireq, existing_ireq)

# TODO: Always pick the largest specifier in case of a conflict
Expand Down
26 changes: 26 additions & 0 deletions tests/test_cli_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import subprocess
import sys
from pathlib import Path
from unittest import mock

import pytest
Expand Down Expand Up @@ -128,6 +129,31 @@ def test_merge_error(req_lines, should_raise, runner):
assert out.exit_code == 1


@pytest.mark.parametrize(
"req_line",
(
"file:.",
"-e file:.",
),
)
@mock.patch("piptools.sync.run")
def test_merge_no_name_urls(run, req_line, runner):
"""
Test sync succeeds when merging requirements that lack names.
"""
reqs_paths = [
Path(name).absolute() for name in ("requirements.txt", "dev_requirements.txt")
]

for reqs_path in reqs_paths:
with reqs_path.open("w") as req_out:
req_out.write(f"{req_line} \n")

out = runner.invoke(cli, [str(path) for path in reqs_paths])
assert out.exit_code == 0
assert run.call_count == 2


@pytest.mark.parametrize(
("cli_flags", "expected_install_flags"),
(
Expand Down
20 changes: 20 additions & 0 deletions tests/test_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,26 @@ def test_merge_urls(from_line):
)


@pytest.mark.parametrize(
"install_req",
(
"from_line",
"from_editable",
),
)
def test_merge_no_name_urls(install_req, request):
install_req = request.getfixturevalue(install_req)
url = "file:///example.zip"
requirements = [
install_req(url),
install_req(url),
]

assert Counter(requirements[1:]) == Counter(
merge(requirements, ignore_conflicts=False)
)


def test_diff_should_do_nothing():
installed = [] # empty env
reqs = [] # no requirements
Expand Down

0 comments on commit 9134115

Please sign in to comment.