Skip to content

Commit

Permalink
fix: check for mutually exclusive markers
Browse files Browse the repository at this point in the history
  • Loading branch information
ralbertazzi committed May 20, 2023
1 parent 093820a commit 27fee87
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 13 deletions.
41 changes: 38 additions & 3 deletions src/poetry/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import logging
import re

from itertools import combinations
from typing import TYPE_CHECKING
from typing import Any
from typing import cast
Expand Down Expand Up @@ -358,7 +359,15 @@ def validate(

results["errors"].extend(validate_object(config))

# A project should not depend on itself.
cls._validate_project_should_not_depend_on_itself(config, results)
cls._validate_dependencies_have_mutually_exclusive_markers(config, results)

return results

@staticmethod
def _validate_project_should_not_depend_on_itself(
config: dict[str, Any], results: dict[str, list[str]]
) -> None:
dependencies = set(config.get("dependencies", {}).keys())
dependencies.update(config.get("dev-dependencies", {}).keys())
groups = config.get("group", {}).values()
Expand All @@ -369,7 +378,33 @@ def validate(

if canonicalize_name(config["name"]) in dependencies:
results["errors"].append(
f"Project name ({config['name']}) is same as one of its dependencies"
f"Project name ({config['name']}) is same as one of its dependencies."
)

return results
@classmethod
def _validate_dependencies_have_mutually_exclusive_markers(
cls, config: dict[str, Any], results: dict[str, list[str]]
) -> None:
dep_groups = [
config.get("dependencies", {}),
config.get("dev-dependencies", {}),
*(
group.get("dependencies", {})
for group in config.get("group", {}).values()
),
]
for group in dep_groups:
for name, constraints in group.items():
if isinstance(constraints, list) and len(constraints) > 1:
deps = [
cls.create_dependency(name, constraint)
for constraint in constraints
]
if not all(
d1.marker.intersect(d2.marker).is_empty()
for d1, d2 in combinations(deps, 2)
):
results["errors"].append(
f"Dependency {name} does not have mutually exclusive"
" markers."
)
3 changes: 2 additions & 1 deletion tests/console/commands/test_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ def test_check_invalid(

expected = """\
Error: 'description' is a required property
Error: Project name (invalid) is same as one of its dependencies
Error: Project name (invalid) is same as one of its dependencies.
Error: Dependency pillow does not have mutually exclusive markers.
Error: Unrecognized classifiers: ['Intended Audience :: Clowns'].
Warning: A wildcard Python dependency is ambiguous.\
Consider specifying a more explicit one.
Expand Down
18 changes: 10 additions & 8 deletions tests/fixtures/invalid_pyproject/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
[tool.poetry]
name = "invalid"
version = "1.0.0"
authors = [
"Foo <foo@bar.com>"
]
license = "INVALID"
authors = ["Foo <foo@bar.com>"]
classifiers = [
"Environment :: Console",
"Intended Audience :: Clowns",
"Natural Language :: Ukranian",
"Topic :: Communications :: Chat :: AOL Instant Messenger",
]
license = "INVALID"
name = "invalid"
version = "1.0.0"

[tool.poetry.dependencies]
python = "*"
pendulum = {"version" = "^2.0.5", allows-prereleases = true}
invalid = "1.0"
pendulum = { "version" = "^2.0.5", allows-prereleases = true }
pillow = [
{ version = "^9", python = "^3.9" },
{ version = "^7", python = "^3.7" },
]
python = "*"
3 changes: 2 additions & 1 deletion tests/test_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,8 @@ def test_create_poetry_fails_on_invalid_configuration(
expected = """\
The Poetry configuration is invalid:
- 'description' is a required property
- Project name (invalid) is same as one of its dependencies
- Project name (invalid) is same as one of its dependencies.
- Dependency pillow does not have mutually exclusive markers.
"""
assert str(e.value) == expected

Expand Down

0 comments on commit 27fee87

Please sign in to comment.