123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- # Copyright (C) 2012 Anaconda, Inc
- # SPDX-License-Identifier: BSD-3-Clause
- from .base.constants import DepsModifier as _DepsModifier
- from .base.constants import UpdateModifier as _UpdateModifier
- from .base.context import context
- from .common.constants import NULL
- from .core.package_cache_data import PackageCacheData as _PackageCacheData
- from .core.prefix_data import PrefixData as _PrefixData
- from .core.subdir_data import SubdirData as _SubdirData
- from .models.channel import Channel
- DepsModifier = _DepsModifier
- """Flags to enable alternate handling of dependencies."""
- UpdateModifier = _UpdateModifier
- """Flags to enable alternate handling for updates of existing packages in the environment."""
- class Solver:
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- A high-level API to conda's solving logic. Three public methods are provided to access a
- solution in various forms.
- * :meth:`solve_final_state`
- * :meth:`solve_for_diff`
- * :meth:`solve_for_transaction`
- """
- def __init__(
- self, prefix, channels, subdirs=(), specs_to_add=(), specs_to_remove=()
- ):
- """
- **Beta**
- Args:
- prefix (str):
- The conda prefix / environment location for which the :class:`Solver`
- is being instantiated.
- channels (Sequence[:class:`Channel`]):
- A prioritized list of channels to use for the solution.
- subdirs (Sequence[str]):
- A prioritized list of subdirs to use for the solution.
- specs_to_add (set[:class:`MatchSpec`]):
- The set of package specs to add to the prefix.
- specs_to_remove (set[:class:`MatchSpec`]):
- The set of package specs to remove from the prefix.
- """
- solver_backend = context.plugin_manager.get_cached_solver_backend()
- self._internal = solver_backend(
- prefix, channels, subdirs, specs_to_add, specs_to_remove
- )
- def solve_final_state(
- self,
- update_modifier=NULL,
- deps_modifier=NULL,
- prune=NULL,
- ignore_pinned=NULL,
- force_remove=NULL,
- ):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Gives the final, solved state of the environment.
- Args:
- deps_modifier (DepsModifier):
- An optional flag indicating special solver handling for dependencies. The
- default solver behavior is to be as conservative as possible with dependency
- updates (in the case the dependency already exists in the environment), while
- still ensuring all dependencies are satisfied. Options include
- * NO_DEPS
- * ONLY_DEPS
- * UPDATE_DEPS
- * UPDATE_DEPS_ONLY_DEPS
- * FREEZE_INSTALLED
- prune (bool):
- If ``True``, the solution will not contain packages that were
- previously brought into the environment as dependencies but are no longer
- required as dependencies and are not user-requested.
- ignore_pinned (bool):
- If ``True``, the solution will ignore pinned package configuration
- for the prefix.
- force_remove (bool):
- Forces removal of a package without removing packages that depend on it.
- Returns:
- tuple[PackageRef]:
- In sorted dependency order from roots to leaves, the package references for
- the solved state of the environment.
- """
- return self._internal.solve_final_state(
- update_modifier, deps_modifier, prune, ignore_pinned, force_remove
- )
- def solve_for_diff(
- self,
- update_modifier=NULL,
- deps_modifier=NULL,
- prune=NULL,
- ignore_pinned=NULL,
- force_remove=NULL,
- force_reinstall=False,
- ):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Gives the package references to remove from an environment, followed by
- the package references to add to an environment.
- Args:
- deps_modifier (DepsModifier):
- See :meth:`solve_final_state`.
- prune (bool):
- See :meth:`solve_final_state`.
- ignore_pinned (bool):
- See :meth:`solve_final_state`.
- force_remove (bool):
- See :meth:`solve_final_state`.
- force_reinstall (bool):
- For requested specs_to_add that are already satisfied in the environment,
- instructs the solver to remove the package and spec from the environment,
- and then add it back--possibly with the exact package instance modified,
- depending on the spec exactness.
- Returns:
- tuple[PackageRef], tuple[PackageRef]:
- A two-tuple of PackageRef sequences. The first is the group of packages to
- remove from the environment, in sorted dependency order from leaves to roots.
- The second is the group of packages to add to the environment, in sorted
- dependency order from roots to leaves.
- """
- return self._internal.solve_for_diff(
- update_modifier,
- deps_modifier,
- prune,
- ignore_pinned,
- force_remove,
- force_reinstall,
- )
- def solve_for_transaction(
- self,
- update_modifier=NULL,
- deps_modifier=NULL,
- prune=NULL,
- ignore_pinned=NULL,
- force_remove=NULL,
- force_reinstall=False,
- ):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Gives an UnlinkLinkTransaction instance that can be used to execute the solution
- on an environment.
- Args:
- deps_modifier (DepsModifier):
- See :meth:`solve_final_state`.
- prune (bool):
- See :meth:`solve_final_state`.
- ignore_pinned (bool):
- See :meth:`solve_final_state`.
- force_remove (bool):
- See :meth:`solve_final_state`.
- force_reinstall (bool):
- See :meth:`solve_for_diff`.
- Returns:
- UnlinkLinkTransaction:
- """
- return self._internal.solve_for_transaction(
- update_modifier,
- deps_modifier,
- prune,
- ignore_pinned,
- force_remove,
- force_reinstall,
- )
- class SubdirData:
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- High-level management and usage of repodata.json for subdirs.
- """
- def __init__(self, channel):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Args:
- channel (str or Channel):
- The target subdir for the instance. Must either be a url that includes a subdir
- or a :obj:`Channel` that includes a subdir. e.g.:
- * 'https://repo.anaconda.com/pkgs/main/linux-64'
- * Channel('https://repo.anaconda.com/pkgs/main/linux-64')
- * Channel('conda-forge/osx-64')
- """
- channel = Channel(channel)
- assert channel.subdir
- self._internal = _SubdirData(channel)
- def query(self, package_ref_or_match_spec):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Run a query against this specific instance of repodata.
- Args:
- package_ref_or_match_spec (PackageRef or MatchSpec or str):
- Either an exact :obj:`PackageRef` to match against, or a :obj:`MatchSpec`
- query object. A :obj:`str` will be turned into a :obj:`MatchSpec` automatically.
- Returns:
- tuple[PackageRecord]
- """
- return tuple(self._internal.query(package_ref_or_match_spec))
- @staticmethod
- def query_all(package_ref_or_match_spec, channels=None, subdirs=None):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Run a query against all repodata instances in channel/subdir matrix.
- Args:
- package_ref_or_match_spec (PackageRef or MatchSpec or str):
- Either an exact :obj:`PackageRef` to match against, or a :obj:`MatchSpec`
- query object. A :obj:`str` will be turned into a :obj:`MatchSpec` automatically.
- channels (Iterable[Channel or str] or None):
- An iterable of urls for channels or :obj:`Channel` objects. If None, will fall
- back to context.channels.
- subdirs (Iterable[str] or None):
- If None, will fall back to context.subdirs.
- Returns:
- tuple[PackageRecord]
- """
- return tuple(
- _SubdirData.query_all(package_ref_or_match_spec, channels, subdirs)
- )
- def iter_records(self):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Returns:
- Iterable[PackageRecord]: A generator over all records contained in the repodata.json
- instance. Warning: this is a generator that is exhausted on first use.
- """
- return self._internal.iter_records()
- def reload(self):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Update the instance with new information. Backing information (i.e. repodata.json)
- is lazily downloaded/loaded on first use by the other methods of this class. You
- should only use this method if you are *sure* you have outdated data.
- Returns:
- SubdirData
- """
- self._internal = self._internal.reload()
- return self
- class PackageCacheData:
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- High-level management and usage of package caches.
- """
- def __init__(self, pkgs_dir):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Args:
- pkgs_dir (str):
- """
- self._internal = _PackageCacheData(pkgs_dir)
- def get(self, package_ref, default=NULL):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Args:
- package_ref (PackageRef):
- A :obj:`PackageRef` instance representing the key for the
- :obj:`PackageCacheRecord` being sought.
- default: The default value to return if the record does not exist. If not
- specified and no record exists, :exc:`KeyError` is raised.
- Returns:
- PackageCacheRecord
- """
- return self._internal.get(package_ref, default)
- def query(self, package_ref_or_match_spec):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Run a query against this specific package cache instance.
- Args:
- package_ref_or_match_spec (PackageRef or MatchSpec or str):
- Either an exact :obj:`PackageRef` to match against, or a :obj:`MatchSpec`
- query object. A :obj:`str` will be turned into a :obj:`MatchSpec` automatically.
- Returns:
- tuple[PackageCacheRecord]
- """
- return tuple(self._internal.query(package_ref_or_match_spec))
- @staticmethod
- def query_all(package_ref_or_match_spec, pkgs_dirs=None):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Run a query against all package caches.
- Args:
- package_ref_or_match_spec (PackageRef or MatchSpec or str):
- Either an exact :obj:`PackageRef` to match against, or a :obj:`MatchSpec`
- query object. A :obj:`str` will be turned into a :obj:`MatchSpec` automatically.
- pkgs_dirs (Iterable[str] or None):
- If None, will fall back to context.pkgs_dirs.
- Returns:
- tuple[PackageCacheRecord]
- """
- return tuple(_PackageCacheData.query_all(package_ref_or_match_spec, pkgs_dirs))
- def iter_records(self):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Returns:
- Iterable[PackageCacheRecord]: A generator over all records contained in the package
- cache instance. Warning: this is a generator that is exhausted on first use.
- """
- return self._internal.iter_records()
- @property
- def is_writable(self):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Indicates if the package cache location is writable or read-only.
- Returns:
- bool
- """
- return self._internal.is_writable
- @staticmethod
- def first_writable(pkgs_dirs=None):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Get an instance object for the first writable package cache.
- Args:
- pkgs_dirs (Iterable[str]):
- If None, will fall back to context.pkgs_dirs.
- Returns:
- PackageCacheData:
- An instance for the first writable package cache.
- """
- return PackageCacheData(_PackageCacheData.first_writable(pkgs_dirs).pkgs_dir)
- def reload(self):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Update the instance with new information. Backing information (i.e. contents of
- the pkgs_dir) is lazily loaded on first use by the other methods of this class. You
- should only use this method if you are *sure* you have outdated data.
- Returns:
- PackageCacheData
- """
- self._internal = self._internal.reload()
- return self
- class PrefixData:
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- High-level management and usage of conda environment prefixes.
- """
- def __init__(self, prefix_path):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Args:
- prefix_path (str):
- """
- self._internal = _PrefixData(prefix_path)
- def get(self, package_ref, default=NULL):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Args:
- package_ref (PackageRef):
- A :obj:`PackageRef` instance representing the key for the
- :obj:`PrefixRecord` being sought.
- default: The default value to return if the record does not exist. If not
- specified and no record exists, :exc:`KeyError` is raised.
- Returns:
- PrefixRecord
- """
- return self._internal.get(package_ref.name, default)
- def query(self, package_ref_or_match_spec):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Run a query against this specific prefix instance.
- Args:
- package_ref_or_match_spec (PackageRef or MatchSpec or str):
- Either an exact :obj:`PackageRef` to match against, or a :obj:`MatchSpec`
- query object. A :obj:`str` will be turned into a :obj:`MatchSpec` automatically.
- Returns:
- tuple[PrefixRecord]
- """
- return tuple(self._internal.query(package_ref_or_match_spec))
- def iter_records(self):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Returns:
- Iterable[PrefixRecord]: A generator over all records contained in the prefix.
- Warning: this is a generator that is exhausted on first use.
- """
- return self._internal.iter_records()
- @property
- def is_writable(self):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Indicates if the prefix is writable or read-only.
- Returns:
- bool or None:
- True if the prefix is writable. False if read-only. None if the prefix
- does not exist as a conda environment.
- """
- return self._internal.is_writable
- def reload(self):
- """
- **Beta** While in beta, expect both major and minor changes across minor releases.
- Update the instance with new information. Backing information (i.e. contents of
- the conda-meta directory) is lazily loaded on first use by the other methods of this
- class. You should only use this method if you are *sure* you have outdated data.
- Returns:
- PrefixData
- """
- self._internal = self._internal.reload()
- return self
|