Repository navigation
[regression] pip/pyproject: grouped updates collapse multiple requirements for the same package when they differ only by extras #14573
Description
Is there an existing issue for this?
- I have searched the existing issues
Package ecosystem
pip
Package manager version
pip 24.2
Language version
Python 3.11
Manifest location and content before the Dependabot update
/pyproject.toml (relevant excerpt, full flle):
requires-python = ">= 3.11, < 4"
dependencies = ["typing-extensions >= 4.13.0, < 5"]
dynamic = ["version"]
[project.optional-dependencies]
dev-flake8 = [
"flake8 == 7.3.0",
"flake8-docstrings == 1.7.0",
"flake8-pyproject == 1.2.4", # For reading the flake8 config from pyproject.toml
"pydoclint == 0.8.3",
"pydocstyle == 6.3.0",
]
dev-formatting = ["black == 25.9.0", "isort == 8.0.1"]
dev-mkdocs = [
"Markdown == 3.10.2",
"black == 25.9.0",
"mike == 2.1.4",
"mkdocs-gen-files == 0.6.1",
"mkdocs-literate-nav == 0.6.3",
"mkdocs-macros-plugin == 1.5.0",
"mkdocs-material == 9.7.6",
"mkdocstrings[python] == 1.0.3",
"mkdocstrings-python == 2.0.3",
"frequenz-repo-config[lib] == 0.14.0",
]
dev-mypy = [
"mypy == 1.19.1",
"types-Markdown == 3.10.2.20260211",
# For checking the noxfile, docs/ script, and tests
"frequenz-core[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-noxfile = ["nox == 2026.2.9", "frequenz-repo-config[lib] == 0.14.0"]
dev-pylint = [
# dev-pytest already defines a dependency to pylint because of the examples
# For checking the noxfile, docs/ script, and tests
"frequenz-core[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-pytest = [
"pytest == 9.0.2",
"pylint == 4.0.5", # We need this to check for the examples
"frequenz-repo-config[extra-lint-examples] == 0.14.0",
"pytest-mock == 3.15.1",
"pytest-asyncio == 1.3.0",
"async-solipsism == 0.9",
"hypothesis == 6.151.10",
]
dev = [
"frequenz-core[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",
]dependabot.yml content
Relevant content (full file):
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "monthly"
day: "monday"
labels:
- "part:tooling"
- "type:tech-debt"
# Default versioning-strategy. For other versioning-strategy see:
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#versioning-strategy
versioning-strategy: auto
# Allow up to 10 open pull requests for updates to dependency versions
open-pull-requests-limit: 10
# We group patch updates as they should always work.
# We also group minor updates, as it works too for most libraries,
# typically except libraries that don't have a stable release yet (v0.x.x
# branch), so we make some exceptions for them.
# Major updates and dependencies excluded by the above groups are still
# managed, but they'll create one PR per dependency, as breakage is
# expected, so it might need manual intervention.
# Finally, we group some dependencies that are related to each other, and
# usually need to be updated together.
groups:
patch:
update-types:
- "patch"
exclude-patterns:
# pydoclint has shipped breaking changes in patch updates often
- "pydoclint"
minor:
update-types:
- "minor"
exclude-patterns:
- "async-solipsism"
- "frequenz-repo-config"
- "frequenz-repo-config[lib]"
- "frequenz-repo-config[extra-lint-examples]"
- "markdown-callouts"
- "mkdocs-gen-files"
- "mkdocs-literate-nav"
- "mkdocstrings*"
- "mkdocstrings[python]"
- "pydoclint"
- "pytest-asyncio"
# We group repo-config updates as it uses optional dependencies that are
# considered different dependencies otherwise, and will create one PR for
# each if we don't group them.
repo-config:
patterns:
- "frequenz-repo-config"
- "frequenz-repo-config[lib]"
- "frequenz-repo-config[extra-lint-examples]"
mkdocstrings:
patterns:
- "mkdocstrings*"
- "mkdocstrings[python]"Updated dependency
frequenz-repo-config
What you expected to see, versus what you actually saw
This worked previously.
Before the recent Python extras handling change, Dependabot treated:
- frequenz-repo-config[api]
- frequenz-repo-config[extra-lint-examples]
as distinct direct requirements. A grouped PR was created successfully and updated both requirements together.
After the recent change that moved extras out of the Python dependency name and into metadata, Dependabot appears to collapse both requirements into the same base package identity. As a result, group matching / update selection no longer behaves correctly for requirements that differ only by extras.
Expected:
Dependabot should continue to treat multiple direct requirements for the same base package but with different extras as separately matchable requirements for grouping and updating, and should update both entries.
Actual:
Dependabot no longer updates/matches both extra-qualified requirements correctly. The behavior regressed compared to earlier runs on the same configuration.
Native package manager behavior
This does not appear to be a resolver limitation in the native tooling.
If both requirement strings are kept explicitly in pyproject.toml and updated manually, the project can still express both direct requirements separately. The regression appears to be in Dependabot's dependency identification / grouping logic after extras were moved out of the dependency name and into metadata.
Images of the diff or a link to the PR, issue, or logs
This appears to be a regression introduced after dependabot-core PR #14476 (“fix(python): Dependency name correct when extras are present”), which moved Python extras out of the dependency name and into metadata.
Before that change, Dependabot treated frequenz-repo-config[api] and frequenz-repo-config[extra-lint-examples] as distinct direct requirements and grouped/updated them correctly. After that change, Dependabot appears to collapse both entries to the same base dependency identity, which breaks grouped updates and matching for direct requirements that differ only by extras.
Related, but not identical, issue:
Working dependabot run (2 weeks ago, March 18):
- https://github.com/frequenz-floss/frequenz-client-microgrid-python/actions/runs/23051846840/job/66954766274
- frequenz-floss/frequenz-client-microgrid-python@247ccb1
Not working dependabot run:
- https://github.com/frequenz-floss/frequenz-core-python/actions/runs/23741881230/job/69160710276
- frequenz-floss/frequenz-core-python@b2eeebc (ignore the follow-up commit done by the migration automation)
Smallest manifest that reproduces the issue
Guess, not checked:
pyproject.toml
[project]
name = "dependabot-extras-repro"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"frequenz-repo-config[api]==0.13.6",
"frequenz-repo-config[extra-lint-examples]==0.13.6",
]
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"dependabot.yaml
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
groups:
repo-config:
patterns:
- "frequenz-repo-config"
- "frequenz-repo-config[api]"
- "frequenz-repo-config[extra-lint-examples]"Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
pip: fix grouped updates with multiple extras
jakecoffman commentedon Mar 31, 2026
Thanks for the detailed and timely report!
llucax commentedon Mar 31, 2026
Thanks for the quick fix. How does this normally work with GitHub deployment, when can I expect this to be rolled out in GitHub.com (if this is when the right place to ask)? Any recommendation on how to fix the existing broken PRs? Would a
@dependabot recreatecommand fix them?jakecoffman commentedon Mar 31, 2026
We deploy from branches, so once a PR is merged it is rolled out. Yes
@dependabot recreateshould fix the issue for open PRs.