Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle circular dependencies when getting extras #2787

Merged
merged 1 commit into from
Aug 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions poetry/utils/extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ def get_extra_package_names(
for extra_package_name in extras.get(extra_name, ())
]

# keep record of packages seen during recursion in order to avoid recursion error
seen_package_names = set()

def _extra_packages(package_names):
"""Recursively find dependencies for packages names"""
# for each extra pacakge name
Expand All @@ -41,11 +44,16 @@ def _extra_packages(package_names):
# dependency (like setuptools), which should be ignored
package = packages_by_name.get(canonicalize_name(package_name))
if package:
yield package.name
if package.name not in seen_package_names:
seen_package_names.add(package.name)
yield package.name
# Recurse for dependencies
for dependency_package_name in _extra_packages(
dependency.name for dependency in package.requires
dependency.name
for dependency in package.requires
if dependency.name not in seen_package_names
):
seen_package_names.add(dependency_package_name)
yield dependency_package_name

return _extra_packages(extra_package_names)
12 changes: 12 additions & 0 deletions tests/utils/test_extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
_PACKAGE_BAR = Package("bar", "0.3.0")
_PACKAGE_BAR.add_dependency("foo")

# recursive dependency
_PACKAGE_BAZ = Package("baz", "0.4.0")
_PACKAGE_BAZ.add_dependency("quix")
_PACKAGE_QUIX = Package("quix", "0.5.0")
_PACKAGE_QUIX.add_dependency("baz")


@pytest.mark.parametrize(
"packages,extras,extra_names,expected_extra_package_names",
Expand Down Expand Up @@ -40,6 +46,12 @@
["group0", "group1"],
["bar", "foo", "spam"],
),
(
[_PACKAGE_BAZ, _PACKAGE_QUIX],
{"group0": ["baz"], "group1": ["quix"]},
["group0", "group1"],
["baz", "quix"],
),
],
)
def test_get_extra_package_names(
Expand Down