From 4d23875aa5879563b6c644e9bac499db1b28ffc4 Mon Sep 17 00:00:00 2001 From: Xuan Hu Date: Tue, 11 Mar 2025 15:13:38 +0000 Subject: [PATCH 1/6] fix: intersects with the lockfile groups to exclude the non-existing groups --- src/pdm/cli/filters.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pdm/cli/filters.py b/src/pdm/cli/filters.py index 97893d1bcf..4744c67823 100644 --- a/src/pdm/cli/filters.py +++ b/src/pdm/cli/filters.py @@ -101,6 +101,10 @@ def _translated_groups(self) -> list[str]: err=True, ) groups_set -= invalid_groups + + # Intersects with the lockfile groups to exclude the non-existing groups + groups_set &= {normalize_name(g) for g in self.project.lockfile.groups} + # Sorts the result in ascending order instead of in random order # to make this function pure result = sorted(groups_set, key=lambda x: (x != "default", x)) From ee4d7d190416e17e88970250a76923af9a02962e Mon Sep 17 00:00:00 2001 From: Xuan Hu Date: Tue, 11 Mar 2025 15:16:22 +0000 Subject: [PATCH 2/6] add news --- news/3404.bugfix.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/3404.bugfix.md diff --git a/news/3404.bugfix.md b/news/3404.bugfix.md new file mode 100644 index 0000000000..82cac526e6 --- /dev/null +++ b/news/3404.bugfix.md @@ -0,0 +1 @@ +Intersects translated groups with lockfile groups to exclude the non-existing ones. From b0a7d1d35967e08a7b8add46dddd270f4672027a Mon Sep 17 00:00:00 2001 From: Xuan Hu Date: Tue, 11 Mar 2025 15:29:47 +0000 Subject: [PATCH 3/6] add test case --- tests/cli/test_remove.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/cli/test_remove.py b/tests/cli/test_remove.py index eefe1340fa..347ceb5876 100644 --- a/tests/cli/test_remove.py +++ b/tests/cli/test_remove.py @@ -105,3 +105,11 @@ def test_remove_group_not_in_lockfile(project, pdm, mocker): pdm(["remove", "--group", "tz", "pytz"], obj=project, strict=True) assert "optional-dependencies" not in project.pyproject.metadata locker.assert_not_called() + +@pytest.mark.usefixtures("working_set") +def test_remove_exclude_non_existing_dev_group_in_lockfile(project, pdm): + pdm(["add", "requests"], obj=project, strict=True) + project.add_dependencies(["pytz"], to_group="tz", dev=True) + assert project.lockfile.groups == ["default"] + result = pdm(["remove", "requests"], obj=project) + assert result.exit_code == 0 From 4aa9d041e771284bee08ed619b7f8645192fdd11 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 15:34:27 +0000 Subject: [PATCH 4/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/cli/test_remove.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cli/test_remove.py b/tests/cli/test_remove.py index 347ceb5876..5a8b774c0c 100644 --- a/tests/cli/test_remove.py +++ b/tests/cli/test_remove.py @@ -106,6 +106,7 @@ def test_remove_group_not_in_lockfile(project, pdm, mocker): assert "optional-dependencies" not in project.pyproject.metadata locker.assert_not_called() + @pytest.mark.usefixtures("working_set") def test_remove_exclude_non_existing_dev_group_in_lockfile(project, pdm): pdm(["add", "requests"], obj=project, strict=True) From edc44adb6e2eaac9584109af05b43640974129cf Mon Sep 17 00:00:00 2001 From: Xuan Hu Date: Tue, 11 Mar 2025 15:51:01 +0000 Subject: [PATCH 5/6] fix --- news/3404.bugfix.md | 2 +- src/pdm/cli/commands/remove.py | 2 +- src/pdm/cli/filters.py | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/news/3404.bugfix.md b/news/3404.bugfix.md index 82cac526e6..4908428d93 100644 --- a/news/3404.bugfix.md +++ b/news/3404.bugfix.md @@ -1 +1 @@ -Intersects translated groups with lockfile groups to exclude the non-existing ones. +Excluding non-existing groups for `pdm remove`. diff --git a/src/pdm/cli/commands/remove.py b/src/pdm/cli/commands/remove.py index 8785a3341b..7c2d8fa6ed 100644 --- a/src/pdm/cli/commands/remove.py +++ b/src/pdm/cli/commands/remove.py @@ -125,7 +125,7 @@ def do_remove( if sync: do_sync( project, - selection=GroupSelection(project, default=False, groups=[group]), + selection=GroupSelection(project, default=False, groups=[group], exclude_non_existing=True), clean=True, no_editable=no_editable, no_self=no_self, diff --git a/src/pdm/cli/filters.py b/src/pdm/cli/filters.py index 4744c67823..2a603a4e97 100644 --- a/src/pdm/cli/filters.py +++ b/src/pdm/cli/filters.py @@ -23,6 +23,7 @@ def __init__( groups: Sequence[str] = (), group: str | None = None, excluded_groups: Sequence[str] = (), + exclude_non_existing: bool = False, ): self.project = project self.groups = groups @@ -30,6 +31,7 @@ def __init__( self.default = default self.dev = dev self.excluded_groups = excluded_groups + self.exclude_non_existing = exclude_non_existing @classmethod def from_options(cls, project: Project, options: argparse.Namespace) -> GroupSelection: @@ -102,8 +104,8 @@ def _translated_groups(self) -> list[str]: ) groups_set -= invalid_groups - # Intersects with the lockfile groups to exclude the non-existing groups - groups_set &= {normalize_name(g) for g in self.project.lockfile.groups} + if self.exclude_non_existing: + groups_set &= {normalize_name(g) for g in self.project.lockfile.groups} # Sorts the result in ascending order instead of in random order # to make this function pure From 446e38801d10632cccd5dd4acfef8e1eea143dd5 Mon Sep 17 00:00:00 2001 From: Xuan Hu Date: Tue, 11 Mar 2025 15:59:12 +0000 Subject: [PATCH 6/6] fix mypy --- src/pdm/cli/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pdm/cli/filters.py b/src/pdm/cli/filters.py index 2a603a4e97..4f9a77848c 100644 --- a/src/pdm/cli/filters.py +++ b/src/pdm/cli/filters.py @@ -104,7 +104,7 @@ def _translated_groups(self) -> list[str]: ) groups_set -= invalid_groups - if self.exclude_non_existing: + if self.exclude_non_existing and self.project.lockfile.groups is not None: groups_set &= {normalize_name(g) for g in self.project.lockfile.groups} # Sorts the result in ascending order instead of in random order