Skip to content

Self-referential extras in pyproject.toml cause pixi.lock to always appear out of date with --locked #6049

@TheSkyentist

Description

@TheSkyentist

Checks

  • I have checked that this issue has not already been reported.

  • I have confirmed this bug exists on the latest version of pixi, using pixi --version.

Reproducible example

Minimal pyproject.toml:

[project]
name = "foo"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

[project.optional-dependencies]
test = ["pytest"]
dev = ["foo[test]"]  # self-referential extra

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["foo"]

[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["osx-arm64", "linux-64"]

[tool.pixi.pypi-dependencies]
foo = { path = ".", editable = true }

[tool.pixi.environments]
dev = { features = ["dev"] }

Also create foo/__init__.py (empty).

Steps:

pixi install           # succeeds, generates pixi.lock
pixi install --locked  # fails immediately
INFO pixi_core::lock_file::outdated: the pypi dependencies of environment 'default' for platform osx-arm64 are out of date because metadata for local package 'foo' has changed: dependencies changed - added: [pytest], removed: [foo]
INFO pixi_core::lock_file::outdated: the pypi dependencies of environment 'dev' for platform osx-arm64 are out of date because metadata for local package 'foo' has changed: dependencies changed - added: [pytest], removed: [foo]
Error:   × lock-file not up-to-date with the workspace

Issue description

When a pyproject.toml has a self-referential extra (e.g. dev = ["mypackage[test]"]), pixi install generates a lockfile that immediately fails pixi install --locked. The lockfile is never valid and it fails its own --locked check right after generation. This occurs after v0.68.0.

The lock file generation and the --locked validation paths handle self-referential extras inconsistently:

  • Generation writes the self-reference verbatim:
    - foo[test] ; extra == 'dev'
  • Validation expands the self-reference to its concrete dependencies (pytest) and finds a mismatch.

Currently you can work around this by replacing self-referential extras with their concrete dependency lists in pyproject.toml.

Expected behavior

Either:

  • The lockfile stores the expanded concrete dependencies (pytest) so validation matches, or
  • The validation path preserves the self-reference and compares it verbatim

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglock filepypiIssue related to PyPI dependencies

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions