Skip to content

Commit

Permalink
add source validation in poetry check (python-poetry#8709)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucemia authored Dec 11, 2023
1 parent f060549 commit f310a59
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/poetry/console/commands/check.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

from typing import TYPE_CHECKING
from typing import Any

from cleo.helpers import option

Expand Down Expand Up @@ -88,6 +89,37 @@ def _validate_readme(self, readme: str | list[str], poetry_file: Path) -> list[s
errors.append(f"Declared README file does not exist: {name}")
return errors

def _validate_dependencies_source(self, config: dict[str, Any]) -> list[str]:
"""Check dependencies's source are valid"""
sources = {k["name"] for k in config.get("source", [])}

dependency_declarations: list[
dict[str, str | dict[str, str] | list[dict[str, str]]]
] = []
# scan dependencies and group dependencies settings in pyproject.toml
if "dependencies" in config:
dependency_declarations.append(config["dependencies"])

for group in config.get("group", {}).values():
if "dependencies" in group:
dependency_declarations.append(group["dependencies"])

all_referenced_sources: set[str] = set()

for dependency_declaration in dependency_declarations:
for declaration in dependency_declaration.values():
if isinstance(declaration, list):
for item in declaration:
if "source" in item:
all_referenced_sources.add(item["source"])
elif isinstance(declaration, dict) and "source" in declaration:
all_referenced_sources.add(declaration["source"])

return [
f'Invalid source "{source}" referenced in dependencies.'
for source in sorted(all_referenced_sources - sources)
]

def handle(self) -> int:
from poetry.factory import Factory
from poetry.pyproject.toml import PyProjectTOML
Expand All @@ -108,6 +140,8 @@ def handle(self) -> int:
errors = self._validate_readme(config["readme"], poetry_file)
check_result["errors"].extend(errors)

check_result["errors"] += self._validate_dependencies_source(config)

# Verify that lock file is consistent
if self.option("lock") and not self.poetry.locker.is_locked():
check_result["errors"] += ["poetry.lock was not found."]
Expand Down
2 changes: 2 additions & 0 deletions tests/console/commands/test_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ def test_check_invalid(
Error: Project name (invalid) is same as one of its dependencies
Error: Unrecognized classifiers: ['Intended Audience :: Clowns'].
Error: Declared README file does not exist: never/exists.md
Error: Invalid source "not-exists" referenced in dependencies.
Error: Invalid source "not-exists2" referenced in dependencies.
Error: poetry.lock was not found.
Warning: A wildcard Python dependency is ambiguous.\
Consider specifying a more explicit one.
Expand Down
9 changes: 9 additions & 0 deletions tests/fixtures/invalid_pyproject/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,12 @@ classifiers = [
python = "*"
pendulum = {"version" = "^2.0.5", allows-prereleases = true}
invalid = "1.0"
invalid_source = { "version" = "*", source = "not-exists" }
invalid_source_multi = [
{ "version" = "*", platform = "linux", source = "exists" },
{ "version" = "*", platform = "win32", source = "not-exists2" },
]

[[tool.poetry.source]]
name = "exists"
priority = "explicit"

0 comments on commit f310a59

Please sign in to comment.