Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0ecc9de
Fix add_pip_as_python_dependency not respected with sharded repodata
danyeaw Apr 30, 2026
526236d
Update news
danyeaw Apr 30, 2026
2b0405b
Merge branch 'main' into fix-pip-sharded
danyeaw Apr 30, 2026
5152259
Simplify test
danyeaw Apr 30, 2026
d9fc542
Use spec_to_package_name to find pip depends
danyeaw Apr 30, 2026
abb7bed
Fix AssertionError on Windows
danyeaw Apr 30, 2026
411f8f4
Merge branch 'main' into fix-pip-sharded
dholth Apr 30, 2026
0f556ca
install test dependencies with canary conda-libmamba-solver
dholth May 1, 2026
01bd72c
use bash -el {0}
dholth May 1, 2026
662b3e9
Merge branch '926-tests-vs-canary' into fix-pip-sharded
dholth May 1, 2026
d511135
Fix test_add_pip_as_python_dependency_sharded CI failure
dholth May 1, 2026
1e6e9f2
Use current subdir in tests
danyeaw May 1, 2026
25d1bb9
Add context verification assertion to test_add_pip_as_python_dependen…
dholth May 1, 2026
d96ab40
Add package record verification assertions
dholth May 1, 2026
b724f12
run failing test only
dholth May 1, 2026
8387925
revert focused test run
dholth May 1, 2026
7ac2b01
add pip as python dependency during traversal
dholth May 1, 2026
533d5a9
Use shard_mentioned_packages extra parameter for pip dependency
dholth May 1, 2026
cca8afa
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 1, 2026
f54e8bf
Fix shard_mentioned_packages has no keyword extra
danyeaw May 1, 2026
9a11798
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 1, 2026
57934f7
add pip to python dependencies when adding to libmamba
dholth May 1, 2026
3cccce7
a sorted dependency
dholth May 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ jobs:
condarc-file: conda\.github\condarc-${{ matrix.default-channel }}
run-post: false # skip post cleanup

- name: Upgrade conda-libmamba-solver (without sharded repodata)
shell: bash -el {0}
run: CONDA_PLUGINS_USE_SHARDED_REPODATA=0 conda install --yes -n base conda-canary/label/dev::conda-libmamba-solver

- name: Conda Install
working-directory: conda # CONDA-LIBMAMBA-SOLVER CHANGE
# CONDA-LIBMAMBA-SOLVER CHANGE: add conda-libmamba-solver requirements.txt
Expand Down Expand Up @@ -306,6 +310,9 @@ jobs:
condarc-file: conda/.github/condarc-${{ matrix.default-channel }}
run-post: false # skip post cleanup

- name: Upgrade conda-libmamba-solver (without sharded repodata)
run: CONDA_PLUGINS_USE_SHARDED_REPODATA=0 conda install --yes -n base conda-canary/label/dev::conda-libmamba-solver

- name: Conda Install
working-directory: conda
run: >
Expand Down Expand Up @@ -582,6 +589,9 @@ jobs:
miniforge-version: ${{ (matrix.default-channel == 'conda-forge' && matrix.arch == 'osx-64') && 'latest' || null }}
architecture: ${{ runner.arch }}

- name: Upgrade conda-libmamba-solver (without sharded repodata)
run: CONDA_PLUGINS_USE_SHARDED_REPODATA=0 conda install --yes -n base conda-canary/label/dev::conda-libmamba-solver

- name: Conda Install
working-directory: conda # CONDA-LIBMAMBA-SOLVER CHANGE
# CONDA-LIBMAMBA-SOLVER CHANGE: add conda-libmamba-solver requirements.txt
Expand Down
28 changes: 25 additions & 3 deletions conda_libmamba_solver/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,11 @@ def _is_sharded_repodata_enabled():


def _package_info_from_package_dict(
record: PackageRecordDict, filename: str, url: str, channel_id: str
record: PackageRecordDict,
filename: str,
url: str,
channel_id: str,
add_pip_as_python_dependency=False,
) -> PackageInfo:
"""
Build libmamba PackageInfo from an unprocessed repodata "packages", "packages.conda" entry.
Expand Down Expand Up @@ -193,6 +197,16 @@ def _package_info_from_package_dict(
if track_features and isinstance(track_features, str):
track_features = track_features.replace(" ", ",").split(",")
track_features = list(f for f in (ff.strip() for ff in track_features) if f)

# Build depends list and append pip if conditions are met
depends = list(record.get("depends") or [])
if (
add_pip_as_python_dependency
and record["name"] == "python"
and record["version"].startswith(("2.", "3."))
):
depends.append("pip")

return PackageInfo(
name=record["name"],
version=record["version"],
Expand All @@ -208,7 +222,7 @@ def _package_info_from_package_dict(
signatures=record.get("signatures") or "",
track_features=track_features,
# conda can have list or tuple, but libmamba only accepts lists
depends=list(record.get("depends") or []),
depends=depends,
constrains=list(record.get("constrains") or []),
defaulted_keys=list(record.get("defaulted_keys") or []),
noarch=noarch,
Expand Down Expand Up @@ -257,6 +271,7 @@ def __init__(
self.subdirs = subdirs or context.subdirs
self.repodata_fn = repodata_fn
self.in_state = in_state
self._add_pip_as_python_dependency = context.add_pip_as_python_dependency
self.db = self._init_db()

self.repos: list[_ChannelRepoInfo] = self._load_channels()
Expand Down Expand Up @@ -641,10 +656,17 @@ def _load_repo_info_from_repodata_dict(
filename,
url=f"{base_url}{filename}",
channel_id=channel_id,
add_pip_as_python_dependency=self._add_pip_as_python_dependency,
)
packages.append(package)

repo = self.db.add_repo_from_packages(packages=packages, name=channel_url)
repo = self.db.add_repo_from_packages(
packages=packages,
name=channel_url,
add_pip_as_python_dependency=PipAsPythonDependency(
context.add_pip_as_python_dependency
),
)
repos.append(
_ChannelRepoInfo(
channel=channel_object,
Expand Down
5 changes: 3 additions & 2 deletions conda_libmamba_solver/shards.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@ def spec_to_package_name(spec: str) -> str:
return name


def shard_mentioned_packages(shard: ShardDict) -> Iterable[str]:
def shard_mentioned_packages(shard: ShardDict, extra: Iterable[str] = ()) -> Iterable[str]:
"""
Return all dependency names mentioned in a shard, not including the shard's
own package name.
own package name. Additional names can be injected via ``extra``.
"""
unique_specs = set()
for package in (*shard["packages"].values(), *shard["packages.conda"].values()):
Expand All @@ -152,6 +152,7 @@ def shard_mentioned_packages(shard: ShardDict) -> Iterable[str]:
unique_specs.add(spec)
name = spec_to_package_name(spec)
yield name # not much improvement from only yielding unique names
yield from extra


class ShardBase(abc.ABC):
Expand Down
17 changes: 15 additions & 2 deletions conda_libmamba_solver/shards_subset.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ def __init__(self, shardlikes: Iterable[ShardBase]):
self.nodes = {}
self.shardlikes = list(shardlikes)
self._use_only_tar_bz2 = context.use_only_tar_bz2
self._add_pip_as_python_dependency = context.add_pip_as_python_dependency

@classmethod
def has_strategy(cls, strategy: str) -> bool:
Expand Down Expand Up @@ -217,7 +218,11 @@ def neighbors(self, node: Node) -> Iterator[Node]:
shard = filter_redundant_packages(shard, self._use_only_tar_bz2)
shardlike.visit_shard(node.package, shard)

for package in shard_mentioned_packages(shard):
# ensure solver has "pip" record if add_pip_as_python_dependency:
extra = (
("pip",) if self._add_pip_as_python_dependency and node.package == "python" else ()
)
for package in shard_mentioned_packages(shard, extra=extra):
node_id = NodeId(package, shardlike.url)

if node_id not in self.nodes:
Expand Down Expand Up @@ -449,7 +454,15 @@ def log_timeout():
shardlike = shardlikes_by_url[node_id.channel]
shardlike.visit_shard(node_id.package, shard)

pending.update(self.visit_node(parent_node, shard_mentioned_packages(shard)))
# ensure solver has "pip" record if add_pip_as_python_dependency:
extra = (
("pip",)
if self._add_pip_as_python_dependency and parent_node.package == "python"
else ()
)
pending.update(
self.visit_node(parent_node, shard_mentioned_packages(shard, extra=extra))
)

def visit_node(self, parent_node: Node, mentioned_packages: Iterable[str]) -> Iterable[NodeId]:
"""Broadcast mentioned packages across channels. yield pending NodeId's."""
Expand Down
20 changes: 20 additions & 0 deletions news/918-fix-add-pip-as-python-dependency-sharded
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
### Enhancements

* <news item>

### Bug fixes

* Fix `add_pip_as_python_dependency` not being honored when sharded repodata
is enabled. (#918 via #929)

### Deprecations

* <news item>

### Docs

* <news item>

### Other

* <news item>
Loading
Loading