Skip to content

Commit

Permalink
Detect endless loops when processing entries where category cannot be…
Browse files Browse the repository at this point in the history
… found

Fixes: #306
  • Loading branch information
frenzymadness committed Jul 31, 2024
1 parent 465b325 commit a0cb47d
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 0 deletions.
8 changes: 8 additions & 0 deletions micropipenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,11 @@ def _poetry2pipfile_lock(

# Double-ended queue for entries
entries_queue = deque(poetry_lock["package"])
# Record of attempts of getting a category of an entry
# to potentially break endless loop caused by corrupted metadata.
# Example: a package is in poetry.lock but it's neither direct
# nor indirect dependency.
entry_category_attempts = defaultdict(int) # type: Dict[str, int]

while entries_queue:
entry = entries_queue.popleft()
Expand All @@ -837,6 +842,9 @@ def _poetry2pipfile_lock(
dev_category.add(entry["name"])
if entry["name"] not in main_category and entry["name"] not in dev_category:
# If we don't know the category yet, process the package later
entry_category_attempts[entry["name"]] += 1
if entry_category_attempts[entry["name"]] > 3:
raise PoetryError(f"Failed to find package category for: {entry['name']}")
entries_queue.append(entry)
continue

Expand Down
44 changes: 44 additions & 0 deletions tests/data/parse/poetry_endless_loop/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions tests/data/parse/poetry_endless_loop/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[tool.poetry]
name = "aaa"
version = "0.1.0"
description = ""
authors = ["Fridolin Pokorny <[email protected]>"]

[tool.poetry.dependencies]
daiquiri = "2.0.0"

[[tool.poetry.source]]
name = "PyPI"
priority = "primary"

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
8 changes: 8 additions & 0 deletions tests/test_micropipenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,14 @@ def test_parse_poetry2pipfile_source_without_url():
}


def test_parse_poetry2pipfile_causing_endless_loop():
"""Test parsing Poetry files with source without URL"""
work_dir = os.path.join(_DATA_DIR, "parse", "poetry_endless_loop")
with cwd(work_dir):
with pytest.raises(micropipenv.PoetryError, match="Failed to find package category for: flexmock"):
micropipenv._poetry2pipfile_lock()


@pytest.mark.parametrize(
"test,options,expected_file",
[
Expand Down

0 comments on commit a0cb47d

Please sign in to comment.