-
Notifications
You must be signed in to change notification settings - Fork 495
fix: fallback to pypi when removing deps without --pypi flag #5794
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
base: main
Are you sure you want to change the base?
Changes from all commits
1e0f369
092ec95
7ed52d5
c3c0aaa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,6 +2,7 @@ use clap::Parser; | |||||||||||||||||||||||||||||||||||
| use pixi_api::{WorkspaceContext, workspace::DependencyOptions}; | ||||||||||||||||||||||||||||||||||||
| use pixi_config::ConfigCli; | ||||||||||||||||||||||||||||||||||||
| use pixi_core::{DependencyType, WorkspaceLocator}; | ||||||||||||||||||||||||||||||||||||
| use pixi_manifest::{FeaturesExt, SpecType}; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| use crate::{cli_config::LockFileUpdateConfig, has_specs::HasSpecs}; | ||||||||||||||||||||||||||||||||||||
| use crate::{ | ||||||||||||||||||||||||||||||||||||
|
|
@@ -58,7 +59,33 @@ pub async fn execute(args: Args) -> miette::Result<()> { | |||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| let workspace_ctx = WorkspaceContext::new(CliInterface {}, workspace.clone()); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| match args.dependency_config.dependency_type() { | ||||||||||||||||||||||||||||||||||||
| let mut dep_type = args.dependency_config.dependency_type(); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Fall back to pypi removal if deps aren't found in conda. | ||||||||||||||||||||||||||||||||||||
| // Only when no explicit type flag (--host, --build) was passed. | ||||||||||||||||||||||||||||||||||||
| if matches!(dep_type, DependencyType::CondaDependency(SpecType::Run)) { | ||||||||||||||||||||||||||||||||||||
| let spec_type = SpecType::Run; | ||||||||||||||||||||||||||||||||||||
| let specs = args.dependency_config.specs()?; | ||||||||||||||||||||||||||||||||||||
| let env = workspace.default_environment(); | ||||||||||||||||||||||||||||||||||||
| 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); | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+70
to
+75
|
||||||||||||||||||||||||||||||||||||
| 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); |
Copilot
AI
Mar 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 thespecsmap to avoid duplicate work and keep the control flow simpler.