Models and exceptions#

Workspace configuration, task definitions, and the errors they can raise.

Data models for workspace configuration.

These dataclasses represent the parsed workspace manifest in a format-agnostic way. Parsers convert from pixi.toml / pyproject.toml / conda.toml into these models; downstream code only works with these types.

Conda dependencies use MatchSpec directly, and channels use Channel, so the workspace layer benefits from conda’s own validation, URL resolution, and spec parsing.

class conda_workspaces.models.Environment(name: str, features: list[str] = <factory>, no_default_feature: bool = False)[source]#

A named environment composed from one or more features.

This maps to a [environments] entry in a pixi manifest. An environment inherits the default feature plus any additional features listed in features.

no_default_feature can be set to exclude the default feature, matching pixi’s no-default-feature = true option.

DEFAULT_NAME: ClassVar[str] = 'default'#
features: list[str]#
property is_default: bool#
name: str#
no_default_feature: bool = False#
class conda_workspaces.models.Feature(name: str, conda_dependencies: dict[str, ~conda.models.match_spec.MatchSpec]=<factory>, pypi_dependencies: dict[str, ~conda_workspaces.models.PyPIDependency]=<factory>, channels: list[Channel] = <factory>, platforms: list[str] = <factory>, system_requirements: dict[str, str]=<factory>, activation_scripts: list[str] = <factory>, activation_env: dict[str, str]=<factory>, target_conda_dependencies: dict[str, dict[str, ~conda.models.match_spec.MatchSpec]]=<factory>, target_pypi_dependencies: dict[str, dict[str, ~conda_workspaces.models.PyPIDependency]]=<factory>)[source]#

A composable group of dependencies and settings.

Features map directly to [feature.<name>] tables in a pixi manifest. They can provide conda dependencies, PyPI dependencies, channel overrides, platform restrictions, and environment variables.

The special feature named "default" corresponds to the top-level workspace dependencies.

DEFAULT_NAME: ClassVar[str] = 'default'#
activation_env: dict[str, str]#
activation_scripts: list[str]#
channels: list[Channel]#
conda_dependencies: dict[str, MatchSpec]#
property is_default: bool#
name: str#
platforms: list[str]#
pypi_dependencies: dict[str, PyPIDependency]#
system_requirements: dict[str, str]#
target_conda_dependencies: dict[str, dict[str, MatchSpec]]#
target_pypi_dependencies: dict[str, dict[str, PyPIDependency]]#
class conda_workspaces.models.PyPIDependency(name: str, spec: str = '', extras: tuple[str, ...] = (), path: str | None = None, editable: bool = False, git: str | None = None, url: str | None = None)[source]#

A PyPI dependency (PEP 508 string).

Names are translated to conda equivalents via conda-pypi’s grayskull mapping and merged into the same solver call as conda deps. Path/git/URL deps are handled post-solve via conda-pypi’s build system.

editable: bool = False#
extras: tuple[str, ...] = ()#
git: str | None = None#
name: str#
path: str | None = None#
spec: str = ''#
url: str | None = None#
class conda_workspaces.models.Task(name: str, cmd: str | list[str] | None = None, args: list[TaskArg] = <factory>, depends_on: list[TaskDependency] = <factory>, cwd: str | None = None, env: dict[str, str]=<factory>, description: str | None = None, inputs: list[str] = <factory>, outputs: list[str] = <factory>, clean_env: bool = False, default_environment: str | None = None, platforms: dict[str, ~conda_workspaces.models.TaskOverride] | None=None)[source]#

A single task definition with all its configuration.

args: list[TaskArg]#
clean_env: bool = False#
cmd: str | list[str] | None = None#
cwd: str | None = None#
default_environment: str | None = None#
depends_on: list[TaskDependency]#
description: str | None = None#
env: dict[str, str]#
inputs: list[str]#
property is_alias: bool#

True when the task is just a dependency grouping with no command.

property is_hidden: bool#

Hidden tasks (prefixed with _) are omitted from listings.

name: str#
outputs: list[str]#
platforms: dict[str, TaskOverride] | None = None#
resolve_for_platform(subdir: str) Task[source]#

Return a copy of this task with platform overrides merged in.

subdir is a conda platform string such as linux-64 or osx-arm64. If there is no matching override the task is returned unchanged.

class conda_workspaces.models.TaskArg(name: str, default: str | None = None, choices: list[str] | None = None)[source]#

A named argument that can be passed to a task.

choices: list[str] | None = None#
default: str | None = None#
name: str#
to_toml() dict[str, object][source]#

Serialize to a TOML-compatible dict.

class conda_workspaces.models.TaskDependency(task: str, args: list[str | dict[str, str]]=<factory>, environment: str | None = None)[source]#

A reference to another task that must run first.

args: list[str | dict[str, str]]#
environment: str | None = None#
task: str#
to_toml() str | dict[str, object][source]#

Serialize to a TOML-compatible value (string or dict).

class conda_workspaces.models.TaskOverride(cmd: str | list[str] | None = None, args: list[TaskArg] | None = None, depends_on: list[TaskDependency] | None = None, cwd: str | None = None, env: dict[str, str] | None = None, inputs: list[str] | None = None, outputs: list[str] | None = None, clean_env: bool | None = None)[source]#

Per-platform override for any task field.

Non-None fields replace the base task’s values when the override is merged into a Task via Task.resolve_for_platform.

args: list[TaskArg] | None = None#
clean_env: bool | None = None#
cmd: str | list[str] | None = None#
cwd: str | None = None#
depends_on: list[TaskDependency] | None = None#
env: dict[str, str] | None = None#
inputs: list[str] | None = None#
outputs: list[str] | None = None#
class conda_workspaces.models.WorkspaceConfig(name: str | None = None, version: str | None = None, description: str | None = None, channels: list[Channel] = <factory>, platforms: list[str] = <factory>, features: dict[str, ~conda_workspaces.models.Feature]=<factory>, environments: dict[str, ~conda_workspaces.models.Environment]=<factory>, root: str = '', manifest_path: str = '', envs_dir: str = '.conda/envs', channel_priority: str | None = None)[source]#

Complete parsed workspace configuration.

This is the top-level model that parsers produce. It contains all channels, platforms, features, and environments defined in a workspace manifest.

manifest_path points to the file that was parsed (for error messages and relative path resolution).

channel_priority: str | None = None#
channels: list[Channel]#
description: str | None = None#
environments: dict[str, Environment]#
envs_dir: str = '.conda/envs'#
features: dict[str, Feature]#
get_environment(name: str) Environment[source]#

Return the environment with name, raising if not found.

manifest_path: str = ''#
merged_channels(environment: Environment) list[Channel][source]#

Merge channels across features for environment.

Feature-specific channels are appended after the workspace-level channels, preserving priority order. Duplicates are removed.

merged_conda_dependencies(environment: Environment, platform: str | None = None) dict[str, MatchSpec][source]#

Merge conda dependencies across features for environment.

Later features override earlier ones. If platform is given, target-specific dependencies are also merged in.

merged_pypi_dependencies(environment: Environment, platform: str | None = None) dict[str, PyPIDependency][source]#

Merge PyPI dependencies across features for environment.

name: str | None = None#
platforms: list[str]#
resolve_features(environment: Environment) list[Feature][source]#

Return the ordered list of features for environment.

By default, the default feature is prepended unless the environment sets no_default_feature.

root: str = ''#
version: str | None = None#

Exception hierarchy for conda-workspaces.

exception conda_workspaces.exceptions.ActivationError(environment: str, reason: str)[source]#

Bases: CondaWorkspacesError

Environment activation failed.

exception conda_workspaces.exceptions.CondaWorkspacesError(message: str, *, hints: list[str] | None = None)[source]#

Bases: CondaError

Base exception for all conda-workspaces errors.

Subclasses provide hints — actionable suggestions shown below the main error message. The full str(exc) still contains everything (for conda’s fallback handler), but the Rich renderer in main.py uses error_message and hints separately.

exception conda_workspaces.exceptions.CyclicDependencyError(cycle: list[str])[source]#

Bases: CondaWorkspacesError

Raised when the task dependency graph contains a cycle.

exception conda_workspaces.exceptions.EnvironmentNotFoundError(name: str, available: list[str])[source]#

Bases: CondaWorkspacesError

The requested environment is not defined in the workspace.

exception conda_workspaces.exceptions.EnvironmentNotInstalledError(name: str)[source]#

Bases: CondaWorkspacesError

The requested environment exists but is not installed.

exception conda_workspaces.exceptions.FeatureNotFoundError(feature: str, environment: str)[source]#

Bases: CondaWorkspacesError

A feature referenced by an environment does not exist.

exception conda_workspaces.exceptions.LockfileNotFoundError(environment: str, path: str | Path)[source]#

Bases: CondaWorkspacesError

No lockfile or lockfile entry exists for the requested environment.

exception conda_workspaces.exceptions.LockfileStaleError(manifest: str | Path, lockfile: str | Path)[source]#

Bases: CondaWorkspacesError

The lockfile is older than the workspace manifest.

exception conda_workspaces.exceptions.ManifestExistsError(path: str | Path)[source]#

Bases: CondaWorkspacesError

A workspace manifest already exists at the target path.

exception conda_workspaces.exceptions.NoTaskFileError(search_dir: str)[source]#

Bases: CondaWorkspacesError

Raised when no task definition file is found.

exception conda_workspaces.exceptions.PlatformError(platform: str, available: list[str])[source]#

Bases: CondaWorkspacesError

Platform configuration error.

exception conda_workspaces.exceptions.SolveError(environment: str, reason: str)[source]#

Bases: CondaWorkspacesError

Dependency solving failed for an environment.

exception conda_workspaces.exceptions.TaskExecutionError(task_name: str, exit_code: int)[source]#

Bases: CondaWorkspacesError

Raised when a task command exits with a non-zero status.

exception conda_workspaces.exceptions.TaskNotFoundError(task_name: str, available: list[str] | None = None)[source]#

Bases: CondaWorkspacesError

Raised when a referenced task does not exist.

exception conda_workspaces.exceptions.TaskParseError(path: str | Path, reason: str)[source]#

Bases: CondaWorkspacesError

Raised when a task definition file cannot be parsed.

exception conda_workspaces.exceptions.WorkspaceNotFoundError(search_dir: str | Path)[source]#

Bases: CondaWorkspacesError

No workspace manifest was found in search_dir or its parents.

exception conda_workspaces.exceptions.WorkspaceParseError(path: str | Path, reason: str)[source]#

Bases: CondaWorkspacesError

The workspace manifest could not be parsed.