Skip to content

Commit ead1dfb

Browse files
authored
Handle circular dependency on root package (#121)
1 parent d920881 commit ead1dfb

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

src/poetry_plugin_export/exporter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ def _export_generic_txt(
9595
for dependency_package in get_project_dependency_packages(
9696
self._poetry.locker,
9797
project_requires=root.all_requires,
98+
root_package_name=root.name,
9899
project_python_marker=root.python_marker,
99100
extras=self._extras,
100101
):

src/poetry_plugin_export/walker.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def get_python_version_region_markers(packages: list[Package]) -> list[BaseMarke
5252
def get_project_dependency_packages(
5353
locker: Locker,
5454
project_requires: list[Dependency],
55+
root_package_name: NormalizedName,
5556
project_python_marker: BaseMarker | None = None,
5657
extras: Collection[NormalizedName] = (),
5758
) -> Iterator[DependencyPackage]:
@@ -96,13 +97,15 @@ def get_project_dependency_packages(
9697
for package, dependency in get_project_dependencies(
9798
project_requires=selected,
9899
locked_packages=repository.packages,
100+
root_package_name=root_package_name,
99101
):
100102
yield DependencyPackage(dependency=dependency, package=package)
101103

102104

103105
def get_project_dependencies(
104106
project_requires: list[Dependency],
105107
locked_packages: list[Package],
108+
root_package_name: NormalizedName,
106109
) -> Iterable[tuple[Package, Dependency]]:
107110
# group packages entries by name, this is required because requirement might use
108111
# different constraints.
@@ -122,6 +125,7 @@ def get_project_dependencies(
122125
nested_dependencies = walk_dependencies(
123126
dependencies=project_requires,
124127
packages_by_name=packages_by_name,
128+
root_package_name=root_package_name,
125129
)
126130

127131
return nested_dependencies.items()
@@ -130,6 +134,7 @@ def get_project_dependencies(
130134
def walk_dependencies(
131135
dependencies: list[Dependency],
132136
packages_by_name: dict[str, list[Package]],
137+
root_package_name: NormalizedName,
133138
) -> dict[Package, Dependency]:
134139
nested_dependencies: dict[Package, Dependency] = {}
135140

@@ -138,6 +143,8 @@ def walk_dependencies(
138143
requirement = dependencies.pop(0)
139144
if (requirement, requirement.marker) in visited:
140145
continue
146+
if requirement.name == root_package_name:
147+
continue
141148
visited.add((requirement, requirement.marker))
142149

143150
locked_package = get_locked_package(

tests/test_exporter.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,43 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_cyclic(
11151115
assert content == expected
11161116

11171117

1118+
def test_exporter_can_export_requirements_txt_with_circular_root_dependency(
1119+
tmp_path: Path, poetry: Poetry
1120+
) -> None:
1121+
poetry.locker.mock_lock_data( # type: ignore[attr-defined]
1122+
{
1123+
"package": [
1124+
{
1125+
"name": "foo",
1126+
"version": "1.2.3",
1127+
"category": "main",
1128+
"optional": False,
1129+
"python-versions": "*",
1130+
"dependencies": {poetry.package.pretty_name: {"version": "1.2.3"}},
1131+
},
1132+
],
1133+
"metadata": {
1134+
"python-versions": "*",
1135+
"content-hash": "123456789",
1136+
"files": {"foo": []},
1137+
},
1138+
}
1139+
)
1140+
set_package_requires(poetry)
1141+
1142+
exporter = Exporter(poetry, NullIO())
1143+
exporter.export("requirements.txt", tmp_path, "requirements.txt")
1144+
1145+
with (tmp_path / "requirements.txt").open(encoding="utf-8") as f:
1146+
content = f.read()
1147+
1148+
expected = f"""\
1149+
foo==1.2.3 ; {MARKER_PY}
1150+
"""
1151+
1152+
assert content == expected
1153+
1154+
11181155
def test_exporter_can_export_requirements_txt_with_nested_packages_and_multiple_markers(
11191156
tmp_path: Path, poetry: Poetry
11201157
) -> None:

0 commit comments

Comments
 (0)