From 076b9fb8acd8c113fdcd7f408676019fccab4295 Mon Sep 17 00:00:00 2001
From: Stefano Rivera <stefano@rivera.za.net>
Date: Mon, 5 May 2025 15:58:22 -0400
Subject: [PATCH] New upstream version 1.3.1
---
CHANGELOG.rst | 7 +++++++
PKG-INFO | 10 ++++++----
pyproject.toml | 11 ++++++-----
src/dependency_groups/_implementation.py | 18 +++++++-----------
tests/test_resolver_class.py | 18 ++++++++++++++++++
5 files changed, 44 insertions(+), 20 deletions(-)
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 5d72c25..0ff7653 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -4,6 +4,13 @@ CHANGELOG
Unreleased
----------
+1.3.1
+-----
+
+- Fix a bug in which names in includes were not normalized before comparisons,
+ resulting in spurious ``LookupError``\s.
+- Optimize the behavior of the ``resolve()`` function on multiple groups.
+
1.3.0
-----
diff --git a/PKG-INFO b/PKG-INFO
index 071fbb9..1ee91d7 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,11 +1,12 @@
-Metadata-Version: 2.3
+Metadata-Version: 2.4
Name: dependency-groups
-Version: 1.3.0
+Version: 1.3.1
Summary: A tool for resolving PEP 735 Dependency Group data
Keywords:
Author-email: Stephen Rosen <sirosen0@gmail.com>
Requires-Python: >=3.8
Description-Content-Type: text/x-rst
+License-Expression: MIT
Classifier: Development Status :: 5 - Production/Stable
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.8
@@ -16,12 +17,13 @@ Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
+License-File: LICENSE.txt
Requires-Dist: packaging
Requires-Dist: tomli;python_version<'3.11'
Requires-Dist: tomli ; extra == "cli" and ( python_version<'3.11')
-Project-URL: changelog, https://github.com/sirosen/dependency-groups/blob/main/CHANGELOG.rst
+Project-URL: changelog, https://github.com/pypa/dependency-groups/blob/main/CHANGELOG.rst
Project-URL: documentation, https://dependency-groups.readthedocs.io/
-Project-URL: source, https://github.com/sirosen/dependency-groups
+Project-URL: source, https://github.com/pypa/dependency-groups
Provides-Extra: cli
Dependency Groups
diff --git a/pyproject.toml b/pyproject.toml
index db86f49..30cd8f5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,5 +1,5 @@
[build-system]
-requires = ["flit-core"]
+requires = ["flit-core>=3.11"]
build-backend = "flit_core.buildapi"
[dependency-groups]
@@ -13,11 +13,12 @@ dev = [{include-group = "test"}]
[project]
name = "dependency-groups"
-version = "1.3.0"
+version = "1.3.1"
description = 'A tool for resolving PEP 735 Dependency Group data'
readme = "README.rst"
requires-python = ">=3.8"
-license = { text = "MIT" }
+license = "MIT"
+license-files = ["LICENSE.txt"]
keywords = []
authors = [
{ name = "Stephen Rosen", email = "sirosen0@gmail.com" },
@@ -48,8 +49,8 @@ dependency-groups = "dependency_groups.__main__:main"
cli = ["tomli; python_version<'3.11'"]
[project.urls]
-source = "https://github.com/sirosen/dependency-groups"
-changelog = "https://github.com/sirosen/dependency-groups/blob/main/CHANGELOG.rst"
+source = "https://github.com/pypa/dependency-groups"
+changelog = "https://github.com/pypa/dependency-groups/blob/main/CHANGELOG.rst"
documentation = "https://dependency-groups.readthedocs.io/"
diff --git a/src/dependency_groups/_implementation.py b/src/dependency_groups/_implementation.py
index cdaa661..c89edaf 100644
--- a/src/dependency_groups/_implementation.py
+++ b/src/dependency_groups/_implementation.py
@@ -12,7 +12,7 @@ def _normalize_name(name: str) -> str:
def _normalize_group_names(
- dependency_groups: Mapping[str, str | Mapping[str, str]]
+ dependency_groups: Mapping[str, str | Mapping[str, str]],
) -> Mapping[str, str | Mapping[str, str]]:
original_names: dict[str, list[str]] = {}
normalized_groups = {}
@@ -171,17 +171,16 @@ class DependencyGroupResolver:
if isinstance(item, Requirement):
resolved_group.append(item)
elif isinstance(item, DependencyGroupInclude):
- if item.include_group in self._include_graph_ancestors.get(group, ()):
+ include_group = _normalize_name(item.include_group)
+ if include_group in self._include_graph_ancestors.get(group, ()):
raise CyclicDependencyError(
requested_group, group, item.include_group
)
- self._include_graph_ancestors[item.include_group] = (
+ self._include_graph_ancestors[include_group] = (
*self._include_graph_ancestors.get(group, ()),
group,
)
- resolved_group.extend(
- self._resolve(item.include_group, requested_group)
- )
+ resolved_group.extend(self._resolve(include_group, requested_group))
else: # unreachable
raise NotImplementedError(
f"Invalid dependency group item after parse: {item}"
@@ -206,8 +205,5 @@ def resolve(
:raises LookupError: if group name is absent
:raises packaging.requirements.InvalidRequirement: if a specifier is not valid
"""
- return tuple(
- str(r)
- for group in groups
- for r in DependencyGroupResolver(dependency_groups).resolve(group)
- )
+ resolver = DependencyGroupResolver(dependency_groups)
+ return tuple(str(r) for group in groups for r in resolver.resolve(group))
diff --git a/tests/test_resolver_class.py b/tests/test_resolver_class.py
index 8141e07..5a3daad 100644
--- a/tests/test_resolver_class.py
+++ b/tests/test_resolver_class.py
@@ -127,3 +127,21 @@ def test_no_double_parse():
assert len(deceived_parse) == 1
assert isinstance(deceived_parse[0], DependencyGroupInclude)
assert deceived_parse[0].include_group == "perfidy"
+
+
+@pytest.mark.parametrize("group_name_declared", ("foo-bar", "foo_bar", "foo..bar"))
+@pytest.mark.parametrize("group_name_used", ("foo-bar", "foo_bar", "foo..bar"))
+def test_normalized_name_is_used_for_include_group_lookups(
+ group_name_declared, group_name_used
+):
+ groups = {
+ group_name_declared: ["spam"],
+ "eggs": [{"include-group": group_name_used}],
+ }
+ resolver = DependencyGroupResolver(groups)
+
+ result = resolver.resolve("eggs")
+ assert len(result) == 1
+ assert isinstance(result[0], Requirement)
+ req = result[0]
+ assert req.name == "spam"
--
GitLab