Skip to content

Commit

Permalink
avoid infinite loop when adding a dependency (#7405)
Browse files Browse the repository at this point in the history
  • Loading branch information
dimbleby committed Apr 10, 2023
1 parent c5a7111 commit d2e6ad6
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/poetry/mixology/version_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,9 @@ def _resolve_conflict(self, incompatibility: Incompatibility) -> Incompatibility
# .. _algorithm documentation:
# https://github.com/dart-lang/pub/tree/master/doc/solver.md#conflict-resolution # noqa: E501
if difference is not None:
new_terms.append(difference.inverse)
inverse = difference.inverse
if inverse.dependency != most_recent_satisfier.dependency:
new_terms.append(inverse)

incompatibility = Incompatibility(
new_terms, ConflictCause(incompatibility, most_recent_satisfier.cause)
Expand Down
13 changes: 8 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ def _factory(
install_deps: bool = True,
source: Path | None = None,
locker_config: dict[str, Any] | None = None,
use_test_locker: bool = True,
) -> Poetry:
project_dir = workspace / f"poetry-fixture-{name}"
dependencies = dependencies or {}
Expand Down Expand Up @@ -412,12 +413,14 @@ def _factory(

poetry = Factory().create_poetry(project_dir)

locker = TestLocker(
poetry.locker.lock, locker_config or poetry.locker._local_config
)
locker.write()
if use_test_locker:
locker = TestLocker(
poetry.locker.lock, locker_config or poetry.locker._local_config
)
locker.write()

poetry.set_locker(locker)

poetry.set_locker(locker)
poetry.set_config(config)

pool = RepositoryPool()
Expand Down
33 changes: 33 additions & 0 deletions tests/console/commands/test_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from poetry.core.constraints.version import Version
from poetry.core.packages.package import Package

from poetry.puzzle.exceptions import SolverProblemError
from poetry.repositories.legacy_repository import LegacyRepository
from tests.helpers import get_dependency
from tests.helpers import get_package
Expand Down Expand Up @@ -45,6 +46,20 @@ def poetry_with_up_to_date_lockfile(
)


@pytest.fixture
def poetry_with_path_dependency(
project_factory: ProjectFactory, fixture_dir: FixtureDirGetter
) -> Poetry:
source = fixture_dir("with_path_dependency")

poetry = project_factory(
name="foobar",
source=source,
use_test_locker=False,
)
return poetry


@pytest.fixture()
def tester(command_tester_factory: CommandTesterFactory) -> CommandTester:
return command_tester_factory("add")
Expand Down Expand Up @@ -2238,3 +2253,21 @@ def error(_: Any) -> int:
assert poetry_with_up_to_date_lockfile.file.read() == original_pyproject_content
assert poetry_with_up_to_date_lockfile.locker.lock_data == original_lockfile_content
assert tester.io.fetch_output() == expected


def test_add_with_path_dependency_no_loopiness(
poetry_with_path_dependency: Poetry,
repo: TestRepository,
command_tester_factory: CommandTesterFactory,
) -> None:
"""https://github.com/python-poetry/poetry/issues/7398"""
tester = command_tester_factory("add", poetry=poetry_with_path_dependency)

requests_old = get_package("requests", "2.25.1")
requests_new = get_package("requests", "2.28.2")

repo.add_package(requests_old)
repo.add_package(requests_new)

with pytest.raises(SolverProblemError):
tester.execute("requests")
12 changes: 12 additions & 0 deletions tests/fixtures/with_path_dependency/bazz/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from __future__ import annotations

from distutils.core import setup


setup(
name="bazz",
version="1",
py_modules=["demo"],
package_dir={"src": "src"},
install_requires=["requests~=2.25.1"],
)
98 changes: 98 additions & 0 deletions tests/fixtures/with_path_dependency/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions tests/fixtures/with_path_dependency/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[tool.poetry]
name = "foobar"
version = "0.1.0"
description = ""
authors = []
readme = "README.md"
packages = [{include = "foobar"}]

[tool.poetry.dependencies]
python = "^3.9"
bazz = { path = "./bazz", develop = true }

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
1 change: 1 addition & 0 deletions tests/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def __call__(
poetry_lock_content: str | None = None,
install_deps: bool = True,
source: Path | None = None,
use_test_locker: bool = True,
) -> Poetry:
...

Expand Down

0 comments on commit d2e6ad6

Please sign in to comment.