Skip to content

Commit

Permalink
locker: ensure correct handling of extras export
Browse files Browse the repository at this point in the history
Previously, when determining nested dependencies, the check for
activated extras/features of top level dependencies were done after the
nested dependencies were processed. This lead to exports containing
in active extras. This change resolves this by pre-selecting top level
packages prior to identifying nested dependencies.
  • Loading branch information
abn committed Oct 14, 2020
1 parent a7d6676 commit 2b6f82e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 18 deletions.
22 changes: 16 additions & 6 deletions poetry/packages/locker.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,20 +318,30 @@ def get_project_dependency_packages(
)
)

for dependency in self.get_project_dependencies(
project_requires=project_requires,
locked_packages=repository.packages,
with_nested=True,
):
# If a package is optional and we haven't opted in to it, do not select
selected = []
for dependency in project_requires:
try:
package = repository.find_packages(dependency=dependency)[0]
except IndexError:
continue

# If a package is optional and we haven't opted in to it, continue
if extra_package_names is not None and (
package.optional and package.name not in extra_package_names
):
# a package is locked as optional, but is not activated via extras
continue

selected.append(dependency)

for dependency in self.get_project_dependencies(
project_requires=selected,
locked_packages=repository.packages,
with_nested=True,
):
try:
package = repository.find_packages(dependency=dependency)[0]
except IndexError:
continue

for extra in dependency.extras:
Expand Down
27 changes: 15 additions & 12 deletions tests/utils/test_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,8 +544,17 @@ def test_exporter_exports_requirements_txt_without_optional_packages(tmp_dir, po
assert expected == content


def test_exporter_exports_requirements_txt_with_optional_packages_if_opted_in(
tmp_dir, poetry
@pytest.mark.parametrize(
"extras,lines",
[
(None, ["foo==1.2.3"]),
(False, ["foo==1.2.3"]),
(True, ["bar==4.5.6", "foo==1.2.3", "spam==0.1.0"]),
(["feature_bar"], ["bar==4.5.6", "foo==1.2.3", "spam==0.1.0"]),
],
)
def test_exporter_exports_requirements_txt_with_optional_packages(
tmp_dir, poetry, extras, lines
):
poetry.locker.mock_lock_data(
{
Expand Down Expand Up @@ -590,22 +599,16 @@ def test_exporter_exports_requirements_txt_with_optional_packages_if_opted_in(
Path(tmp_dir),
"requirements.txt",
dev=True,
extras=["feature_bar"],
with_hashes=False,
extras=extras,
)

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()

expected = """\
bar==4.5.6 \\
--hash=sha256:67890
foo==1.2.3 \\
--hash=sha256:12345
spam==0.1.0 \\
--hash=sha256:abcde
"""
expected = "\n".join(lines)

assert expected == content
assert content.strip() == expected


def test_exporter_can_export_requirements_txt_with_git_packages(tmp_dir, poetry):
Expand Down

0 comments on commit 2b6f82e

Please sign in to comment.