Commit d2e6ad6e by David Hotham Committed by GitHub

avoid infinite loop when adding a dependency (#7405)

parent c5a71115
......@@ -331,7 +331,9 @@ class VersionSolver:
# .. _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)
......
......@@ -378,6 +378,7 @@ def project_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 {}
......@@ -412,12 +413,14 @@ def project_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()
......
......@@ -10,6 +10,7 @@ import pytest
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
......@@ -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")
......@@ -2238,3 +2253,21 @@ Resolving dependencies...
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")
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"],
)
# This file is automatically @generated by Poetry 1.4.0.dev0 and should not be changed by hand.
[[package]]
name = "bazz"
version = "1"
description = ""
category = "main"
optional = false
python-versions = "*"
files = []
develop = true
[package.dependencies]
requests = ">=2.25.1,<2.26.0"
[package.source]
type = "directory"
url = "bazz"
[[package]]
name = "certifi"
version = "2022.12.7"
description = "Python package for providing Mozilla's CA Bundle."
category = "main"
optional = false
python-versions = ">=3.6"
files = [
{file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"},
{file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"},
]
[[package]]
name = "chardet"
version = "4.0.0"
description = "Universal encoding detector for Python 2 and 3"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
files = [
{file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
{file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
]
[[package]]
name = "idna"
version = "2.10"
description = "Internationalized Domain Names in Applications (IDNA)"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = [
{file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"},
{file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"},
]
[[package]]
name = "requests"
version = "2.25.1"
description = "Python HTTP for Humans."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
files = [
{file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"},
{file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"},
]
[package.dependencies]
certifi = ">=2017.4.17"
chardet = ">=3.0.2,<5"
idna = ">=2.5,<3"
urllib3 = ">=1.21.1,<1.27"
[package.extras]
security = ["cryptography (>=1.3.4)", "pyOpenSSL (>=0.14)"]
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
[[package]]
name = "urllib3"
version = "1.26.14"
description = "HTTP library with thread-safe connection pooling, file post, and more."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
files = [
{file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"},
{file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"},
]
[package.extras]
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"]
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[metadata]
lock-version = "2.0"
python-versions = "^3.9"
content-hash = "81853eb3be9c7faf1950f23273d0fb3dae75833f6e4aa21b6c3038da25ba26f6"
[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"
......@@ -46,6 +46,7 @@ class ProjectFactory(Protocol):
poetry_lock_content: str | None = None,
install_deps: bool = True,
source: Path | None = None,
use_test_locker: bool = True,
) -> Poetry:
...
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment