Commit a46b5c2f by Arun Babu Neelicattu Committed by finswimmer

locker: ensure correct handling of extras export

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.

(cherry picked from commit 2b6f82e9494b99bdb04d0dac90f87eb23548e4a5)
parent ed8a3f97
...@@ -318,20 +318,30 @@ class Locker(object): ...@@ -318,20 +318,30 @@ class Locker(object):
) )
) )
for dependency in self.get_project_dependencies( # If a package is optional and we haven't opted in to it, do not select
project_requires=project_requires, selected = []
locked_packages=repository.packages, for dependency in project_requires:
with_nested=True,
):
try: try:
package = repository.find_packages(dependency=dependency)[0] package = repository.find_packages(dependency=dependency)[0]
except IndexError: except IndexError:
continue continue
# If a package is optional and we haven't opted in to it, continue
if extra_package_names is not None and ( if extra_package_names is not None and (
package.optional and package.name not in extra_package_names 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 continue
for extra in dependency.extras: for extra in dependency.extras:
......
...@@ -544,8 +544,17 @@ foo==1.2.3 \\ ...@@ -544,8 +544,17 @@ foo==1.2.3 \\
assert expected == content assert expected == content
def test_exporter_exports_requirements_txt_with_optional_packages_if_opted_in( @pytest.mark.parametrize(
tmp_dir, poetry "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( poetry.locker.mock_lock_data(
{ {
...@@ -590,22 +599,16 @@ def test_exporter_exports_requirements_txt_with_optional_packages_if_opted_in( ...@@ -590,22 +599,16 @@ def test_exporter_exports_requirements_txt_with_optional_packages_if_opted_in(
Path(tmp_dir), Path(tmp_dir),
"requirements.txt", "requirements.txt",
dev=True, dev=True,
extras=["feature_bar"], with_hashes=False,
extras=extras,
) )
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read() content = f.read()
expected = """\ expected = "\n".join(lines)
bar==4.5.6 \\
--hash=sha256:67890
foo==1.2.3 \\
--hash=sha256:12345
spam==0.1.0 \\
--hash=sha256:abcde
"""
assert expected == content assert content.strip() == expected
def test_exporter_can_export_requirements_txt_with_git_packages(tmp_dir, poetry): def test_exporter_can_export_requirements_txt_with_git_packages(tmp_dir, 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