Skip to content

Commit

Permalink
add broken tests for conflicting dependency extras
Browse files Browse the repository at this point in the history
  • Loading branch information
reesehyde committed Oct 11, 2024
1 parent 8490954 commit fd1c1dc
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 0 deletions.
104 changes: 104 additions & 0 deletions tests/installation/test_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,110 @@ def test_run_with_dependencies_nested_extras(
assert locker.written_data == expected


@pytest.mark.parametrize("locked", [False]) # TODO: lock data
@pytest.mark.parametrize("extra", [None, "extra-one", "extra-two"])
def test_run_with_conflicting_dependency_extras(
installer: Installer,
pool: RepositoryPool,
locker: Locker,
installed: CustomInstalledRepository,
repo: Repository,
config: Config,
package: ProjectPackage,
extra: str | None,
locked: bool,
) -> None:
"""https://github.com/python-poetry/poetry/issues/834
Tests resolution of extras in both root ('extra-one', 'extra-two') and transitive
('demo-extra-one', 'demo-extra-two') dependencies
"""
# Demo package with two optional transitive dependencies, one for each extra
demo_pkg = get_package("demo", "1.0.0")
transitive_dep_one = get_package("transitive-dep", "1.1.0")
transitive_dep_two = get_package("transitive-dep", "1.2.0")
demo_pkg.extras = {
canonicalize_name("demo-extra-one"): [
get_dependency("transitive-dep", constraint={"version": "1.1.0", "optional": True})
],
canonicalize_name("demo-extra-two"): [
get_dependency("transitive-dep", constraint={"version": "1.2.0", "optional": True})
],
}
demo_pkg.add_dependency(
Factory.create_dependency(
"transitive-dep",
{
"version": "1.1.0",
"markers": "extra == 'demo-extra-one' and extra != 'demo-extra-two'",
"optional": True,
}
)
)
demo_pkg.add_dependency(
Factory.create_dependency(
"transitive-dep",
{
"version": "1.2.0",
"markers": "extra != 'demo-extra-one' and extra == 'demo-extra-two'",
"optional": True,
}
)
)
repo.add_package(demo_pkg)
repo.add_package(transitive_dep_one)
repo.add_package(transitive_dep_two)

# 'demo' with extra 'demo-extra-one' when package has 'extra-one' extra
# and with extra 'demo-extra-two' when 'extra-two'
extra_one_dep = Factory.create_dependency(
"demo",
{
"version": "1.0.0",
"markers": "extra == 'extra-one' and extra != 'extra-two'",
"extras": ["demo-extra-one"],
"optional": True,
},
)
extra_two_dep = Factory.create_dependency(
"demo",
{
"version": "1.0.0",
"markers": "extra != 'extra-one' and extra == 'extra-two'",
"extras": ["demo-extra-two"],
"optional": True,
},
)
package.add_dependency(extra_one_dep)
package.add_dependency(extra_two_dep)
package.extras = {
canonicalize_name("extra-one"): [extra_one_dep],
canonicalize_name("extra-two"): [extra_two_dep],
}

locker.locked(locked)
if locked:
raise ValueError("no lock data for this test yet")
locker.mock_lock_data(dict(fixture("TODO")))

if extra is not None:
installer.extras([extra])
result = installer.run()
assert result == 0

if not locked:
raise ValueError("no lock data for this test yet")
expected = fixture("TODO")
assert locker.written_data == expected

# Results of installation are consistent with the 'extra' input
assert isinstance(installer.executor, Executor)
if extra is None:
assert len(installer.executor.installations) == 0
else:
assert len(installer.executor.installations) == 2


@pytest.mark.parametrize("locked", [True, False])
@pytest.mark.parametrize("extra", [None, "cpu", "cuda"])
def test_run_with_exclusive_extras_different_sources(
Expand Down
41 changes: 41 additions & 0 deletions tests/puzzle/test_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -4707,6 +4707,47 @@ def test_solver_resolves_duplicate_dependency_in_extra(
)


@pytest.mark.parametrize("with_extra", [False, True])
def test_solver_resolves_duplicate_dependency_in_root_extra(
package: ProjectPackage,
pool: RepositoryPool,
repo: Repository,
io: NullIO,
with_extra: bool,
) -> None:
"""
Without extras, a newer version of A can be chosen than with root extras.
"""
constraint: dict[str, Any] = {"version": "*"}
if with_extra:
constraint["extras"] = ["foo"]
package_a1 = get_package("A", "1.0")
package_a2 = get_package("A", "2.0")

dep = get_dependency("A", ">=1.0")
package.add_dependency(dep)

dep_extra = get_dependency("A", "^1.0", optional=True)
dep_extra.marker = parse_marker("extra == 'foo'")
package.extras = {canonicalize_name("foo"): [dep_extra]}
package.add_dependency(dep_extra)

repo.add_package(package_a1)
repo.add_package(package_a2)

solver = Solver(package, pool, [], [], io)
transaction = solver.solve()

check_solver_result(

Check failure on line 4741 in tests/puzzle/test_solver.py

View check run for this annotation

Cirrus CI / Tests / FreeBSD (Python 3.8) / pytest

tests/puzzle/test_solver.py#L4741

tests.puzzle.test_solver.test_solver_resolves_duplicate_dependency_in_root_extra[True]
Raw output
package = Package('root', '1.0')
pool = <poetry.repositories.repository_pool.RepositoryPool object at 0x180045d71130>
repo = <poetry.repositories.repository.Repository object at 0x180045d710d0>
io = <cleo.io.null_io.NullIO object at 0x18003bb700a0>, with_extra = True

    @pytest.mark.parametrize("with_extra", [False, True])
    def test_solver_resolves_duplicate_dependency_in_root_extra(
        package: ProjectPackage,
        pool: RepositoryPool,
        repo: Repository,
        io: NullIO,
        with_extra: bool,
    ) -> None:
        """
        Without extras, a newer version of A can be chosen than with root extras.
        """
        constraint: dict[str, Any] = {"version": "*"}
        if with_extra:
            constraint["extras"] = ["foo"]
        package_a1 = get_package("A", "1.0")
        package_a2 = get_package("A", "2.0")
    
        dep = get_dependency("A", ">=1.0")
        package.add_dependency(dep)
    
        dep_extra = get_dependency("A", "^1.0", optional=True)
        dep_extra.marker = parse_marker("extra == 'foo'")
        package.extras = {canonicalize_name("foo"): [dep_extra]}
        package.add_dependency(dep_extra)
    
        repo.add_package(package_a1)
        repo.add_package(package_a2)
    
        solver = Solver(package, pool, [], [], io)
        transaction = solver.solve()
    
>       check_solver_result(
            transaction,
            (
                [
                    {"job": "install", "package": package_a1 if with_extra else package_a2},
                ]
            ),
        )

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:4741: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

transaction = <poetry.puzzle.transaction.Transaction object at 0x180045d234c0>
expected = [{'job': 'install', 'package': Package('a', '1.0'), 'skipped': False}]
synchronize = False

    def check_solver_result(
        transaction: Transaction,
        expected: list[dict[str, Any]],
        synchronize: bool = False,
    ) -> list[Operation]:
        for e in expected:
            if "skipped" not in e:
                e["skipped"] = False
    
        result = []
        ops = transaction.calculate_operations(synchronize=synchronize)
        for op in ops:
            if op.job_type == "update":
                assert isinstance(op, Update)
                result.append(
                    {
                        "job": "update",
                        "from": op.initial_package,
                        "to": op.target_package,
                        "skipped": op.skipped,
                    }
                )
            else:
                job = "install"
                if op.job_type == "uninstall":
                    job = "remove"
    
                result.append({"job": job, "package": op.package, "skipped": op.skipped})
    
>       assert result == expected
E       AssertionError: assert [{'job': 'ins...pped': False}] == [{'job': 'ins...pped': False}]
E         
E         Left contains one more item: {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         
E         Full diff:
E           [
E               {
E                   'job': 'install',
E                   'package': Package('a', '1.0'),
E                   'skipped': False,
E               },
E         +     {
E         +         'job': 'install',
E         +         'package': Package('a', '2.0'),
E         +         'skipped': False,
E         +     },
E           ]

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:113: AssertionError

Check failure on line 4741 in tests/puzzle/test_solver.py

View check run for this annotation

Cirrus CI / Tests / FreeBSD (Python 3.8) / pytest

tests/puzzle/test_solver.py#L4741

tests.puzzle.test_solver.test_solver_resolves_duplicate_dependency_in_root_extra[False]
Raw output
package = Package('root', '1.0')
pool = <poetry.repositories.repository_pool.RepositoryPool object at 0x180045dfe1c0>
repo = <poetry.repositories.repository.Repository object at 0x180045dfea00>
io = <cleo.io.null_io.NullIO object at 0x18003ad76c10>, with_extra = False

    @pytest.mark.parametrize("with_extra", [False, True])
    def test_solver_resolves_duplicate_dependency_in_root_extra(
        package: ProjectPackage,
        pool: RepositoryPool,
        repo: Repository,
        io: NullIO,
        with_extra: bool,
    ) -> None:
        """
        Without extras, a newer version of A can be chosen than with root extras.
        """
        constraint: dict[str, Any] = {"version": "*"}
        if with_extra:
            constraint["extras"] = ["foo"]
        package_a1 = get_package("A", "1.0")
        package_a2 = get_package("A", "2.0")
    
        dep = get_dependency("A", ">=1.0")
        package.add_dependency(dep)
    
        dep_extra = get_dependency("A", "^1.0", optional=True)
        dep_extra.marker = parse_marker("extra == 'foo'")
        package.extras = {canonicalize_name("foo"): [dep_extra]}
        package.add_dependency(dep_extra)
    
        repo.add_package(package_a1)
        repo.add_package(package_a2)
    
        solver = Solver(package, pool, [], [], io)
        transaction = solver.solve()
    
>       check_solver_result(
            transaction,
            (
                [
                    {"job": "install", "package": package_a1 if with_extra else package_a2},
                ]
            ),
        )

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:4741: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

transaction = <poetry.puzzle.transaction.Transaction object at 0x18003ad76f40>
expected = [{'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}]
synchronize = False

    def check_solver_result(
        transaction: Transaction,
        expected: list[dict[str, Any]],
        synchronize: bool = False,
    ) -> list[Operation]:
        for e in expected:
            if "skipped" not in e:
                e["skipped"] = False
    
        result = []
        ops = transaction.calculate_operations(synchronize=synchronize)
        for op in ops:
            if op.job_type == "update":
                assert isinstance(op, Update)
                result.append(
                    {
                        "job": "update",
                        "from": op.initial_package,
                        "to": op.target_package,
                        "skipped": op.skipped,
                    }
                )
            else:
                job = "install"
                if op.job_type == "uninstall":
                    job = "remove"
    
                result.append({"job": job, "package": op.package, "skipped": op.skipped})
    
>       assert result == expected
E       AssertionError: assert [{'job': 'ins...pped': False}] == [{'job': 'ins...pped': False}]
E         
E         At index 0 diff: {'job': 'install', 'package': Package('a', '1.0'), 'skipped': False} != {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         Left contains one more item: {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         
E         Full diff:
E           [
E         +     {
E         +         'job': 'install',
E         +         'package': Package('a', '1.0'),
E         +         'skipped': False,
E         +     },
E               {
E                   'job': 'install',
E                   'package': Package('a', '2.0'),
E                   'skipped': False,
E               },
E           ]

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:113: AssertionError

Check failure on line 4741 in tests/puzzle/test_solver.py

View check run for this annotation

Cirrus CI / Tests / FreeBSD (Python 3.9) / pytest

tests/puzzle/test_solver.py#L4741

tests.puzzle.test_solver.test_solver_resolves_duplicate_dependency_in_root_extra[True]
Raw output
package = Package('root', '1.0')
pool = <poetry.repositories.repository_pool.RepositoryPool object at 0x30ad68972af0>
repo = <poetry.repositories.repository.Repository object at 0x30ad68972cd0>
io = <cleo.io.null_io.NullIO object at 0x30ad68972d90>, with_extra = True

    @pytest.mark.parametrize("with_extra", [False, True])
    def test_solver_resolves_duplicate_dependency_in_root_extra(
        package: ProjectPackage,
        pool: RepositoryPool,
        repo: Repository,
        io: NullIO,
        with_extra: bool,
    ) -> None:
        """
        Without extras, a newer version of A can be chosen than with root extras.
        """
        constraint: dict[str, Any] = {"version": "*"}
        if with_extra:
            constraint["extras"] = ["foo"]
        package_a1 = get_package("A", "1.0")
        package_a2 = get_package("A", "2.0")
    
        dep = get_dependency("A", ">=1.0")
        package.add_dependency(dep)
    
        dep_extra = get_dependency("A", "^1.0", optional=True)
        dep_extra.marker = parse_marker("extra == 'foo'")
        package.extras = {canonicalize_name("foo"): [dep_extra]}
        package.add_dependency(dep_extra)
    
        repo.add_package(package_a1)
        repo.add_package(package_a2)
    
        solver = Solver(package, pool, [], [], io)
        transaction = solver.solve()
    
>       check_solver_result(
            transaction,
            (
                [
                    {"job": "install", "package": package_a1 if with_extra else package_a2},
                ]
            ),
        )

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:4741: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

transaction = <poetry.puzzle.transaction.Transaction object at 0x30ad68972760>
expected = [{'job': 'install', 'package': Package('a', '1.0'), 'skipped': False}]
synchronize = False

    def check_solver_result(
        transaction: Transaction,
        expected: list[dict[str, Any]],
        synchronize: bool = False,
    ) -> list[Operation]:
        for e in expected:
            if "skipped" not in e:
                e["skipped"] = False
    
        result = []
        ops = transaction.calculate_operations(synchronize=synchronize)
        for op in ops:
            if op.job_type == "update":
                assert isinstance(op, Update)
                result.append(
                    {
                        "job": "update",
                        "from": op.initial_package,
                        "to": op.target_package,
                        "skipped": op.skipped,
                    }
                )
            else:
                job = "install"
                if op.job_type == "uninstall":
                    job = "remove"
    
                result.append({"job": job, "package": op.package, "skipped": op.skipped})
    
>       assert result == expected
E       AssertionError: assert [{'job': 'ins...pped': False}] == [{'job': 'ins...pped': False}]
E         
E         Left contains one more item: {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         
E         Full diff:
E           [
E               {
E                   'job': 'install',
E                   'package': Package('a', '1.0'),
E                   'skipped': False,
E               },
E         +     {
E         +         'job': 'install',
E         +         'package': Package('a', '2.0'),
E         +         'skipped': False,
E         +     },
E           ]

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:113: AssertionError

Check failure on line 4741 in tests/puzzle/test_solver.py

View check run for this annotation

Cirrus CI / Tests / FreeBSD (Python 3.9) / pytest

tests/puzzle/test_solver.py#L4741

tests.puzzle.test_solver.test_solver_resolves_duplicate_dependency_in_root_extra[False]
Raw output
package = Package('root', '1.0')
pool = <poetry.repositories.repository_pool.RepositoryPool object at 0x30ad668bcdf0>
repo = <poetry.repositories.repository.Repository object at 0x30ad668bca30>
io = <cleo.io.null_io.NullIO object at 0x30ad68eb1e20>, with_extra = False

    @pytest.mark.parametrize("with_extra", [False, True])
    def test_solver_resolves_duplicate_dependency_in_root_extra(
        package: ProjectPackage,
        pool: RepositoryPool,
        repo: Repository,
        io: NullIO,
        with_extra: bool,
    ) -> None:
        """
        Without extras, a newer version of A can be chosen than with root extras.
        """
        constraint: dict[str, Any] = {"version": "*"}
        if with_extra:
            constraint["extras"] = ["foo"]
        package_a1 = get_package("A", "1.0")
        package_a2 = get_package("A", "2.0")
    
        dep = get_dependency("A", ">=1.0")
        package.add_dependency(dep)
    
        dep_extra = get_dependency("A", "^1.0", optional=True)
        dep_extra.marker = parse_marker("extra == 'foo'")
        package.extras = {canonicalize_name("foo"): [dep_extra]}
        package.add_dependency(dep_extra)
    
        repo.add_package(package_a1)
        repo.add_package(package_a2)
    
        solver = Solver(package, pool, [], [], io)
        transaction = solver.solve()
    
>       check_solver_result(
            transaction,
            (
                [
                    {"job": "install", "package": package_a1 if with_extra else package_a2},
                ]
            ),
        )

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:4741: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

transaction = <poetry.puzzle.transaction.Transaction object at 0x30ad64fa7a90>
expected = [{'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}]
synchronize = False

    def check_solver_result(
        transaction: Transaction,
        expected: list[dict[str, Any]],
        synchronize: bool = False,
    ) -> list[Operation]:
        for e in expected:
            if "skipped" not in e:
                e["skipped"] = False
    
        result = []
        ops = transaction.calculate_operations(synchronize=synchronize)
        for op in ops:
            if op.job_type == "update":
                assert isinstance(op, Update)
                result.append(
                    {
                        "job": "update",
                        "from": op.initial_package,
                        "to": op.target_package,
                        "skipped": op.skipped,
                    }
                )
            else:
                job = "install"
                if op.job_type == "uninstall":
                    job = "remove"
    
                result.append({"job": job, "package": op.package, "skipped": op.skipped})
    
>       assert result == expected
E       AssertionError: assert [{'job': 'ins...pped': False}] == [{'job': 'ins...pped': False}]
E         
E         At index 0 diff: {'job': 'install', 'package': Package('a', '1.0'), 'skipped': False} != {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         Left contains one more item: {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         
E         Full diff:
E           [
E         +     {
E         +         'job': 'install',
E         +         'package': Package('a', '1.0'),
E         +         'skipped': False,
E         +     },
E               {
E                   'job': 'install',
E                   'package': Package('a', '2.0'),
E                   'skipped': False,
E               },
E           ]

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:113: AssertionError

Check failure on line 4741 in tests/puzzle/test_solver.py

View check run for this annotation

Cirrus CI / Tests / FreeBSD (Python 3.11) / pytest

tests/puzzle/test_solver.py#L4741

tests.puzzle.test_solver.test_solver_resolves_duplicate_dependency_in_root_extra[True]
Raw output
package = Package('root', '1.0')
pool = <poetry.repositories.repository_pool.RepositoryPool object at 0x2f70a85a7b50>
repo = <poetry.repositories.repository.Repository object at 0x2f70a85a7690>
io = <cleo.io.null_io.NullIO object at 0x2f70a85a7ed0>, with_extra = True

    @pytest.mark.parametrize("with_extra", [False, True])
    def test_solver_resolves_duplicate_dependency_in_root_extra(
        package: ProjectPackage,
        pool: RepositoryPool,
        repo: Repository,
        io: NullIO,
        with_extra: bool,
    ) -> None:
        """
        Without extras, a newer version of A can be chosen than with root extras.
        """
        constraint: dict[str, Any] = {"version": "*"}
        if with_extra:
            constraint["extras"] = ["foo"]
        package_a1 = get_package("A", "1.0")
        package_a2 = get_package("A", "2.0")
    
        dep = get_dependency("A", ">=1.0")
        package.add_dependency(dep)
    
        dep_extra = get_dependency("A", "^1.0", optional=True)
        dep_extra.marker = parse_marker("extra == 'foo'")
        package.extras = {canonicalize_name("foo"): [dep_extra]}
        package.add_dependency(dep_extra)
    
        repo.add_package(package_a1)
        repo.add_package(package_a2)
    
        solver = Solver(package, pool, [], [], io)
        transaction = solver.solve()
    
>       check_solver_result(
            transaction,
            (
                [
                    {"job": "install", "package": package_a1 if with_extra else package_a2},
                ]
            ),
        )

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:4741: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

transaction = <poetry.puzzle.transaction.Transaction object at 0x2f70a8fc2150>
expected = [{'job': 'install', 'package': Package('a', '1.0'), 'skipped': False}]
synchronize = False

    def check_solver_result(
        transaction: Transaction,
        expected: list[dict[str, Any]],
        synchronize: bool = False,
    ) -> list[Operation]:
        for e in expected:
            if "skipped" not in e:
                e["skipped"] = False
    
        result = []
        ops = transaction.calculate_operations(synchronize=synchronize)
        for op in ops:
            if op.job_type == "update":
                assert isinstance(op, Update)
                result.append(
                    {
                        "job": "update",
                        "from": op.initial_package,
                        "to": op.target_package,
                        "skipped": op.skipped,
                    }
                )
            else:
                job = "install"
                if op.job_type == "uninstall":
                    job = "remove"
    
                result.append({"job": job, "package": op.package, "skipped": op.skipped})
    
>       assert result == expected
E       AssertionError: assert [{'job': 'ins...pped': False}] == [{'job': 'ins...pped': False}]
E         
E         Left contains one more item: {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         
E         Full diff:
E           [
E               {
E                   'job': 'install',
E                   'package': Package('a', '1.0'),
E                   'skipped': False,
E               },
E         +     {
E         +         'job': 'install',
E         +         'package': Package('a', '2.0'),
E         +         'skipped': False,
E         +     },
E           ]

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:113: AssertionError

Check failure on line 4741 in tests/puzzle/test_solver.py

View check run for this annotation

Cirrus CI / Tests / FreeBSD (Python 3.11) / pytest

tests/puzzle/test_solver.py#L4741

tests.puzzle.test_solver.test_solver_resolves_duplicate_dependency_in_root_extra[False]
Raw output
package = Package('root', '1.0')
pool = <poetry.repositories.repository_pool.RepositoryPool object at 0x2f70a5a79750>
repo = <poetry.repositories.repository.Repository object at 0x2f70a5a7a890>
io = <cleo.io.null_io.NullIO object at 0x2f70a5bb7490>, with_extra = False

    @pytest.mark.parametrize("with_extra", [False, True])
    def test_solver_resolves_duplicate_dependency_in_root_extra(
        package: ProjectPackage,
        pool: RepositoryPool,
        repo: Repository,
        io: NullIO,
        with_extra: bool,
    ) -> None:
        """
        Without extras, a newer version of A can be chosen than with root extras.
        """
        constraint: dict[str, Any] = {"version": "*"}
        if with_extra:
            constraint["extras"] = ["foo"]
        package_a1 = get_package("A", "1.0")
        package_a2 = get_package("A", "2.0")
    
        dep = get_dependency("A", ">=1.0")
        package.add_dependency(dep)
    
        dep_extra = get_dependency("A", "^1.0", optional=True)
        dep_extra.marker = parse_marker("extra == 'foo'")
        package.extras = {canonicalize_name("foo"): [dep_extra]}
        package.add_dependency(dep_extra)
    
        repo.add_package(package_a1)
        repo.add_package(package_a2)
    
        solver = Solver(package, pool, [], [], io)
        transaction = solver.solve()
    
>       check_solver_result(
            transaction,
            (
                [
                    {"job": "install", "package": package_a1 if with_extra else package_a2},
                ]
            ),
        )

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:4741: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

transaction = <poetry.puzzle.transaction.Transaction object at 0x2f70a85ee890>
expected = [{'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}]
synchronize = False

    def check_solver_result(
        transaction: Transaction,
        expected: list[dict[str, Any]],
        synchronize: bool = False,
    ) -> list[Operation]:
        for e in expected:
            if "skipped" not in e:
                e["skipped"] = False
    
        result = []
        ops = transaction.calculate_operations(synchronize=synchronize)
        for op in ops:
            if op.job_type == "update":
                assert isinstance(op, Update)
                result.append(
                    {
                        "job": "update",
                        "from": op.initial_package,
                        "to": op.target_package,
                        "skipped": op.skipped,
                    }
                )
            else:
                job = "install"
                if op.job_type == "uninstall":
                    job = "remove"
    
                result.append({"job": job, "package": op.package, "skipped": op.skipped})
    
>       assert result == expected
E       AssertionError: assert [{'job': 'ins...pped': False}] == [{'job': 'ins...pped': False}]
E         
E         At index 0 diff: {'job': 'install', 'package': Package('a', '1.0'), 'skipped': False} != {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         Left contains one more item: {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         
E         Full diff:
E           [
E         +     {
E         +         'job': 'install',
E         +         'package': Package('a', '1.0'),
E         +         'skipped': False,
E         +     },
E               {
E                   'job': 'install',
E                   'package': Package('a', '2.0'),
E                   'skipped': False,
E               },
E           ]

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:113: AssertionError

Check failure on line 4741 in tests/puzzle/test_solver.py

View check run for this annotation

Cirrus CI / Tests / FreeBSD (Python 3.10) / pytest

tests/puzzle/test_solver.py#L4741

tests.puzzle.test_solver.test_solver_resolves_duplicate_dependency_in_root_extra[False]
Raw output
package = Package('root', '1.0')
pool = <poetry.repositories.repository_pool.RepositoryPool object at 0x235c06e10b50>
repo = <poetry.repositories.repository.Repository object at 0x235c06e10c10>
io = <cleo.io.null_io.NullIO object at 0x235c06e10f40>, with_extra = False

    @pytest.mark.parametrize("with_extra", [False, True])
    def test_solver_resolves_duplicate_dependency_in_root_extra(
        package: ProjectPackage,
        pool: RepositoryPool,
        repo: Repository,
        io: NullIO,
        with_extra: bool,
    ) -> None:
        """
        Without extras, a newer version of A can be chosen than with root extras.
        """
        constraint: dict[str, Any] = {"version": "*"}
        if with_extra:
            constraint["extras"] = ["foo"]
        package_a1 = get_package("A", "1.0")
        package_a2 = get_package("A", "2.0")
    
        dep = get_dependency("A", ">=1.0")
        package.add_dependency(dep)
    
        dep_extra = get_dependency("A", "^1.0", optional=True)
        dep_extra.marker = parse_marker("extra == 'foo'")
        package.extras = {canonicalize_name("foo"): [dep_extra]}
        package.add_dependency(dep_extra)
    
        repo.add_package(package_a1)
        repo.add_package(package_a2)
    
        solver = Solver(package, pool, [], [], io)
        transaction = solver.solve()
    
>       check_solver_result(
            transaction,
            (
                [
                    {"job": "install", "package": package_a1 if with_extra else package_a2},
                ]
            ),
        )

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:4741: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

transaction = <poetry.puzzle.transaction.Transaction object at 0x235c06ef3ee0>
expected = [{'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}]
synchronize = False

    def check_solver_result(
        transaction: Transaction,
        expected: list[dict[str, Any]],
        synchronize: bool = False,
    ) -> list[Operation]:
        for e in expected:
            if "skipped" not in e:
                e["skipped"] = False
    
        result = []
        ops = transaction.calculate_operations(synchronize=synchronize)
        for op in ops:
            if op.job_type == "update":
                assert isinstance(op, Update)
                result.append(
                    {
                        "job": "update",
                        "from": op.initial_package,
                        "to": op.target_package,
                        "skipped": op.skipped,
                    }
                )
            else:
                job = "install"
                if op.job_type == "uninstall":
                    job = "remove"
    
                result.append({"job": job, "package": op.package, "skipped": op.skipped})
    
>       assert result == expected
E       AssertionError: assert [{'job': 'ins...pped': False}] == [{'job': 'ins...pped': False}]
E         
E         At index 0 diff: {'job': 'install', 'package': Package('a', '1.0'), 'skipped': False} != {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         Left contains one more item: {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         
E         Full diff:
E           [
E         +     {
E         +         'job': 'install',
E         +         'package': Package('a', '1.0'),
E         +         'skipped': False,
E         +     },
E               {
E                   'job': 'install',
E                   'package': Package('a', '2.0'),
E                   'skipped': False,
E               },
E           ]

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:113: AssertionError

Check failure on line 4741 in tests/puzzle/test_solver.py

View check run for this annotation

Cirrus CI / Tests / FreeBSD (Python 3.10) / pytest

tests/puzzle/test_solver.py#L4741

tests.puzzle.test_solver.test_solver_resolves_duplicate_dependency_in_root_extra[True]
Raw output
package = Package('root', '1.0')
pool = <poetry.repositories.repository_pool.RepositoryPool object at 0x235c06f223b0>
repo = <poetry.repositories.repository.Repository object at 0x235c06f21ff0>
io = <cleo.io.null_io.NullIO object at 0x235c07480490>, with_extra = True

    @pytest.mark.parametrize("with_extra", [False, True])
    def test_solver_resolves_duplicate_dependency_in_root_extra(
        package: ProjectPackage,
        pool: RepositoryPool,
        repo: Repository,
        io: NullIO,
        with_extra: bool,
    ) -> None:
        """
        Without extras, a newer version of A can be chosen than with root extras.
        """
        constraint: dict[str, Any] = {"version": "*"}
        if with_extra:
            constraint["extras"] = ["foo"]
        package_a1 = get_package("A", "1.0")
        package_a2 = get_package("A", "2.0")
    
        dep = get_dependency("A", ">=1.0")
        package.add_dependency(dep)
    
        dep_extra = get_dependency("A", "^1.0", optional=True)
        dep_extra.marker = parse_marker("extra == 'foo'")
        package.extras = {canonicalize_name("foo"): [dep_extra]}
        package.add_dependency(dep_extra)
    
        repo.add_package(package_a1)
        repo.add_package(package_a2)
    
        solver = Solver(package, pool, [], [], io)
        transaction = solver.solve()
    
>       check_solver_result(
            transaction,
            (
                [
                    {"job": "install", "package": package_a1 if with_extra else package_a2},
                ]
            ),
        )

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:4741: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

transaction = <poetry.puzzle.transaction.Transaction object at 0x235c06ee39a0>
expected = [{'job': 'install', 'package': Package('a', '1.0'), 'skipped': False}]
synchronize = False

    def check_solver_result(
        transaction: Transaction,
        expected: list[dict[str, Any]],
        synchronize: bool = False,
    ) -> list[Operation]:
        for e in expected:
            if "skipped" not in e:
                e["skipped"] = False
    
        result = []
        ops = transaction.calculate_operations(synchronize=synchronize)
        for op in ops:
            if op.job_type == "update":
                assert isinstance(op, Update)
                result.append(
                    {
                        "job": "update",
                        "from": op.initial_package,
                        "to": op.target_package,
                        "skipped": op.skipped,
                    }
                )
            else:
                job = "install"
                if op.job_type == "uninstall":
                    job = "remove"
    
                result.append({"job": job, "package": op.package, "skipped": op.skipped})
    
>       assert result == expected
E       AssertionError: assert [{'job': 'ins...pped': False}] == [{'job': 'ins...pped': False}]
E         
E         Left contains one more item: {'job': 'install', 'package': Package('a', '2.0'), 'skipped': False}
E         
E         Full diff:
E           [
E               {
E                   'job': 'install',
E                   'package': Package('a', '1.0'),
E                   'skipped': False,
E               },
E         +     {
E         +         'job': 'install',
E         +         'package': Package('a', '2.0'),
E         +         'skipped': False,
E         +     },
E           ]

/tmp/cirrus-ci-build/tests/puzzle/test_solver.py:113: AssertionError
transaction,
(
[
{"job": "install", "package": package_a1 if with_extra else package_a2},
]
),
)


def test_solver_resolves_duplicate_dependencies_with_restricted_extras(
package: ProjectPackage,
pool: RepositoryPool,
Expand Down

0 comments on commit fd1c1dc

Please sign in to comment.