fix: fallback to pypi when removing deps without --pypi flag#5794
fix: fallback to pypi when removing deps without --pypi flag#5794theycallmeaabie wants to merge 4 commits intoprefix-dev:mainfrom
Conversation
Signed-off-by: theycallmeaabie <theycallmeaabie@gmail.com>
There was a problem hiding this comment.
Pull request overview
Adjusts pixi remove to better handle dependencies originally added from PyPI when the user omits --pypi, avoiding the misleading “doesn’t exist” warning and ensuring the correct dependency type is reported in the success output.
Changes:
- Add a fallback in
removeto check PyPI dependencies when a dependency is not found as a conda dependency. - Thread the resolved dependency type through the success output to print the correct “Removed these as …” message.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| crates/pixi_cli/src/remove.rs | Adds conda→PyPI fallback detection and passes the resolved dependency type to the success display. |
| crates/pixi_cli/src/cli_config.rs | Introduces display_success_with_type so callers can print success messages using an explicit dependency type. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let conda_deps = env.dependencies(spec_type, None); | ||
|
|
||
| let all_missing_from_conda = specs | ||
| .keys() | ||
| .all(|name| !conda_deps.contains_key(name)); | ||
|
|
||
| if all_missing_from_conda { | ||
| let pypi_deps = env.pypi_dependencies(None); |
There was a problem hiding this comment.
The fallback detection uses env.dependencies(spec_type, None) / env.pypi_dependencies(None), which merges across all features in the environment and ignores args.dependency_config.platforms and the selected feature. Since the actual removal uses DependencyOptions (feature + platforms), this can prevent fallback (or trigger it incorrectly) for feature/platform-specific removals. Consider checking presence in the exact target(s) being modified instead.
| let conda_deps = env.dependencies(spec_type, None); | |
| let all_missing_from_conda = specs | |
| .keys() | |
| .all(|name| !conda_deps.contains_key(name)); | |
| if all_missing_from_conda { | |
| let pypi_deps = env.pypi_dependencies(None); | |
| let feature = args.dependency_config.feature.as_deref(); | |
| let conda_deps = env.dependencies(spec_type, feature); | |
| let all_missing_from_conda = specs | |
| .keys() | |
| .all(|name| !conda_deps.contains_key(name)); | |
| if all_missing_from_conda { | |
| let pypi_deps = env.pypi_dependencies(feature); |
| let any_in_pypi = specs.keys().any(|name| { | ||
| pypi_deps | ||
| .names() | ||
| .any(|pypi_name| pypi_name.as_source() == name.as_source()) |
There was a problem hiding this comment.
PyPI presence is detected by comparing pypi_name.as_source() to name.as_source(). as_source() preserves the original string and won’t match common normalized equivalents (e.g. foo-bar vs foo_bar, case differences), so the fallback may fail even when the PyPI dep exists. Prefer comparing normalized forms (e.g. pypi_name.as_normalized() vs a normalized name derived from the input) or using contains_key/get on the PyPI dependency map with an appropriate normalized key type.
| .any(|pypi_name| pypi_name.as_source() == name.as_source()) | |
| .any(|pypi_name| pypi_name.as_normalized() == name.as_normalized()) |
| let all_missing_from_conda = specs | ||
| .keys() | ||
| .all(|name| !conda_deps.contains_key(name)); | ||
|
|
||
| if all_missing_from_conda { |
There was a problem hiding this comment.
Fallback only triggers when all requested specs are missing from conda (all_missing_from_conda). If the user removes multiple packages and some are conda while others are PyPI-only, the PyPI-only ones will still hit the old confusing behavior. If the intended behavior is “for each spec, if it’s not a conda dep, try PyPI before warning”, this logic will need to be per-package (or split the remove into conda + PyPI subsets).
| let specs = args.dependency_config.specs()?; | ||
| let env = workspace.default_environment(); | ||
| let conda_deps = env.dependencies(spec_type, None); |
There was a problem hiding this comment.
args.dependency_config.specs()? is parsed here for the fallback check and then parsed again in the conda removal branch. Consider parsing once and reusing the specs map to avoid duplicate work and keep the control flow simpler.
Signed-off-by: theycallmeaabie <theycallmeaabie@gmail.com>
Signed-off-by: theycallmeaabie <theycallmeaabie@gmail.com>
Signed-off-by: theycallmeaabie <theycallmeaabie@gmail.com>
|
Hey @ruben-arts, please take a look, lemme know if you would prefer something changed. |
Description
When a user adds a pypi dependency (e.g.,
pixi add gym==0.26.2 --pypi) and later runspixi remove gymwithout the--pypiflag, the command would silently warn "Dependencygymdoesn't exist" and remove nothing.This PR adds a fallback: if the package isn't found in conda dependencies, the remove command checks pypi dependencies before giving up. If found there, it removes it as a pypi dependency and displays the correct output.
Before:
$ pixi add gym==0.26.2 --pypi
✔ Added gym==0.26.2
$ pixi remove gym
WARN Dependency gym doesn't exist
✔ Removed gym
After:
$ pixi add gym==0.26.2 --pypi
✔ Added gym==0.26.2
$ pixi remove gym
✔ Removed gym
Removed these as pypi-dependencies.
Fixes #1567
How Has This Been Tested?
cargo check -p pixi_cli: compiles cleancargo test -p pixi_cli:41 passed, 0 failedcargo clippy -p pixi_cli: no warningsChecklist:
schema/model.py.