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