Skip to content

Support Recursive Optional Dependencies #2024

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tokoko opened this issue Sep 10, 2024 · 12 comments · May be fixed by #3646
Open

Support Recursive Optional Dependencies #2024

tokoko opened this issue Sep 10, 2024 · 12 comments · May be fixed by #3646
Labels
bug Something isn't working enhancement Feature request 🐍 pypi Issue related to PyPI dependencies

Comments

@tokoko
Copy link

tokoko commented Sep 10, 2024

Problem description

We're migrating to pyproject.toml and plan to switch to using recursive optional dependencies similar to what's described here. Seems like uv handles such dependencies correctly (during during compile and sync), but pixi update basically ignores additional extras when constructing a lock file. An example here.

@tokoko tokoko added the enhancement Feature request label Sep 10, 2024
@tdejager
Copy link
Contributor

cc @baszalmstra as you've been the pixi update frontrunner :)

@ruben-arts ruben-arts added bug Something isn't working 🐍 pypi Issue related to PyPI dependencies labels Sep 18, 2024
@ruben-arts
Copy link
Contributor

@tokoko Are you able to create a minimal reproducer?

@tokoko
Copy link
Author

tokoko commented Sep 20, 2024

@ruben-arts sure, I tested with the following just now:

[project]
name = "example"

[project.optional-dependencies]
np = [
  "numpy",
]

all = [
    "example[np]"
]

[tool.pixi.project]
channels = ["conda-forge"]
platforms = ["linux-64"]

[tool.pixi.environments]
np = {features = ["np"]}
all = {features = ["all"]}

I'm able to run pixi run -e np python -c "import numpy" just fine, but when I try pixi run -e all python -c "import numpy" I'm getting No module named 'numpy' error.

Here's the output from uv compile command (uv pip compile --extra all pyproject.toml):

# This file was autogenerated by uv via the following command:
#    uv pip compile --extra all pyproject.toml
numpy==2.0.2
    # via example (pyproject.toml)

Hope this helps

@ruben-arts
Copy link
Contributor

Thank you, I would like to ask @tdejager for his input as this is a use-case I'm not sure we have tried to support yet.

@olivier-lacroix
Copy link
Contributor

olivier-lacroix commented Oct 2, 2024

Thanks @tokoko for the example.

@ruben-arts @tdejager pixi init handles that case by resolving the recursion and writing

[tool.pixi.environments]
np = {features = ["np"]}
all = {features = ["all","np"]}

I am not sure this is fixable / should be fixed. This comes from the recursive nature of pyproject extras, versus the distinction in pixi between features and environments.

A middle ground may be to issue a warning during the parsing of the pyproject.toml in that case, hinting at adding the feature to the environment manually

@ruben-arts
Copy link
Contributor

@olivier-lacroix Thanks for jumping in! Could we support it by just simply making it understand "self" and in the example case result in skipping example[np] in the dependency list?

@olivier-lacroix
Copy link
Contributor

olivier-lacroix commented Oct 3, 2024

It is indeed what happens currently. example[np] is skipped.

And the np dependencies will only be considered if the feature is added to an environment.

@baszalmstra baszalmstra added the pixi label Mar 27, 2025 — with Linear
@baszalmstra baszalmstra removed the pixi label Apr 1, 2025
@dhirschfeld
Copy link
Contributor

I want to start using pixi for existing repos, using the pyproject.toml support but I'm running into this problem also.

All of our pyproject.toml files make heavy use of recursive optional dependencies to keep our deps DRY e.g.

dev = [
  "myproject[docs]",
  "myproject[lint]",
  "myproject[test]",
  "other-dep>=1.0",
]

This will unfortunately be a blocker for adoption. I can fix up the environments in my own repos but your average analyst here wouldn't have the necessary skills/knowledge (yet) 😞.

@tdejager
Copy link
Contributor

tdejager commented Apr 7, 2025

@dhirschfeld ah that's unfortunate :(. Would dependency groups make sense for your use case? https://packaging.python.org/en/latest/specifications/dependency-groups/

@dhirschfeld
Copy link
Contributor

Would dependency groups make sense for your use case?

I'm not sure - I've never used them! 🤔

I'm not too sure of the motivation for dependency groups as it seems to just duplicate the recursive optional dependency functionality?

...but it seems more limited in that it can only be a collection of existing groups?

As shown in the example above, my extras are combinations of existing extras plus other packages.

Also, I'd like the extras to be installable - that doesn't seem possible with dependency groups?

There is no syntax or specification-defined interface for installing or referring to Dependency Groups. Tools are expected to provide dedicated interfaces for this purpose.

Finally, I will need my projects to be usable by both pip and pixi. The magic of pixi's pyproject.toml integration makes that possible - pip install -e .[test] works equally well as pixi shell -e test with no need to separately maintain dependencies for each tool... except for this issue.

@olivier-lacroix
Copy link
Contributor

olivier-lacroix commented Apr 7, 2025

@dhirschfeld handling recursive extras would be possible indeed. In the meantime, you can use pixi init / replicate its behaviour by adding the various needed features to each environment. that is, in your case:

dev = ["dev", "docs", "lint", "test"]

@dhirschfeld
Copy link
Contributor

That's what I'm doing for now.

It's actually working fine, as 90% of repos don't define their own custom extras groups and the owners of repos which do define custom extras groups are usually sophisticated enough to fix up their default pixi config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement Feature request 🐍 pypi Issue related to PyPI dependencies
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants