JSON Schema for Conda Solver Tests#

This page documents the schema for the declarative YAML test files consumed by pytest-conda-solvers. Each test file deserialises into a TestModule containing an ordered list of test specs. Four test kinds are supported, each represented by a distinct class and selected via the kind discriminator field.

Top-level container#

class pytest_conda_solvers.models.TestModule(tests)[source]#

The top-level container for a conda solver test file.

A test file (typically a .yaml file) deserializes into a TestModule, which holds an ordered list of test specs. Each spec is one of the four supported test kinds, discriminated by the kind field.

Parameters:

tests (list[SolveTestSpec | SolveForDiffTestSpec | DetermineConstrictingSpecsTestSpec | UnsatisfiableTestSpec])

tests: list[SolveTestSpec | SolveForDiffTestSpec | DetermineConstrictingSpecsTestSpec | UnsatisfiableTestSpec]#

The list of test specs contained in this module. Each element is one of SolveTestSpec, SolveForDiffTestSpec, DetermineConstrictingSpecsTestSpec, or UnsatisfiableTestSpec, selected by the kind field.

A test file consists of a single top-level tests key whose value is a list of test specs:

tests:
- kind: solve
  name: solve_1_1
  id: B001
  provenance:
    node_id: tests/core/test_solve.py::test_solve_1::1
    commit: 03329e0f4a627c9b9aa92ef34f7f93b9aa83e438
    url: https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/tests/core/test_solve.py#L58-L124
  input:
    channels: channel-1
    specs_to_add: numpy
  output:
    final_state:
    - channel-1/${{ arch }}::openssl-1.0.1c-0
    - channel-1/${{ arch }}::readline-6.2-0
    - channel-1/${{ arch }}::sqlite-3.7.13-0
    - channel-1/${{ arch }}::system-5.8-1
    - channel-1/${{ arch }}::tk-8.5.13-0
    - channel-1/${{ arch }}::zlib-1.2.7-0
    - channel-1/${{ arch }}::python-3.3.2-0
    - channel-1/${{ arch }}::numpy-1.7.1-py33_0
  description: 'Upstream marks the whole of test_solve_1 flaky with reruns=5, so this

    stage carries the same rerun allowance there, see

    https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/tests/core/test_solve.py#L56-L58.

    Upstream''s docstring only documents mis-picks in the python=2 stage

    (solve_1_2). In this port, the result was observed to be deterministic

    enough as a failure occurred in roughly 1 in 800 libmamba runs across

    the two stages.

    '
- kind: unsatisfiable
  name: test_unsatisfiable_from_channel_1_1
  id: B005
  provenance:
    node_id: conda/testing/solver_helpers.py::SolverTests.test_unsat_from_r1::1
    commit: 03329e0f4a627c9b9aa92ef34f7f93b9aa83e438
    url: https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/conda/testing/solver_helpers.py#L351-L380
  input:
    channels: channel-1
    specs_to_add:
    - numpy 1.5*
    - scipy 0.12.0b1
    add_pip: true
  error:
    exception: UnsatisfiableError
    entries:
    - numpy=1.5
    - - scipy==0.12.0b1
      - numpy[version='1.6.*|1.7.*']

Test specs#

Each element of tests is one of the four spec types below, identified by its kind field.

class pytest_conda_solvers.models.SolveTestSpec(name, id, provenance, input, output, description=None, test_function='test_solve', solvers=None, xfail_solvers=None, xfail_reason=None)[source]#

Test spec for a standard solve operation (kind: solve).

Asserts that the solver produces a specific final environment state given the inputs. The kind discriminator field is always "solve" and is set automatically.

Parameters:
  • name (str)

  • id (str)

  • provenance (Provenance)

  • input (TestInput)

  • output (TestOutput)

  • description (str | None)

  • test_function (str)

  • solvers (str | list[str] | None)

  • xfail_solvers (str | list[str] | None)

  • xfail_reason (str | None)

name: str#

A human-readable name for the test (e.g. "test_install_numpy").

id: str#

A stable unique identifier for this test case. Used to look up the test by ID independently of its name or position in the file.

provenance: Provenance#

Provenance information linking this test back to its upstream source.

input: TestInput#

The solver inputs for this test case.

output: TestOutput#

The expected output (final environment state) after the solve.

description: str | None#

An optional human-readable description of what this test exercises. Defaults to None.

test_function: str#

The name of the base-test method to invoke for this spec. Defaults to "test_solve".

solvers: str | list[str] | None#

Restrict this test to a specific solver backend or list of backends (e.g. "classic" or ["classic", "libmamba"]). None means the test runs against all registered solver backends.

xfail_solvers: str | list[str] | None#

Solver backend(s) for which this test is expected to fail (xfail) rather than error. May be a single string or a list. None means no solver is expected to fail.

xfail_reason: str | None#

A human-readable explanation of why the solver(s) in xfail_solvers are expected to fail. None if not applicable.

A solve test asserts that the solver reaches a specific final environment state. Example (B001):

kind: solve
name: solve_1_1
id: B001
provenance:
  node_id: tests/core/test_solve.py::test_solve_1::1
  commit: 03329e0f4a627c9b9aa92ef34f7f93b9aa83e438
  url: https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/tests/core/test_solve.py#L58-L124
input:
  channels: channel-1
  specs_to_add: numpy
output:
  final_state:
  - channel-1/${{ arch }}::openssl-1.0.1c-0
  - channel-1/${{ arch }}::readline-6.2-0
  - channel-1/${{ arch }}::sqlite-3.7.13-0
  - channel-1/${{ arch }}::system-5.8-1
  - channel-1/${{ arch }}::tk-8.5.13-0
  - channel-1/${{ arch }}::zlib-1.2.7-0
  - channel-1/${{ arch }}::python-3.3.2-0
  - channel-1/${{ arch }}::numpy-1.7.1-py33_0
description: 'Upstream marks the whole of test_solve_1 flaky with reruns=5, so this

  stage carries the same rerun allowance there, see

  https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/tests/core/test_solve.py#L56-L58.

  Upstream''s docstring only documents mis-picks in the python=2 stage

  (solve_1_2). In this port, the result was observed to be deterministic

  enough as a failure occurred in roughly 1 in 800 libmamba runs across

  the two stages.

  '
class pytest_conda_solvers.models.SolveForDiffTestSpec(name, id, provenance, input, output, description=None, test_function='test_solve_for_diff', solvers=None, xfail_solvers=None, xfail_reason=None)[source]#

Test spec for a solve-for-diff operation (kind: solve_for_diff).

Asserts that the solver produces specific unlink/link package sets rather than a full final environment state. The kind discriminator field is always "solve_for_diff" and is set automatically.

Parameters:
  • name (str)

  • id (str)

  • provenance (Provenance)

  • input (TestInput)

  • output (DiffTestOutput)

  • description (str | None)

  • test_function (str)

  • solvers (str | list[str] | None)

  • xfail_solvers (str | list[str] | None)

  • xfail_reason (str | None)

name: str#

A human-readable name for the test.

id: str#

A stable unique identifier for this test case.

provenance: Provenance#

Provenance information linking this test back to its upstream source.

input: TestInput#

The solver inputs for this test case.

output: DiffTestOutput#

The expected diff output (packages to unlink and link).

description: str | None#

An optional human-readable description of what this test exercises. Defaults to None.

test_function: str#

The name of the base-test method to invoke for this spec. Defaults to "test_solve_for_diff".

solvers: str | list[str] | None#

Restrict this test to a specific solver backend or list of backends. None means the test runs against all registered solver backends.

xfail_solvers: str | list[str] | None#

Solver backend(s) for which this test is expected to fail (xfail) rather than error. May be a single string or a list. None means no solver is expected to fail.

xfail_reason: str | None#

A human-readable explanation of why the solver(s) in xfail_solvers are expected to fail. None if not applicable.

A solve_for_diff test asserts the set of packages unlinked and linked rather than the complete final environment state. Example (B034):

kind: solve_for_diff
name: test_update_deps_2_2
id: B034
provenance:
  node_id: tests/core/test_solve.py::test_update_deps_2::2
  commit: 03329e0f4a627c9b9aa92ef34f7f93b9aa83e438
  url: https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/tests/core/test_solve.py#L2164-L2232
input:
  channels:
  - channel-4
  - channel-2
  specs_to_add:
  - flask
  prefix:
  - channel-4/${{ arch }}::ca-certificates-2018.03.07-0
  - channel-4/${{ arch }}::libgcc-ng-8.2.0-hdf63c60_0
  - channel-4/${{ arch }}::libstdcxx-ng-8.2.0-hdf63c60_0
  - channel-4/${{ arch }}::libffi-3.2.1-hd88cf55_4
  - channel-4/${{ arch }}::ncurses-6.1-hf484d3e_0
  - channel-4/${{ arch }}::openssl-1.0.2p-h14c3975_0
  - channel-4/${{ arch }}::tk-8.6.7-hc745277_3
  - channel-4/${{ arch }}::xz-5.2.4-h14c3975_4
  - channel-4/${{ arch }}::zlib-1.2.11-ha838bed_2
  - channel-4/${{ arch }}::libedit-3.1.20170329-h6b74fdf_2
  - channel-4/${{ arch }}::readline-7.0-ha6073c6_4
  - channel-4/${{ arch }}::sqlite-3.24.0-h84994c4_0
  - channel-4/${{ arch }}::python-3.6.6-hc3d631a_0
  - channel-4/${{ arch }}::certifi-2018.8.13-py36_0
  - channel-4/${{ arch }}::click-6.7-py36_0
  - channel-4/${{ arch }}::itsdangerous-0.24-py36_1
  - channel-4/${{ arch }}::markupsafe-1.0-py36h14c3975_1
  - channel-4/${{ arch }}::werkzeug-0.14.1-py36_0
  - channel-4/${{ arch }}::setuptools-40.0.0-py36_0
  - channel-2/${{ arch }}::jinja2-2.8-py36_1
  - channel-2/${{ arch }}::flask-0.12-py36_0
  history_specs:
  - flask==0.12
  - jinja2==2.8
output:
  unlink_precs:
  - channel-2/${{ arch }}::flask-0.12-py36_0
  link_precs:
  - channel-4/${{ arch }}::flask-0.12.2-py36hb24657c_0
class pytest_conda_solvers.models.DetermineConstrictingSpecsTestSpec(name, id, provenance, input, output, description=None, test_function='test_determine_constricting_specs', solvers=None, xfail_solvers=None, xfail_reason=None)[source]#

Test spec for a constricting-specs determination (kind: determine_constricting_specs).

Asserts that the solver correctly identifies which installed packages are blocking a requested operation. The kind discriminator field is always "determine_constricting_specs" and is set automatically.

Parameters:
name: str#

A human-readable name for the test.

id: str#

A stable unique identifier for this test case.

provenance: Provenance#

Provenance information linking this test back to its upstream source.

input: TestInput#

The solver inputs for this test case.

output: DeterminingConstrictingSpecsTestOutput#

The expected output listing the constricting package relationships.

description: str | None#

An optional human-readable description of what this test exercises. Defaults to None.

test_function: str#

The name of the base-test method to invoke for this spec. Defaults to "test_determine_constricting_specs".

solvers: str | list[str] | None#

Restrict this test to a specific solver backend or list of backends. None means the test runs against all registered solver backends.

xfail_solvers: str | list[str] | None#

Solver backend(s) for which this test is expected to fail (xfail) rather than error. May be a single string or a list. None means no solver is expected to fail.

xfail_reason: str | None#

A human-readable explanation of why the solver(s) in xfail_solvers are expected to fail. None if not applicable.

A determine_constricting_specs test asserts which installed packages are blocking a requested installation or upgrade. Example (S001):

kind: determine_constricting_specs
name: test_determine_constricting_specs_conflicts
id: S001
provenance:
  node_id: tests/core/test_solve.py::test_determine_constricting_specs_conflicts
  commit: 03329e0f4a627c9b9aa92ef34f7f93b9aa83e438
  url: https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/tests/core/test_solve.py#L3499-L3535
input:
  channels: conda_format_repo
  subdirs: linux-64
  specs_to_add: mypkg
  solution_records:
  - record_type: prefix
    package_type: noarch_generic
    name: mypkg
    version: 0.1.0
    channel: test
    subdir: conda-test
    fn: mypkg-0.1.0
    build: pypi_0
  - record_type: prefix
    package_type: noarch_generic
    name: mypkgnot
    version: 1.1.1
    channel: test
    subdir: conda-test
    fn: mypkgnot-1.1.1
    build: pypi_0
    depends:
    - mypkg 0.1.0
output:
  constrictions:
  - package: mypkgnot
    constricting_match_spec: mypkg==0.1.0
description: 'mypkgnot depends on mypkg 0.1.0, so updating mypkg is constricted to

  exactly that version. Upstream only asserts that some constriction is

  named mypkgnot, so the exact single-element list checked here is a

  strengthening, see

  https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/tests/core/test_solve.py#L3534-L3535

  Upstream''s fixtures carried copy-paste quirks (fn mypkg-0.1.1 on the

  0.1.0 record, build_number 1 on pypi_0 builds), fixed in

  https://github.com/conda/conda/pull/16573 and mirrored here.

  '
class pytest_conda_solvers.models.UnsatisfiableTestSpec(name, id, provenance, input, error, description=None, operation='solve_final_state', test_function='test_unsatisfiable', solvers=None, xfail_solvers=None, xfail_reason=None)[source]#

Test spec for a solve that is expected to fail (kind: unsatisfiable).

Asserts that the solver raises a specific exception given the inputs. The kind discriminator field is always "unsatisfiable" and is set automatically.

Parameters:
name: str#

A human-readable name for the test.

id: str#

A stable unique identifier for this test case.

provenance: Provenance#

Provenance information linking this test back to its upstream source.

input: TestInput#

The solver inputs for this test case.

error: UnsatisfiableTestError | ResolvePackageNotFoundTestError | PackagesNotFoundTestError | SpecsConfigurationConflictTestError#

The expected error the solver should raise. Must be one of UnsatisfiableTestError, ResolvePackageNotFoundTestError, PackagesNotFoundTestError, or SpecsConfigurationConflictTestError, discriminated by the exception field.

description: str | None#

An optional human-readable description of what this test exercises. Defaults to None.

operation: Literal['solve_final_state', 'solve_for_diff']#

computing the final environment state or computing the unlink/link diff. Defaults to "solve_final_state".

Type:

Which solve operation is expected to raise the error

test_function: str#

The name of the base-test method to invoke for this spec. Defaults to "test_unsatisfiable".

solvers: str | list[str] | None#

Restrict this test to a specific solver backend or list of backends. None means the test runs against all registered solver backends.

xfail_solvers: str | list[str] | None#

Solver backend(s) for which this test is expected to fail (xfail) rather than error. May be a single string or a list. None means no solver is expected to fail.

xfail_reason: str | None#

A human-readable explanation of why the solver(s) in xfail_solvers are expected to fail. None if not applicable.

An unsatisfiable test asserts that the solver raises a specific error. The error field is a discriminated union — see the Errors section for all four error types. Example with UnsatisfiableError (B005):

kind: unsatisfiable
name: test_unsatisfiable_from_channel_1_1
id: B005
provenance:
  node_id: conda/testing/solver_helpers.py::SolverTests.test_unsat_from_r1::1
  commit: 03329e0f4a627c9b9aa92ef34f7f93b9aa83e438
  url: https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/conda/testing/solver_helpers.py#L351-L380
input:
  channels: channel-1
  specs_to_add:
  - numpy 1.5*
  - scipy 0.12.0b1
  add_pip: true
error:
  exception: UnsatisfiableError
  entries:
  - numpy=1.5
  - - scipy==0.12.0b1
    - numpy[version='1.6.*|1.7.*']

Example with ResolvePackageNotFound (B007):

kind: unsatisfiable
name: test_unsatisfiable_from_channel_1_3
id: B007
provenance:
  node_id: conda/testing/solver_helpers.py::SolverTests.test_unsat_from_r1::3
  commit: 03329e0f4a627c9b9aa92ef34f7f93b9aa83e438
  url: https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/conda/testing/solver_helpers.py#L351-L380
input:
  channels: channel-1
  specs_to_add:
  - numpy 1.5*
  - numpy 1.6*
  add_pip: true
error:
  exception: ResolvePackageNotFound
  entries:
  - numpy[version='1.5.*,1.6.*']
description: 'Upstream accepts ResolvePackageNotFound or PackagesNotFoundError and

  checks bad_deps for classic only, see

  https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/conda/testing/solver_helpers.py#L375-L380

  '
solvers: classic

Example with PackagesNotFoundError (B007b):

kind: unsatisfiable
name: test_unsatisfiable_from_channel_1_3_libmamba
id: B007b
provenance:
  node_id: conda/testing/solver_helpers.py::SolverTests.test_unsat_from_r1::3
  commit: 03329e0f4a627c9b9aa92ef34f7f93b9aa83e438
  url: https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/conda/testing/solver_helpers.py#L351-L380
input:
  channels: channel-1
  specs_to_add:
  - numpy 1.5*
  - numpy 1.6*
  add_pip: true
error:
  exception: PackagesNotFoundError
  entries:
  - numpy[version='1.5.*,1.6.*']
description: 'libmamba variant: raises PackagesNotFoundError for the same conflicting

  numpy globs, matching upstream''s accepted exception pair. Upstream checks

  nothing beyond the exception for the PackagesNotFoundError case, see

  https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/conda/testing/solver_helpers.py#L375-L380

  The harness compares package names only, so the version text in entries

  is informative rather than asserted.

  '
solvers: libmamba

Example with SpecsConfigurationConflictError (I004):

kind: unsatisfiable
name: pinned_1_4
id: I004
provenance:
  node_id: tests/core/test_solve.py::test_pinned_1::5
  commit: 03329e0f4a627c9b9aa92ef34f7f93b9aa83e438
  url: https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/tests/core/test_solve.py#L2356-L2603
input:
  channels: channel-1
  specs_to_add: scikit-learn==0.13
  prefix: channel-1/${{ arch }}::system-5.8-0
  history_specs: system=5.8=0
  ignore_pinned: false
  pinned_packages:
  - python=2.6
  - iopro<=1.4.2
error:
  exception: SpecsConfigurationConflictError
  requested_specs:
  - scikit-learn==0.13
  pinned_specs:
  - python=2.6
description: 'Classic raises SpecsConfigurationConflictError for the pinned python

  conflict. The libmamba branch is ported separately as I004b, matching

  upstream''s per-solver split, see

  https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/tests/core/test_solve.py#L2443-L2458

  '
solvers: classic

Input#

class pytest_conda_solvers.models.TestInput(channels=None, subdirs=<factory>, specs_to_add=None, specs_to_remove=None, prefix=None, history_specs=None, solution_records=None, add_pip=False, ignore_pinned=None, force_reinstall=None, prune=None, force_remove=None, pinned_packages=None, aggressive_update_packages=None, auto_update_conda=None, update_modifier=None, deps_modifier=None, channel_priority=None, set_sys_prefix=None, override_cuda=None, override_glibc=None)[source]#

Describes the solver inputs for a single test case.

Most fields are optional. Each field’s description explains how None is handled.

Parameters:
  • channels (TestChannel | list[TestChannel] | None)

  • subdirs (TestSubdir | list[TestSubdir])

  • specs_to_add (str | list[str] | None)

  • specs_to_remove (str | list[str] | None)

  • prefix (str | list[str] | None)

  • history_specs (str | list[str] | None)

  • solution_records (PrefixRecord | list[PrefixRecord] | None)

  • add_pip (bool)

  • ignore_pinned (bool | None)

  • force_reinstall (bool | None)

  • prune (bool | None)

  • force_remove (bool | None)

  • pinned_packages (str | list[str] | None)

  • aggressive_update_packages (str | list[str] | None)

  • auto_update_conda (bool | None)

  • update_modifier (UpdateModifier | None)

  • deps_modifier (DepsModifier | None)

  • channel_priority (ChannelPriority | None)

  • set_sys_prefix (bool | None)

  • override_cuda (str | None)

  • override_glibc (str | None)

channels: TestChannel | list[TestChannel] | None#

The channel(s) to make available to the solver. May be a single TestChannel value or a list of them. None means no test channels are supplied.

subdirs: TestSubdir | list[TestSubdir]#

The platform subdirectory (or list of subdirectories) to consider when resolving packages. Defaults to ["linux-64", "noarch"].

specs_to_add: str | list[str] | None#

The package spec(s) to add/install in this solve. May be a single match-spec string or a list. None means no new specs are added.

specs_to_remove: str | list[str] | None#

The package spec(s) to remove in this solve. May be a single match-spec string or a list. None means nothing is removed.

prefix: str | list[str] | None#

Installed package distribution string(s) used to populate the temporary prefix before solving. May be a single string or a list. None means the prefix starts empty.

history_specs: str | list[str] | None#

Match spec(s) representing the history of explicitly requested packages in the prefix. May be a single string or a list. None means no history is set.

solution_records: PrefixRecord | list[PrefixRecord] | None#

Package record(s) in the candidate solution inspected by determine_constricting_specs(). May be a single PrefixRecord or a list. None means no solution records are supplied.

add_pip: bool#

Whether to add pip as an implicit dependency. Defaults to False.

ignore_pinned: bool | None#

Whether to ignore pinned package constraints during the solve. None means use the solver default.

force_reinstall: bool | None#

Whether to force reinstallation of already-satisfied packages. None means use the solver default.

prune: bool | None#

Whether to remove packages that are no longer needed by any history spec. None means use the solver default.

force_remove: bool | None#

Whether to remove the requested packages without removing their dependents. None means use the solver default.

pinned_packages: str | list[str] | None#

Package spec(s) to pin (hold at their current version). May be a single string or a list. None means no packages are pinned.

aggressive_update_packages: str | list[str] | None#

Package spec(s) that should be aggressively updated when possible. May be a single string or a list. None means use the solver default.

auto_update_conda: bool | None#

Whether conda itself should be auto-updated during the solve. None means use the solver default.

update_modifier: UpdateModifier | None#

Controls how already-installed packages are treated during an update. None means use the solver default. Valid string values mirror conda.core.solve.UpdateModifier: "freeze_installed", "specs_satisfied_skip_solve", "update_all", "update_deps", "update_specs".

deps_modifier: DepsModifier | None#

Controls whether dependencies are installed, skipped, or exclusively targeted. None means use the solver default. Valid string values mirror conda.core.solve.DepsModifier: "no_deps", "not_set", "only_deps".

channel_priority: ChannelPriority | None#

The channel priority mode to use for this solve. None means use the solver default. See ChannelPriority for valid values.

set_sys_prefix: bool | None#

Whether to set sys.prefix as the target prefix. False or None leaves sys.prefix unchanged.

override_cuda: str | None#

Override the detected CUDA version string (e.g. "11.8"). None means no override; the solver uses its auto-detected value.

override_glibc: str | None#

Override the detected glibc version string (e.g. "2.17"). None means no override; the solver uses its auto-detected value.

Most fields are optional. A typical minimal solve input sets only specs_to_add:

channels: channel-1
specs_to_add: numpy

A more complete input showing prefix pre-population and solver modifiers:

channels:
- channel-4
- channel-2
specs_to_add:
- flask
prefix:
- channel-4/${{ arch }}::python-3.6.6-hc3d631a_0
- channel-2/${{ arch }}::flask-0.12-py36_0
history_specs:
- flask==0.12
pinned_packages:
- python=3.6
update_modifier: update_specs
channel_priority: flexible
class pytest_conda_solvers.models.PrefixRecord(*, package_type=None, name, version, channel, subdir, fn, build='0', build_number=0, paths_data=None, files=None, depends=<factory>, constrains=<factory>)[source]#

Represents a package record in the solution inspected by determine_constricting_specs(). The record_type discriminator field is always "prefix" and is set automatically.

Parameters:
  • package_type (PackageType | None)

  • name (str)

  • version (str)

  • channel (str)

  • subdir (str)

  • fn (str)

  • build (str)

  • build_number (int)

  • paths_data (list[str] | None)

  • files (list[str] | None)

  • depends (list[str])

  • constrains (list[str])

package_type: PackageType | None#

The conda package type. Optional; defaults to None. Valid values mirror conda.models.enums.PackageType, e.g. "noarch_generic", "noarch_python", "virtual_system", etc.

name: str#

The package name (e.g. "numpy").

version: str#

The package version string (e.g. "1.24.3").

channel: str#

The channel the package was installed from (e.g. "conda-forge").

subdir: str#

The platform subdirectory the package belongs to (e.g. "linux-64").

fn: str#

The filename of the package archive (e.g. "numpy-1.24.3-py311h0000000_0.conda").

build: str#

The build string (e.g. "py311h0000000_0"). Defaults to "0".

build_number: int#

The build number. Defaults to 0.

paths_data: list[str] | None#

List of relative paths recorded in the package’s path data. Optional.

files: list[str] | None#

List of files installed by the package. Optional.

depends: list[str]#

List of run-dependency match specs (e.g. ["python >=3.11", "numpy"]). Defaults to an empty list.

constrains: list[str]#

List of match specs describing optional runtime constraints (run_constrained).

A PrefixRecord in solution_records looks like:

record_type: prefix
package_type: noarch_generic
name: mypkgnot
version: 1.1.1
channel: test
subdir: conda-test
fn: mypkgnot-1.1.1
build: pypi_0
depends:
- mypkg 0.1.0

Output#

class pytest_conda_solvers.models.TestOutput(final_state=None)[source]#

Expected output for a kind: solve test case.

Describes the expected final state returned by a successful solve.

Parameters:

final_state (str | list[str] | None)

final_state: str | list[str] | None#

The expected package distribution string(s) returned by the solve. None only asserts that the solve succeeds without checking its result.

final_state:
- channel-1/${{ arch }}::openssl-1.0.1c-0
- channel-1/${{ arch }}::readline-6.2-0
- channel-1/${{ arch }}::sqlite-3.7.13-0
- channel-1/${{ arch }}::system-5.8-1
- channel-1/${{ arch }}::tk-8.5.13-0
- channel-1/${{ arch }}::zlib-1.2.7-0
- channel-1/${{ arch }}::python-3.3.2-0
- channel-1/${{ arch }}::numpy-1.7.1-py33_0
class pytest_conda_solvers.models.DiffTestOutput(unlink_precs=None, link_precs=None)[source]#

Expected output for a kind: solve_for_diff test case.

Describes the expected package-level diff (unlinks and links) produced by the solver rather than the full final environment state.

Parameters:
  • unlink_precs (str | list[str] | None)

  • link_precs (str | list[str] | None)

The package distribution string(s) expected to be unlinked from the prefix. None means no unlinks are expected.

The package distribution string(s) expected to be linked into the prefix. None means no links are expected.

unlink_precs:
- channel-2/${{ arch }}::flask-0.12-py36_0
link_precs:
- channel-4/${{ arch }}::flask-0.12.2-py36hb24657c_0
class pytest_conda_solvers.models.DeterminingConstrictingSpecsTestOutput(constrictions=None)[source]#

Expected output for a kind: determine_constricting_specs test case.

Describes the set of constricting package relationships the solver is expected to identify.

Parameters:

constrictions (list[Constriction] | None)

constrictions: list[Constriction] | None#

The list of constrictions the solver is expected to report. Each entry is a Constriction describing one blocking dependency. None means the solver is expected to report no constrictions.

When no constrictions are found, constrictions is null:

constrictions: null

When constrictions are present:

constrictions:
- package: mypkgnot
  constricting_match_spec: mypkg==0.1.0
class pytest_conda_solvers.models.Constriction(package, constricting_match_spec)[source]#

A single constricting package relationship identified by the solver.

Represents one entry in the output of a determine_constricting_specs solve, describing which installed package is blocking a requested upgrade or installation.

Parameters:
  • package (str)

  • constricting_match_spec (str)

package: str#

The name of the installed package that is imposing the constriction (e.g. "scipy").

constricting_match_spec: str#

The match spec from package’s dependencies that is blocking the requested operation (e.g. "numpy >=1.22,<1.24").

Errors#

The error field of UnsatisfiableTestSpec is a discriminated union of the four error types below, identified by the exception field.

class pytest_conda_solvers.models.UnsatisfiableTestError(entries, message_excludes=<factory>, message_includes=<factory>)[source]#

Expected error for a test where the solver should raise UnsatisfiableError.

The exception discriminator field is always "UnsatisfiableError" and is set automatically.

Parameters:
  • entries (str | list[str | list[str]])

  • message_excludes (str | list[str] | dict[str, str | list[str]])

  • message_includes (str | list[str] | dict[str, str | list[str]])

entries: str | list[str | list[str]]#

The conflicting dependency chain(s) that make the environment unsatisfiable. Each entry may be a single string or a list of strings representing one conflict path. May also be given as a single string instead of a list when there is only one entry.

message_excludes: str | list[str] | dict[str, str | list[str]]#

Substring(s) that must NOT appear in the raised exception’s message. May be a single string, a list, or a mapping keyed by solver name. Defaults to an empty list (no exclusion checks).

message_includes: str | list[str] | dict[str, str | list[str]]#

Substring(s) that must appear in the raised exception’s message. May be a single string, a list, or a mapping keyed by solver name. Defaults to an empty list (no inclusion checks).

exception: UnsatisfiableError
entries:
- numpy=1.5
- - scipy==0.12.0b1
  - numpy[version='1.6.*|1.7.*']

An empty entries list is valid when the solver raises the error but no specific conflict chain is being asserted:

exception: UnsatisfiableError
entries: []
class pytest_conda_solvers.models.ResolvePackageNotFoundTestError(entries)[source]#

Expected error for a test where the solver should raise ResolvePackageNotFound.

The exception discriminator field is always "ResolvePackageNotFound" and is set automatically.

Parameters:

entries (str | list[str | list[str]])

entries: str | list[str | list[str]]#

The package spec(s) that could not be resolved. Each entry is a string (or list of strings) describing the missing package. May also be given as a single string instead of a list when there is only one entry.

exception: ResolvePackageNotFound
entries:
- numpy[version='1.5.*,1.6.*']
class pytest_conda_solvers.models.PackagesNotFoundTestError(entries)[source]#

Expected error for a test where the solver should raise PackagesNotFoundError.

The exception discriminator field is always "PackagesNotFoundError" and is set automatically.

Parameters:

entries (str | list[str | list[str]])

entries: str | list[str | list[str]]#

The package spec(s) that could not be found in any configured channel. Each entry is a string or list of strings. May also be given as a single string instead of a list when there is only one entry.

exception: PackagesNotFoundError
entries:
- numpy[version='1.5.*,1.6.*']
class pytest_conda_solvers.models.SpecsConfigurationConflictTestError(requested_specs, pinned_specs)[source]#

Expected error for a test where the solver should raise SpecsConfigurationConflictError.

This error occurs when explicitly requested specs conflict with pinned package constraints. The exception discriminator field is always "SpecsConfigurationConflictError" and is set automatically.

Parameters:
  • requested_specs (str | list[str])

  • pinned_specs (str | list[str])

requested_specs: str | list[str]#

The explicitly requested spec(s) that conflict with pinned constraints. May be a single string or a list of strings.

pinned_specs: str | list[str]#

The pinned spec(s) that conflict with the requested specs. May be a single string or a list of strings.

exception: SpecsConfigurationConflictError
requested_specs:
- scikit-learn==0.13
pinned_specs:
- python=2.6

Provenance#

class pytest_conda_solvers.models.Provenance(node_id, commit, url)[source]#

Records the origin of a test case — where it came from in the conda source tree.

This information is used to trace each test back to its upstream source commit and to generate links to the original test in the conda repository.

Parameters:
  • node_id (str)

  • commit (str)

  • url (str)

node_id: str#

The pytest node ID of the original test in the upstream conda test suite (e.g. "tests/test_solve.py::TestSolveUserStories::test_install_numpy").

commit: str#

The full Git commit SHA of the upstream conda commit the test was ported from (e.g. "03329e0f4a627c9b9aa92ef34f7f93b9aa83e438").

url: str#

The URL to the specific source file in the upstream conda repository at the recorded commit, linking directly to the test’s location on GitHub.

node_id: tests/core/test_solve.py::test_solve_1::1
commit: 03329e0f4a627c9b9aa92ef34f7f93b9aa83e438
url: https://github.com/conda/conda/blob/03329e0f4a627c9b9aa92ef34f7f93b9aa83e438/tests/core/test_solve.py#L58-L124

Enumerations#

class pytest_conda_solvers.models.TestChannel(*values)[source]#

Enumeration of test channel identifiers available in the test fixture data.

These names correspond to the channel directories bundled with the test suite.

CHANNEL_1 = 'channel-1'#
CHANNEL_2 = 'channel-2'#
CHANNEL_4 = 'channel-4'#
CHANNEL_6 = 'channel-6'#
CHANNEL_7 = 'channel-7'#
CHANNEL_8 = 'channel-8'#
CHANNEL_9 = 'channel-9'#
CHANNEL_10 = 'channel-10'#
CHANNEL_11 = 'channel-11'#
CHANNEL_12 = 'channel-12'#
CHANNEL_13 = 'channel-13'#
CHANNEL_14 = 'channel-14'#
CHANNEL_FREEZE = 'channel-freeze'#
CHANNEL_EMPTY = 'channel-empty'#
CONDA_FORMAT_REPO = 'conda_format_repo'#
TEST = 'test'#
class pytest_conda_solvers.models.TestSubdir(*values)[source]#

Enumeration of platform subdirectories available in the test fixture data.

NOARCH = 'noarch'#
LINUX_64 = 'linux-64'#
CONDA_TEST = 'conda-test'#
class pytest_conda_solvers.models.ChannelPriority(*values)[source]#

Enumeration of channel priority modes, mirroring conda’s ChannelPriority setting.

Controls whether packages from higher-priority channels are preferred over those from lower-priority channels when both satisfy a requirement.

STRICT = 'strict'#
FLEXIBLE = 'flexible'#
DISABLED = 'disabled'#