Skip to content

Commit c0adab7

Browse files
committed
feat: parse include-groups
1 parent 142299b commit c0adab7

File tree

12 files changed

+199
-0
lines changed

12 files changed

+199
-0
lines changed

src/poetry/core/factory.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,20 @@ def _configure_package_dependencies(
350350
dependencies=group_config["dependencies"],
351351
)
352352

353+
for group_name, group_config in tool_poetry["group"].items():
354+
if include_groups := group_config.get("include-groups", []):
355+
current_group = package.dependency_group(group_name)
356+
for name in include_groups:
357+
try:
358+
group_to_include = package.dependency_group(name)
359+
except ValueError as e:
360+
raise ValueError(
361+
f"Group '{group_name}' includes group '{name}'"
362+
" which is not defined."
363+
) from e
364+
365+
current_group.include_dependency_group(group_to_include)
366+
353367
if with_groups and "dev-dependencies" in tool_poetry:
354368
cls._add_package_group_dependencies(
355369
package=package,
@@ -614,6 +628,8 @@ def validate(
614628
' Use "poetry.group.dev.dependencies" instead.'
615629
)
616630

631+
cls._validate_dependency_groups_includes(toml_data, result)
632+
617633
if strict:
618634
# Validate relation between [project] and [tool.poetry]
619635
cls._validate_legacy_vs_project(toml_data, result)
@@ -622,6 +638,33 @@ def validate(
622638

623639
return result
624640

641+
@classmethod
642+
def _validate_dependency_groups_includes(
643+
cls, toml_data: dict[str, Any], result: dict[str, list[str]]
644+
) -> None:
645+
"""Ensure that dependency groups do not include themselves."""
646+
config = toml_data.setdefault("tool", {}).setdefault("poetry", {})
647+
648+
group_includes = {}
649+
for group_name, group_config in config.get("group", {}).items():
650+
if include_groups := group_config.get("include-groups", []):
651+
group_includes[canonicalize_name(group_name)] = [
652+
canonicalize_name(name) for name in include_groups
653+
]
654+
655+
for group_name in group_includes:
656+
visited = set()
657+
stack = [group_name]
658+
while stack:
659+
group = stack.pop()
660+
if group in visited:
661+
result["errors"].append(
662+
f"Dependency group '{group}' includes itself."
663+
)
664+
continue
665+
visited.add(group)
666+
stack.extend(group_includes.get(group, []))
667+
625668
@classmethod
626669
def _validate_legacy_vs_project(
627670
cls, toml_data: dict[str, Any], result: dict[str, list[str]]

src/poetry/core/json/schemas/poetry-schema.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@
179179
"type": "boolean",
180180
"description": "Whether the dependency group is optional or not"
181181
},
182+
"include-groups": {
183+
"type": "array",
184+
"description": "List of dependency group names included in this group.",
185+
"items": {
186+
"type": "string"
187+
}
188+
},
182189
"dependencies": {
183190
"type": "object",
184191
"description": "The dependencies of this dependency group",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
My Package
2+
==========
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
[tool.poetry]
2+
name = "simple-project"
3+
version = "1.2.3"
4+
description = "Some description."
5+
authors = [
6+
"Sébastien Eustace <sebastien@eustace.io>"
7+
]
8+
license = "MIT"
9+
10+
readme = "README.rst"
11+
12+
homepage = "https://python-poetry.org"
13+
repository = "https://github.com/python-poetry/poetry"
14+
documentation = "https://python-poetry.org/docs"
15+
16+
keywords = ["packaging", "dependency", "poetry"]
17+
18+
classifiers = [
19+
"Topic :: Software Development :: Build Tools",
20+
"Topic :: Software Development :: Libraries :: Python Modules"
21+
]
22+
23+
# Requirements
24+
[tool.poetry.dependencies]
25+
python = "~2.7 || ^3.4"
26+
27+
[tool.poetry.group.testing]
28+
include-groups = [
29+
"dev",
30+
]
31+
32+
[tool.poetry.group.testing.dependencies]
33+
pytest = "*"
34+
pytest-cov ="*"
35+
36+
[tool.poetry.group.dev]
37+
include-groups = [
38+
"testing",
39+
]
40+
[tool.poetry.group.dev.dependencies]
41+
black = "*"

tests/json/__init__.py renamed to tests/fixtures/project_with_invalid_nested_groups/simple_project/__init__.py

File renamed without changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
My Package
2+
==========
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[tool.poetry]
2+
name = "simple-project"
3+
version = "1.2.3"
4+
description = "Some description."
5+
authors = [
6+
"Sébastien Eustace <sebastien@eustace.io>"
7+
]
8+
license = "MIT"
9+
10+
readme = "README.rst"
11+
12+
homepage = "https://python-poetry.org"
13+
repository = "https://github.com/python-poetry/poetry"
14+
documentation = "https://python-poetry.org/docs"
15+
16+
keywords = ["packaging", "dependency", "poetry"]
17+
18+
classifiers = [
19+
"Topic :: Software Development :: Build Tools",
20+
"Topic :: Software Development :: Libraries :: Python Modules"
21+
]
22+
23+
# Requirements
24+
[tool.poetry.dependencies]
25+
python = "~2.7 || ^3.4"
26+
27+
[tool.poetry.group.testing.dependencies]
28+
pytest = "*"
29+
pytest-cov ="*"
30+
31+
[tool.poetry.group.dev]
32+
include-groups = [
33+
"testing",
34+
]
35+
[tool.poetry.group.dev.dependencies]
36+
black = "*"

tests/fixtures/project_with_nested_groups/simple_project/__init__.py

Whitespace-only changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
My Package
2+
==========
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[tool.poetry]
2+
name = "simple-project"
3+
version = "1.2.3"
4+
description = "Some description."
5+
authors = [
6+
"Sébastien Eustace <sebastien@eustace.io>"
7+
]
8+
license = "MIT"
9+
10+
readme = "README.rst"
11+
12+
homepage = "https://python-poetry.org"
13+
repository = "https://github.com/python-poetry/poetry"
14+
documentation = "https://python-poetry.org/docs"
15+
16+
keywords = ["packaging", "dependency", "poetry"]
17+
18+
classifiers = [
19+
"Topic :: Software Development :: Build Tools",
20+
"Topic :: Software Development :: Libraries :: Python Modules"
21+
]
22+
23+
# Requirements
24+
[tool.poetry.dependencies]
25+
python = "~2.7 || ^3.4"
26+
27+
[tool.poetry.group.dev]
28+
include-groups = [
29+
"testing",
30+
]
31+
[tool.poetry.group.dev.dependencies]
32+
black = "*"

0 commit comments

Comments
 (0)