From 95337dbe6b90b547b997c108420a19faa2743a82 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 2 Sep 2026 11:14:46 -0700 Subject: [PATCH 1/2] trait tests in python use dev pyslim --- .github/workflows/tests.yml | 16 +- treerec/tests/README.md | 3 + treerec/tests/conftest.py | 7 +- treerec/tests/init.slim | 13 + treerec/tests/pyproject.toml | 4 +- treerec/tests/recipe_specs.py | 15 + treerec/tests/test_recipes/recipe_WF.slim | 24 + treerec/tests/test_recipes/recipe_WF_H.slim | 23 + treerec/tests/test_recipes/recipe_WF_HF.slim | 24 + treerec/tests/test_recipes/recipe_WF_HM.slim | 24 + treerec/tests/test_recipes/recipe_WF_W.slim | 24 + treerec/tests/test_recipes/recipe_WF_X.slim | 24 + treerec/tests/test_recipes/recipe_WF_Y.slim | 24 + treerec/tests/test_recipes/recipe_WF_Z.slim | 24 + .../tests/test_recipes/recipe_WF_adds.slim | 32 ++ .../recipe_WF_no_substitutions.slim | 25 ++ treerec/tests/test_recipes/recipe_nonWF.slim | 34 ++ .../tests/test_recipes/recipe_nonWF_H.slim | 34 ++ .../tests/test_recipes/recipe_nonWF_X.slim | 35 ++ .../tests/test_recipes/recipe_nonWF_Y.slim | 35 ++ .../recipe_nonWF_substitutions.slim | 36 ++ treerec/tests/test_trait_consistency.py | 226 ++++++++++ treerec/tests/uv.lock | 410 ++++++++++++++++++ 23 files changed, 1104 insertions(+), 12 deletions(-) create mode 100644 treerec/tests/test_recipes/recipe_WF.slim create mode 100644 treerec/tests/test_recipes/recipe_WF_H.slim create mode 100644 treerec/tests/test_recipes/recipe_WF_HF.slim create mode 100644 treerec/tests/test_recipes/recipe_WF_HM.slim create mode 100644 treerec/tests/test_recipes/recipe_WF_W.slim create mode 100644 treerec/tests/test_recipes/recipe_WF_X.slim create mode 100644 treerec/tests/test_recipes/recipe_WF_Y.slim create mode 100644 treerec/tests/test_recipes/recipe_WF_Z.slim create mode 100644 treerec/tests/test_recipes/recipe_WF_adds.slim create mode 100644 treerec/tests/test_recipes/recipe_WF_no_substitutions.slim create mode 100644 treerec/tests/test_recipes/recipe_nonWF.slim create mode 100644 treerec/tests/test_recipes/recipe_nonWF_H.slim create mode 100644 treerec/tests/test_recipes/recipe_nonWF_X.slim create mode 100644 treerec/tests/test_recipes/recipe_nonWF_Y.slim create mode 100644 treerec/tests/test_recipes/recipe_nonWF_substitutions.slim create mode 100644 treerec/tests/test_trait_consistency.py create mode 100644 treerec/tests/uv.lock diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 177dcc99a..374f18a46 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -85,9 +85,10 @@ jobs: # treerec/tests/environment.yml has not changed CACHE_NUMBER: 0 id: cache - - name: Update environment - run: conda env update -n anaconda-client-env -f treerec/tests/environment.yml + - name: Install uv and dependencies if: steps.cache.outputs.cache-hit != 'true' + run: | + pip install uv - name: Workaround for gcc-11 if: startsWith(matrix.os, 'ubuntu') && matrix.gcc == 11 run: | @@ -122,7 +123,7 @@ jobs: conda activate anaconda-client-env && \ export PATH=$PATH:$PWD/Release && \ echo $PATH && \ - cd treerec/tests && python -m pytest -xv + cd treerec/tests && uv run pytest -xv tests-Windows-CLI: if: github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository == 'messerlab/slim') @@ -178,12 +179,12 @@ jobs: - uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 with: activate-environment: anaconda-client-env - environment-file: treerec/tests/environment.yml pkgs-dirs: D:\conda_pkgs_dir - - name: Update environment + - name: Install uv and dependencies shell: bash -el {0} - run: conda env update -n anaconda-client-env -f treerec/tests/environment.yml if: steps.cache.outputs.cache-hit != 'true' + run: | + pip install uv - name: Build and test (Debug) run: | cd windows_compat/gnulib && \ @@ -210,9 +211,10 @@ jobs: shell: bash -el {0} run: | conda activate anaconda-client-env && \ + pip install git+https://github.com/tskit-dev/pyslim@main && \ export PATH=$PATH:$PWD/Release && \ echo $PATH && \ - cd treerec/tests && python -m pytest -xv + cd treerec/tests && uv run pytest -xv tests-Unix-GUI: if: github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository == 'messerlab/slim') diff --git a/treerec/tests/README.md b/treerec/tests/README.md index ad71e4862..59078dd95 100644 --- a/treerec/tests/README.md +++ b/treerec/tests/README.md @@ -72,5 +72,8 @@ To add a new test: add individuals to the saved list by calling `addIndividuals(individuals)` at any point in the simulation. + * Ensure that tree sequences are written to subdirectories! If there are no subdirectories + then nothing will happen. + To temporarily turn off a test just comment out the appropriate line in `recipe_specs.py` diff --git a/treerec/tests/conftest.py b/treerec/tests/conftest.py index ffb08b974..a70c1764b 100644 --- a/treerec/tests/conftest.py +++ b/treerec/tests/conftest.py @@ -40,12 +40,11 @@ def get_ts(self): # binary print("******** Binary input.") bin_ts = load_file_or_dir(os.path.join(self.dir, "test_output.trees")) - yield bin_ts # and nonsimplified binary print("******** Unsimplified binary.") bin_nonsimp_ts = load_file_or_dir( os.path.join(self.dir, "test_output.unsimplified.trees")) - yield bin_nonsimp_ts + return (bin_ts, bin_nonsimp_ts) @staticmethod def get_slim_ids(ts): @@ -154,11 +153,13 @@ def make_result(run_dir): SLiM recipes are expected to output their results into a set of directories within the run_dir: return a list of results, one for each subdirectory """ - return [ + out = [ OutputResult(os.path.join(run_dir, f.name)) for f in os.scandir(run_dir) if f.is_dir() ] + assert len(out) > 0 + return out def run_slim(recipe, run_dir, recipe_dir="test_recipes"): """ diff --git a/treerec/tests/init.slim b/treerec/tests/init.slim index 52fa390ee..c84d42ec0 100644 --- a/treerec/tests/init.slim +++ b/treerec/tests/init.slim @@ -30,6 +30,19 @@ function (void)initializeMarks(i$ num_marks) return; } +function (void)saveTreeSeqTraits(void) { + MD = Dictionary(); + for (mt in sim.mutationTypes) { + MD.setValue("m" + mt.id, Dictionary( + "convertToSubstitution", mt.convertToSubstitution + )); + } + sim.demandPhenotype(sim.subpopulations); + setwdForGen(); + sim.treeSeqOutput("test_output.trees", metadata=Dictionary("mutation_types", MD)); + sim.treeSeqOutput("test_output.unsimplified.trees", simplify=F); +} + function (void)saveTreeSeq(void) { // create tree seq representation in various formats: this could overwrite any // existing ones output in the same cycle, but they should be identical diff --git a/treerec/tests/pyproject.toml b/treerec/tests/pyproject.toml index ed2fd28ab..ca6a3d2f6 100644 --- a/treerec/tests/pyproject.toml +++ b/treerec/tests/pyproject.toml @@ -4,9 +4,9 @@ version = "0.1.0" requires-python = ">=3.13" dependencies = [ "filelock>=3.32.4", - "msprime>=1.2.0", + "msprime>=1.4.4", "numpy>=2.5.2", - "pyslim>=1.0.4", + "pyslim @ git+https://github.com/tskit-dev/pyslim@main", "pytest>=9.1.1", "pytest-xdist>=3.8.0", "setuptools>=84.0.0", diff --git a/treerec/tests/recipe_specs.py b/treerec/tests/recipe_specs.py index 6b1e3a7a3..5d7d32bd1 100644 --- a/treerec/tests/recipe_specs.py +++ b/treerec/tests/recipe_specs.py @@ -50,6 +50,21 @@ "test_836_output from multiple-chromosome models.slim": {"mutations": True, "individuals": True}, "test_169_complex multi-chromosome inheritance.slim": {"mutations": True, "individuals": True}, "test_1610_modeling pseudo-autosomal regions.slim": {"mutations": True, "individuals": True}, + "recipe_WF.slim": {"traits": True}, + "recipe_WF_adds.slim": {"traits": True}, + "recipe_WF_no_substitutions.slim": {"traits": True}, + "recipe_WF_H.slim": {"traits": True}, + "recipe_WF_HF.slim": {"traits": True}, + "recipe_WF_HM.slim": {"traits": True}, + "recipe_WF_W.slim": {"traits": True}, + "recipe_WF_X.slim": {"traits": True}, + "recipe_WF_Y.slim": {"traits": True}, + "recipe_WF_Z.slim": {"traits": True}, + "recipe_nonWF.slim": {"traits": True}, + "recipe_nonWF_substitutions.slim": {"traits": True}, + "recipe_nonWF_H.slim": {"traits": True}, + "recipe_nonWF_X.slim": {"traits": True}, + "recipe_nonWF_Y.slim": {"traits": True}, } diff --git a/treerec/tests/test_recipes/recipe_WF.slim b/treerec/tests/test_recipes/recipe_WF.slim new file mode 100644 index 000000000..0471c8916 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_WF.slim @@ -0,0 +1,24 @@ +initialize() +{ + setSeed(23); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(timeUnit="generations"); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.1); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +30 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_WF_H.slim b/treerec/tests/test_recipes/recipe_WF_H.slim new file mode 100644 index 000000000..a73464c64 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_WF_H.slim @@ -0,0 +1,23 @@ +initialize() +{ + setSeed(23); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(timeUnit="generations"); + source("init.slim"); + initializeChromosome(1, 100, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.1); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +30 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_WF_HF.slim b/treerec/tests/test_recipes/recipe_WF_HF.slim new file mode 100644 index 000000000..0471c8916 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_WF_HF.slim @@ -0,0 +1,24 @@ +initialize() +{ + setSeed(23); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(timeUnit="generations"); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.1); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +30 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_WF_HM.slim b/treerec/tests/test_recipes/recipe_WF_HM.slim new file mode 100644 index 000000000..0471c8916 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_WF_HM.slim @@ -0,0 +1,24 @@ +initialize() +{ + setSeed(23); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(timeUnit="generations"); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.1); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +30 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_WF_W.slim b/treerec/tests/test_recipes/recipe_WF_W.slim new file mode 100644 index 000000000..0471c8916 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_WF_W.slim @@ -0,0 +1,24 @@ +initialize() +{ + setSeed(23); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(timeUnit="generations"); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.1); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +30 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_WF_X.slim b/treerec/tests/test_recipes/recipe_WF_X.slim new file mode 100644 index 000000000..0471c8916 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_WF_X.slim @@ -0,0 +1,24 @@ +initialize() +{ + setSeed(23); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(timeUnit="generations"); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.1); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +30 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_WF_Y.slim b/treerec/tests/test_recipes/recipe_WF_Y.slim new file mode 100644 index 000000000..0471c8916 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_WF_Y.slim @@ -0,0 +1,24 @@ +initialize() +{ + setSeed(23); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(timeUnit="generations"); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.1); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +30 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_WF_Z.slim b/treerec/tests/test_recipes/recipe_WF_Z.slim new file mode 100644 index 000000000..0471c8916 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_WF_Z.slim @@ -0,0 +1,24 @@ +initialize() +{ + setSeed(23); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(timeUnit="generations"); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.1); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +30 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_WF_adds.slim b/treerec/tests/test_recipes/recipe_WF_adds.slim new file mode 100644 index 000000000..b17598909 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_WF_adds.slim @@ -0,0 +1,32 @@ +initialize() +{ + setSeed(37); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(timeUnit="generations"); + source("init.slim"); + initializeSex(); + defineConstant("L", 1); + initializeChromosome(1, L, "A", "A"); + initializeMutationRate(0.99); + initializeMutationType("m1", NAN, "f", 0.01); + initializeMutationType("m2", NAN, "f", 0.01); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, L-1); + initializeRecombinationRate(1e-2); +} + +1 early() { + sim.addSubpop("p1", 7); +} + +1 late() { + hap = sample(p1.haplosomes, 1); + loc = sample(0:(L-1), 1); + hap.addNewDrawnMutation(m2, loc); +} + +30 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_WF_no_substitutions.slim b/treerec/tests/test_recipes/recipe_WF_no_substitutions.slim new file mode 100644 index 000000000..2138f6146 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_WF_no_substitutions.slim @@ -0,0 +1,25 @@ +initialize() +{ + setSeed(23); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(timeUnit="generations"); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.1); + m1.convertToSubstitution = F; + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +30 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_nonWF.slim b/treerec/tests/test_recipes/recipe_nonWF.slim new file mode 100644 index 000000000..e6693ea6c --- /dev/null +++ b/treerec/tests/test_recipes/recipe_nonWF.slim @@ -0,0 +1,34 @@ +initialize() +{ + setSeed(23); + initializeSLiMModelType("nonWF"); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(); + source("init.slim"); + initializeChromosome(1, 1000, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", 0.001); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 999); + initializeRecombinationRate(1e-2); + defineConstant("K", 10); +} + +reproduction(NULL) { + mate = subpop.sampleIndividuals(1); + subpop.addCrossed(individual, mate); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +early() { + p1.fitnessScaling = K / p1.individualCount; +} + +100 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_nonWF_H.slim b/treerec/tests/test_recipes/recipe_nonWF_H.slim new file mode 100644 index 000000000..bb9ea23c5 --- /dev/null +++ b/treerec/tests/test_recipes/recipe_nonWF_H.slim @@ -0,0 +1,34 @@ +initialize() +{ + setSeed(23); + initializeSLiMModelType("nonWF"); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(); + source("init.slim"); + initializeChromosome(1, 100, "H", "H"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.001); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); + defineConstant("K", 10); +} + +reproduction() { + mate = subpop.sampleIndividuals(1); + subpop.addCrossed(individual, mate); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +early() { + p1.fitnessScaling = K / p1.individualCount; +} + +100 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_nonWF_X.slim b/treerec/tests/test_recipes/recipe_nonWF_X.slim new file mode 100644 index 000000000..2b488b5ba --- /dev/null +++ b/treerec/tests/test_recipes/recipe_nonWF_X.slim @@ -0,0 +1,35 @@ +initialize() +{ + setSeed(23); + initializeSLiMModelType("nonWF"); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "X", "X"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.001); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); + defineConstant("K", 10); +} + +reproduction(NULL, "F") { + mate = subpop.sampleIndividuals(1, sex="M"); + subpop.addCrossed(individual, mate); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +early() { + p1.fitnessScaling = K / p1.individualCount; +} + +100 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_nonWF_Y.slim b/treerec/tests/test_recipes/recipe_nonWF_Y.slim new file mode 100644 index 000000000..2567b6c2f --- /dev/null +++ b/treerec/tests/test_recipes/recipe_nonWF_Y.slim @@ -0,0 +1,35 @@ +initialize() +{ + setSeed(23); + initializeSLiMModelType("nonWF"); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "Y", "Y"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.001); + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); + defineConstant("K", 20); +} + +reproduction(NULL, "F") { + mate = subpop.sampleIndividuals(1, sex="M"); + subpop.addCrossed(individual, mate); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +early() { + p1.fitnessScaling = K / p1.individualCount; +} + +100 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_recipes/recipe_nonWF_substitutions.slim b/treerec/tests/test_recipes/recipe_nonWF_substitutions.slim new file mode 100644 index 000000000..3827044fc --- /dev/null +++ b/treerec/tests/test_recipes/recipe_nonWF_substitutions.slim @@ -0,0 +1,36 @@ +initialize() +{ + setSeed(23); + initializeSLiMModelType("nonWF"); + initializeSLiMOptions(keepPedigrees=T); + initializeTreeSeq(); + source("init.slim"); + initializeSex(); + initializeChromosome(1, 100, "A", "A"); + initializeMutationRate(1e-2); + initializeMutationType("m1", 0.5, "f", -0.001); + m1.convertToSubstitution = T; + initializeGenomicElementType("g1", m1, 1.0); + initializeGenomicElement(g1, 0, 99); + initializeRecombinationRate(1e-2); + defineConstant("K", 10); +} + +reproduction(NULL, "F") { + mate = subpop.sampleIndividuals(1, sex="M"); + subpop.addCrossed(individual, mate); +} + +1 early() { + sim.addSubpop("p1", 10); +} + +early() { + p1.fitnessScaling = K / p1.individualCount; +} + +100 late() { + saveTreeSeqTraits(); + catn("Done."); + sim.simulationFinished(); +} diff --git a/treerec/tests/test_trait_consistency.py b/treerec/tests/test_trait_consistency.py new file mode 100644 index 000000000..344af1ffd --- /dev/null +++ b/treerec/tests/test_trait_consistency.py @@ -0,0 +1,226 @@ +import tskit, pyslim +import numpy as np +import pytest +from collections import Counter + +from recipe_specs import recipe_eq + +class TraitCalculator: + """ + Calculating phenotypes by hand from metadata takes a good bit of + internal state, especially if it's from a multi-chromosome simulation, + so here's a class that does it. See below for how to use this. + """ + + def __init__(self, ts): + self.ts_metadata = None + self.slim_phenotypes = None + self.offsets = None + self.add_ts(ts) + + def add_ts(self, ts): + ts_metadata = ts.metadata + if self.ts_metadata is not None: + assert ts_metadata["SLiM"]["traits"] == self.ts_metadata["SLiM"]["traits"] + self.ts_metadata = ts_metadata + self.ts = ts + chrom_type = self.ts_metadata["SLiM"]["this_chromosome"]["type"] + self.haploid_chromosome = chrom_type in ("H", "HF", "HM") + self.mut_metadata = pyslim.mutation_metadata(ts) + self.nodes_vacant = pyslim.nodes_vacant(ts) + self.num_traits = len(self.ts_metadata["SLiM"]["traits"]) + self.types = [m["type"] for m in self.ts_metadata["SLiM"]["traits"]] + self.accumulates = [ + m["baselineAccumulation"] for m in self.ts_metadata["SLiM"]["traits"] + ] + # to properly do traits in the case where baselineAccumulation=F and there are + # mutation types with convertToSubstitution=T then we need to store this in metadata: + # (so, this code won't work if this is not present for such traits, which are probably + # only the default trait!) + if ( + "user_metadata" in ts_metadata["SLiM"] + and "mutation_types" in ts_metadata["SLiM"]["user_metadata"] + ): + self.mutation_types = { + k: v[0]["convertToSubstitution"][0] + for k, v in ts_metadata["SLiM"]["user_metadata"]["mutation_types"][ + 0 + ].items() + } + else: + # guess T if there just a single trait without baseline accumulation + # whose name is simT and this is a WF model + # since that describes "default trait" + convert = ( + self.ts_metadata["SLiM"]["model_type"] == "WF" + and len(self.ts_metadata["SLiM"]["traits"]) == 1 + and self.ts_metadata["SLiM"]["traits"][0]["name"] == "simT" + and self.ts_metadata["SLiM"]["traits"][0]["baselineAccumulation"] + == False + ) + print("convert!", convert) + mtypes = set(md["mutation_type"] for md in self.mut_metadata.values()) + self.mutation_types = {f"m{k}": convert for k in mtypes} + sp = np.column_stack( + [ + self.ts.tables.individuals.metadata_vector(["per_trait", j, "phenotype"]) + for j in range(self.num_traits) + ] + ) + if self.slim_phenotypes is None: + self.slim_phenotypes = sp + assert np.all(self.slim_phenotypes == sp) + # initialize phenotypes where we'll accumulate changes + self.phenotypes = np.full( + self.slim_phenotypes.shape, + [1.0 if t == "multiplicative" else 0.0 for t in self.types], + dtype="float", + ) + offsets = np.column_stack( + [ + self.ts.tables.individuals.metadata_vector(["per_trait", j, "offset"]) + for j in range(self.num_traits) + ] + ) + if self.offsets is None: + self.offsets = offsets + # only do offsets if this is the first ts! + self.do_offsets() + else: + assert np.all(offsets == self.offsets) + self.get_frequencies() + self.do_effects() + + def transform(self): + for k, t in enumerate(self.types): + if t == "logistic": + self.phenotypes[:, k] = 1 / (1 + np.exp(-self.phenotypes[:, k])) + + def is_converted(self, a): + # is allele a from a convert-to-substitution mutation type? + # if we haven't recorded whether or not it's converted, assume T + md = self.mut_metadata[int(a)] + return self.mutation_types[f"m{md['mutation_type']}"] + + def get_frequencies(self): + # Fixed mutations count unless they are converted to substitutions + # and baseline accumulation is off, so we need to look up both these things: + # (frequency, whether they're converted to substitutions) for each mutation. + self.frequencies = {} + for v in self.ts.variants(isolated_as_missing=False): + freqs = {} + for ds, f in v.counts().items(): + for a in ds.split(","): + if a != "": + if a not in freqs: + convert = self.is_converted(a) + freqs[a] = [0, convert] + freqs[a][0] += f + self.frequencies[v.site.id] = freqs + + def do_offsets(self): + for k, t in enumerate(self.types): + bO = self.ts_metadata["SLiM"]["traits"][k]["baselineOffsetFromUser"] + if t == "multiplicative": + self.phenotypes[:, k] *= bO * self.offsets[:, k] + else: + self.phenotypes[:, k] += bO + self.offsets[:, k] + + def do_effects(self): + for ind in self.ts.individuals(): + ploidy = np.sum(~self.nodes_vacant[ind.nodes]) + if ploidy == 0: + continue + else: + hemizygous = ploidy == 1 + for k, t in enumerate(self.types): + if t == "multiplicative": + g = self.multiplicative_effect(ind, k, hemizygous) + self.phenotypes[ind.id, k] *= g + else: + g = self.additive_effect(ind, k, hemizygous) + self.phenotypes[ind.id, k] += g + + def skip_mut(self, m, freqs, trait_id): + if m == "": + out = True + else: + f, convert = freqs[m] + out = f == 0 or (f == self.ts.num_samples and convert and not self.accumulates[trait_id]) + return out + + def additive_effect(self, ind, trait_id, hemizygous): + out = 0.0 + for v in self.ts.variants(samples=ind.nodes, isolated_as_missing=False): + freqs = self.frequencies[v.site.id] + a = ",".join([v.alleles[g] for g in v.genotypes]) + muts = Counter(a.split(",")) + for m in muts: + if self.skip_mut(m, freqs, trait_id): + continue + md = self.mut_metadata[int(m)]["per_trait"][trait_id] + s = md["effect_size"] + if muts[m] == 2: + h = 1 + else: + assert muts[m] == 1 + if self.haploid_chromosome: + h = 1 + else: + if hemizygous: + h = md["hemizygous_dominance"] + else: + h = md["dominance"] + if np.isnan(h): + h = 1 / 2 + out += 2 * h * s + return out + + def multiplicative_effect(self, ind, trait_id, hemizygous): + out = 1.0 + for v in self.ts.variants(samples=ind.nodes, isolated_as_missing=False): + freqs = self.frequencies[v.site.id] + a = ",".join([v.alleles[g] for g in v.genotypes]) + muts = Counter(a.split(",")) + for m in muts: + if self.skip_mut(m, freqs, trait_id): + continue + assert muts[m] > 0 and muts[m] <= 2 + md = self.mut_metadata[int(m)]["per_trait"][trait_id] + s = md["effect_size"] + if muts[m] == 2: + h = 1 + else: + assert muts[m] == 1 + if self.haploid_chromosome: + h = 1 + elif hemizygous: + h = md["hemizygous_dominance"] + else: + h = md["dominance"] + if np.isnan(h): + # "independent dominance occurs when (1+hs)(1+hs) equals 1+s, + # which occurs when h=(sqrt(1+s)−1)/s" + h = (np.sqrt(1 + s) - 1) / s if s != 0 else 0 + out *= 1 + h * s + return out + + +class TestTraits: + + @pytest.mark.parametrize("recipe", recipe_eq("traits"), indirect=True) + def test_traits_consistency(self, recipe): + assert len(recipe["results"]) > 0 + for result in recipe["results"]: + # note we don't have multi-chromosome sims here! + # see pyslim tests for that setup + ts = result.get_normal_ts() + assert ts.num_mutations > 0 + assert ts.num_individuals > 0 + # phenotypes as computed by us + tc = TraitCalculator(ts) + tc.transform() + print(np.column_stack([tc.phenotypes, tc.slim_phenotypes, + tc.phenotypes - tc.slim_phenotypes])) + assert np.allclose(tc.phenotypes, tc.slim_phenotypes) + diff --git a/treerec/tests/uv.lock b/treerec/tests/uv.lock new file mode 100644 index 000000000..5b3bd90be --- /dev/null +++ b/treerec/tests/uv.lock @@ -0,0 +1,410 @@ +version = 1 +revision = 3 +requires-python = ">=3.13" + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "demes" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "ruamel-yaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f2/e3/9171b92732305162916d299b3286dc0532669f17ddf9915656bc22539e5a/demes-0.2.3.tar.gz", hash = "sha256:9e613b65b475dba277bca751de1f37a89fd5eb4d856ba27733a2099c8a823617", size = 103269, upload-time = "2023-05-04T19:33:41.913Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/e2/7520ba6ae29d7923a1d1710ad210a2eb8264c40c9dbd3a72f3c4a7be157a/demes-0.2.3-py3-none-any.whl", hash = "sha256:e92455d30bd600bed21ed74583e2b952b4dbc074a7434a9a2d8adecf6fb187d5", size = 40883, upload-time = "2023-05-04T19:33:40.247Z" }, +] + +[[package]] +name = "execnet" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" }, +] + +[[package]] +name = "filelock" +version = "3.32.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/30/03b03951873a1a0ffc7e8ca0e10c15597b59e8d0e39260704cd2ea087bc4/filelock-3.32.4.tar.gz", hash = "sha256:2bde2e4cf732e0153406d8a7bc80620ecf5e621fe0d25e41143c4e3b4733ff30", size = 222126, upload-time = "2026-08-23T17:37:55.363Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/a4/9b63d595d748e3aff8812b65eacc1a2c4bd90b7c2012e08e72373b4835eb/filelock-3.32.4-py3-none-any.whl", hash = "sha256:22e58ca3b1ae3b98993b762d7338367ae64fe50252bf78d59da3bfebcdf1cedd", size = 99864, upload-time = "2026-08-23T17:37:53.913Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "msprime" +version = "1.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "demes" }, + { name = "newick" }, + { name = "numpy" }, + { name = "tskit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/c7/1efd44e6aa35c9dfb743c8bf4772aa34a560d817bd9e43f5fdedf7afbbd0/msprime-1.4.4.tar.gz", hash = "sha256:54deb6be3d80f2d9fa03b7f039883024cdebdb14851a890a12650d7ad6fec568", size = 2279231, upload-time = "2026-09-01T17:28:43.248Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/7c/b671f1b8df51d484554e54a840464066d49a55f8aa2525311b5ecd6b3370/msprime-1.4.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4aa0f711c580c5fb456187c86d35fa0664f93233489e34c5376b0a60bcb3731a", size = 1292332, upload-time = "2026-09-01T17:28:31.937Z" }, + { url = "https://files.pythonhosted.org/packages/14/00/cef00569466f8463dc5226373966dfb0a5ed494e0065fac7eb1d4265ab7b/msprime-1.4.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:9de6ff01895b8441b33d84be4878bfa2e141b33ed407734f816bd22bea8f2664", size = 1517646, upload-time = "2026-09-01T17:28:33.448Z" }, + { url = "https://files.pythonhosted.org/packages/06/27/e01a2f9beb28cada4ee6a38f0f5effcfbcf7e60c1c0f98d36bbbc92d0eb5/msprime-1.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5b7a03694919f6dec884b8c6d5c0b75b883d50e1513c7481b9e65aaba79c0162", size = 2451275, upload-time = "2026-09-01T17:28:34.802Z" }, + { url = "https://files.pythonhosted.org/packages/f4/48/571be07b65bd390a3eff6154a02c2a89005c0c759b9fc4bbfa4ec9957f84/msprime-1.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:3624a47e6990182436d81874798280af6012bbc0df805a639c06bb29fe451252", size = 1587433, upload-time = "2026-09-01T17:28:36.136Z" }, + { url = "https://files.pythonhosted.org/packages/95/53/0cc73d0eb1bbedfed1c47aae82e7c4cacac9f007709cfc69b2918cc3c73b/msprime-1.4.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:2c33a07a3500dc4639f45919146e19119ee330c7c3a04d5cfdca4bca081956c3", size = 1292350, upload-time = "2026-09-01T17:28:37.745Z" }, + { url = "https://files.pythonhosted.org/packages/cd/a1/4db2c85787a27a75469b9e58543a560061e0bd49ff697bfff8549821c5e9/msprime-1.4.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:5b5c4f4f0589b94ca7231df9ce55c262aa1fd5828f41898e53aac97a61960444", size = 1517392, upload-time = "2026-09-01T17:28:38.975Z" }, + { url = "https://files.pythonhosted.org/packages/c9/cf/25e534ac2a8880b8ee5f9bc4c2de774c84924b2f97a91c1389760e16c39e/msprime-1.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b3a5ba03a1611a00683423791d28fdac55070a3bad2df4e1883512f1c537763", size = 2451222, upload-time = "2026-09-01T17:28:40.439Z" }, + { url = "https://files.pythonhosted.org/packages/ce/50/445a5be595fca098efd4b22ed69c0ae5583a9be09d40f07111b3c317f04f/msprime-1.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:c3decb4069fc91db286e1736ebabdf669e5fa483107ab810381f097062c0d569", size = 1641591, upload-time = "2026-09-01T17:28:41.817Z" }, +] + +[[package]] +name = "newick" +version = "1.11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/75/71/6adc60734e7366b5c45332a21193020acc89a4f4391f037e1fc7d368917f/newick-1.11.0.tar.gz", hash = "sha256:b8bf81f88dbc0e1cb85928e6f4c7e0e29062c3739e27216aae76c3065a297186", size = 25426, upload-time = "2026-01-14T11:19:53.065Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/3f/66348a0ff595970ad226d7d5b1583d94486ea64e9e12c434f5d1dd3b3606/newick-1.11.0-py2.py3-none-any.whl", hash = "sha256:c431976e33ea9166d6bf87394408086ce616930a5a434a30883220dee547d6eb", size = 15782, upload-time = "2026-01-14T11:19:51.454Z" }, +] + +[[package]] +name = "numpy" +version = "2.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/80/db0b4559e57ec36362bedbb05530a87fafbcb6067708c946967a41d449e7/numpy-2.5.2.tar.gz", hash = "sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860", size = 20773161, upload-time = "2026-08-09T13:48:27.962Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f5/d2/6b24738a0ef4557d189b150046cd07823c50e4273e8aebd651222e24306f/numpy-2.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8e4cb9a754c8a0c62eaa88273a5fba3391f4a610d1dee893c0755da31c083f15", size = 16886595, upload-time = "2026-08-09T13:45:27.323Z" }, + { url = "https://files.pythonhosted.org/packages/65/60/f2d208d366f263f39c6e69ed309290717aab41078b6d04c9be2a84fa2a07/numpy-2.5.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:52c808f96484f5571a5cc863775ce50247c17dfb3b0361f8ed6b4b0456f80080", size = 11896845, upload-time = "2026-08-09T13:45:31.638Z" }, + { url = "https://files.pythonhosted.org/packages/3c/79/81e0bf24f4d020a2b1d5cd297a9f60c3f24eeb116f9bba5870443f7b6a4a/numpy-2.5.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:29d81e97f668489cba8ebfd796b9bdd453525d35dd9e162e2daec94bf3fc7740", size = 5343880, upload-time = "2026-08-09T13:45:34.373Z" }, + { url = "https://files.pythonhosted.org/packages/ba/cc/e3141cf06d1a8a2c7e107543fe1269c1d1af760d4d683c0794a4ee1127c2/numpy-2.5.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afb3f0632d6b2e3ba04dbce8d1e48d321b369138b73830b5ca371a0e8d479d56", size = 6682264, upload-time = "2026-08-09T13:45:36.7Z" }, + { url = "https://files.pythonhosted.org/packages/29/f1/2a64a307d92c5d98f5255a4014eb43bb6103ee477087b61ecae44a3aa9b9/numpy-2.5.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0aadf13b60048d501e05fa699efaf7734e2494f3498a4c2a5521d822640324f3", size = 15609566, upload-time = "2026-08-09T13:45:39.518Z" }, + { url = "https://files.pythonhosted.org/packages/7b/44/59a1eb68e773c4098d107ef34a0dbdeca501d72ffcfbff9a7707343921ce/numpy-2.5.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29b86ff8a6cc556b47ec6b64b194815cc80e6bf5eedcc6cddfd65318cb0b4eee", size = 16709995, upload-time = "2026-08-09T13:45:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/8a/4c/3e54d4ddbc359a1295f8b633e8106bcd4d7d4a206e82df051bdfb3058755/numpy-2.5.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6950c4b7dd562453090548ba7f5da7e59f57f85663f15d5dcc60e249192f7e59", size = 16972511, upload-time = "2026-08-09T13:45:47.094Z" }, + { url = "https://files.pythonhosted.org/packages/f2/9f/02e371638ebf19b66d46231e4be52999e87f32d1961b113bc45656608b22/numpy-2.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b9727f472d2f3888053b8a75ab0cb94745a9de224bb5846dbadc0092101bc71d", size = 18465609, upload-time = "2026-08-09T13:45:50.808Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ae/ad6645abc7a3510fe48e8ea1ab4598166f500057ef4ebf38bfad4f1577de/numpy-2.5.2-cp313-cp313-win32.whl", hash = "sha256:4f9744f9fbdcea0bc552e8f19e1f141f811a3f9bc2be2cc6e86d982cab23e3f4", size = 6070204, upload-time = "2026-08-09T13:45:54.111Z" }, + { url = "https://files.pythonhosted.org/packages/15/20/f3489f86d81ea460b2bcdceaed094142ca6579f6be0ec527b781d39afe68/numpy-2.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:85aaccb24182c25df891ad0ec333585967e115269d5f1b17f2c9ae005bc96657", size = 12460532, upload-time = "2026-08-09T13:45:57.167Z" }, + { url = "https://files.pythonhosted.org/packages/d5/21/35b31dde1b283b79de828b80f876afd8c94e28fe1e9c375f89e261cc4c0d/numpy-2.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:bd68ece1553d2023c09a4226d9e41c586ad2d20594d1a456186c33513d2cb3f2", size = 10396725, upload-time = "2026-08-09T13:46:00.478Z" }, + { url = "https://files.pythonhosted.org/packages/ac/f8/c3b222bf075b50afd8e949a07a15c4b312a4a84bd8102a332bcd953cbbb4/numpy-2.5.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1", size = 16885180, upload-time = "2026-08-09T13:46:03.939Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/2c1d4b1987795a92b5bbf7c24fe249ab96aa2573ab0d7604802c189d7b86/numpy-2.5.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8", size = 11907878, upload-time = "2026-08-09T13:46:07.045Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ee/d08226fc858044355983a6e5b94f08ff6f3969e0a2b160a4a89f0ddb3445/numpy-2.5.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323", size = 5354922, upload-time = "2026-08-09T13:46:10.04Z" }, + { url = "https://files.pythonhosted.org/packages/94/f0/6d3d933056440ebbc5e6bad92065fc6c26a48a84a36b1208580e94eea76c/numpy-2.5.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e", size = 6679168, upload-time = "2026-08-09T13:46:12.275Z" }, + { url = "https://files.pythonhosted.org/packages/c4/3b/ecd49dd90033cceb2704d88ca905d4d7d89b0e8c739608754ffd325fa820/numpy-2.5.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65", size = 15624501, upload-time = "2026-08-09T13:46:15.322Z" }, + { url = "https://files.pythonhosted.org/packages/c7/99/461bd36dbdfac6c1c53efa370bd55a83227542d0d118f1677dbf1a3dacd5/numpy-2.5.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee", size = 16713701, upload-time = "2026-08-09T13:46:18.949Z" }, + { url = "https://files.pythonhosted.org/packages/f9/9c/2b251df9e8a5d647b62b0cbc1b90a91850c1cf4859ecb532fd0b4eacff6c/numpy-2.5.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68", size = 16986065, upload-time = "2026-08-09T13:46:23.006Z" }, + { url = "https://files.pythonhosted.org/packages/8f/25/20de43f53ff1390534a124475055a19f01fe10c920a0fd11b8e18d6d6052/numpy-2.5.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb", size = 18470031, upload-time = "2026-08-09T13:46:27.102Z" }, + { url = "https://files.pythonhosted.org/packages/56/5e/0c577ca308d6da5eb79b546ba10bbe5b60148192194e2da060913b1de4f1/numpy-2.5.2-cp314-cp314-win32.whl", hash = "sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98", size = 6121028, upload-time = "2026-08-09T13:46:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/15/5c/7bcbd5b11f94199073320410cddcbb80cee62415bfeb540874b265c2d922/numpy-2.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d", size = 12597627, upload-time = "2026-08-09T13:46:32.886Z" }, + { url = "https://files.pythonhosted.org/packages/87/bc/4d0b06fba0da90ccc75af62823cb9dcedb6c9ea0cffa058cb2c9ee773a77/numpy-2.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf", size = 10680414, upload-time = "2026-08-09T13:46:36.036Z" }, + { url = "https://files.pythonhosted.org/packages/cd/17/f429aac9dc08833a0d0f188eba38c532a751b1a1f2ca6018a37b455cb321/numpy-2.5.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1", size = 12026967, upload-time = "2026-08-09T13:46:39.084Z" }, + { url = "https://files.pythonhosted.org/packages/ca/9f/d0849de96a2a4ceaa16662f18ee13eaa9c0aa418269fdc8c4857c56b11da/numpy-2.5.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f", size = 5473874, upload-time = "2026-08-09T13:46:42.075Z" }, + { url = "https://files.pythonhosted.org/packages/89/3c/8df216d4a4a5422a3de045301cf7df8ea47286d76f5cb7160b0128ac26b7/numpy-2.5.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf", size = 6789276, upload-time = "2026-08-09T13:46:44.387Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3a/20d7e9891c4ddfadd6ff8d95bf4b29f353d8e1770553de2099880551dfb9/numpy-2.5.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4", size = 15659154, upload-time = "2026-08-09T13:46:47.538Z" }, + { url = "https://files.pythonhosted.org/packages/aa/d6/f3aa3d2688bf501b858835c6bd087ae9b51a56ae6fca8e2b0990abd177af/numpy-2.5.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce", size = 16748909, upload-time = "2026-08-09T13:46:51.442Z" }, + { url = "https://files.pythonhosted.org/packages/7d/8f/1c5cae8d2baf86ab802ae97a00be55bc7e21ebc11b12bbc33376c5f05342/numpy-2.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26", size = 17027685, upload-time = "2026-08-09T13:46:55.095Z" }, + { url = "https://files.pythonhosted.org/packages/5c/27/71d3467404aedc1c24ce79610f91b52b0b0f466c43a701aa56fc75c145ab/numpy-2.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac", size = 18501181, upload-time = "2026-08-09T13:46:59.09Z" }, + { url = "https://files.pythonhosted.org/packages/14/2f/42921d27c40aea7e077f4a423ae509fd9220b028cd787bafefd8ab2b3a5f/numpy-2.5.2-cp314-cp314t-win32.whl", hash = "sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba", size = 6271085, upload-time = "2026-08-09T13:47:01.903Z" }, + { url = "https://files.pythonhosted.org/packages/75/e6/bad5f5d56de9b1971bac959963dda276d35c40f1854475005434bbe08692/numpy-2.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884", size = 12787971, upload-time = "2026-08-09T13:47:04.963Z" }, + { url = "https://files.pythonhosted.org/packages/df/05/f608795cb34391acd67e38d94a3c36abd8d8576293a3a80727d7595c372c/numpy-2.5.2-cp314-cp314t-win_arm64.whl", hash = "sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e", size = 10750306, upload-time = "2026-08-09T13:47:07.976Z" }, + { url = "https://files.pythonhosted.org/packages/33/c6/28de0191c5f82b7d42a0a51390ba98587048aa93a39fafb05bdbe6e8d00c/numpy-2.5.2-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f", size = 16885274, upload-time = "2026-08-09T13:47:11.439Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d1/973ca116000d244897e468ea1aff30b589e5022e3c8744b71706fe33bd57/numpy-2.5.2-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842", size = 11907846, upload-time = "2026-08-09T13:47:15.128Z" }, + { url = "https://files.pythonhosted.org/packages/78/d9/8c4b3937ef204cb2fd88d389ccd0f265a2ffb11f35a01d2064cf46714bd6/numpy-2.5.2-cp315-cp315-macosx_14_0_arm64.whl", hash = "sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6", size = 5354892, upload-time = "2026-08-09T13:47:18.07Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/b6ee65ea2999fdb7023935e108e6fb776ee4082aa15f159acfa857e578c8/numpy-2.5.2-cp315-cp315-macosx_14_0_x86_64.whl", hash = "sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8", size = 6679309, upload-time = "2026-08-09T13:47:20.456Z" }, + { url = "https://files.pythonhosted.org/packages/43/f3/acb18d8b137a393c8e7803a8c994c9e64bde3930692a69d826993113a159/numpy-2.5.2-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69", size = 15625850, upload-time = "2026-08-09T13:47:24.365Z" }, + { url = "https://files.pythonhosted.org/packages/a9/bf/a8e9bb0db815a0e265b5744ebedd3af0bd5faad8604e5b50a1cd012f3c91/numpy-2.5.2-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab", size = 16713664, upload-time = "2026-08-09T13:47:27.965Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c3/6e913736b3dd6582344af32418b5fb9dab34282e8a8174ae1d54ceb0fc13/numpy-2.5.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514", size = 16986749, upload-time = "2026-08-09T13:47:31.541Z" }, + { url = "https://files.pythonhosted.org/packages/80/09/7d3b23eff5c7428ef6c01e6f7052bb60d504c4d33e317b36b8959c24ad97/numpy-2.5.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710", size = 18470495, upload-time = "2026-08-09T13:47:35.364Z" }, + { url = "https://files.pythonhosted.org/packages/a5/a4/68a321d825374f6eb677ffe8ef8c6b9a328304e6fd2e39d9530822776607/numpy-2.5.2-cp315-cp315-win32.whl", hash = "sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617", size = 6120696, upload-time = "2026-08-09T13:47:38.561Z" }, + { url = "https://files.pythonhosted.org/packages/c8/23/deafbb1700f79fae9cd1e91220f133d124cc267de1b584da3fbf6db2f6cd/numpy-2.5.2-cp315-cp315-win_amd64.whl", hash = "sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7", size = 12597324, upload-time = "2026-08-09T13:47:41.401Z" }, + { url = "https://files.pythonhosted.org/packages/33/cd/3272ba105e3bbbdaeb11357eda31e7a6825ffe159e8171665660299a948f/numpy-2.5.2-cp315-cp315-win_arm64.whl", hash = "sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788", size = 10680466, upload-time = "2026-08-09T13:47:44.873Z" }, + { url = "https://files.pythonhosted.org/packages/0e/0e/58370637b1bb70a5c9ce2b43f4b521ccb224e36ccb76a6596b17ae4b447c/numpy-2.5.2-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b", size = 16993947, upload-time = "2026-08-09T13:47:48.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/93/2abcb807712b289d6d60fe4cf30532f98974a8396d885650f3ba5a13026e/numpy-2.5.2-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e", size = 12025331, upload-time = "2026-08-09T13:47:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3a/2898e003a5fbaf87e76c039b4ee1f5eb390471b4ffe74887c1f34c4e791e/numpy-2.5.2-cp315-cp315t-macosx_14_0_arm64.whl", hash = "sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a", size = 5472336, upload-time = "2026-08-09T13:47:55.403Z" }, + { url = "https://files.pythonhosted.org/packages/61/a5/23f69d07c544597b29758b31b55c27dc9d541012a2c1496189fef702aec2/numpy-2.5.2-cp315-cp315t-macosx_14_0_x86_64.whl", hash = "sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8", size = 6788387, upload-time = "2026-08-09T13:47:58.192Z" }, + { url = "https://files.pythonhosted.org/packages/15/ea/c0dbdbcf22f43782510a3e492dd3da73c6112b69cac8929d16d127536fc4/numpy-2.5.2-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc", size = 15667096, upload-time = "2026-08-09T13:48:01.562Z" }, + { url = "https://files.pythonhosted.org/packages/fc/5e/29c73c31748cdb0f7566642125ba17fd5b56780cddf891b085dab27e4466/numpy-2.5.2-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec", size = 16751730, upload-time = "2026-08-09T13:48:05.706Z" }, + { url = "https://files.pythonhosted.org/packages/47/95/02501e8454796bb58dadf7a99d3181e0b464bf264e1003039572f9779fac/numpy-2.5.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0", size = 17038686, upload-time = "2026-08-09T13:48:09.627Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b5/53a681d91b5c82687067d8ea5035e02d917b5509d6f334cb06484a954714/numpy-2.5.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2", size = 18507727, upload-time = "2026-08-09T13:48:13.744Z" }, + { url = "https://files.pythonhosted.org/packages/42/06/6e11443f7b64ee376c860506091103bf68f92d2cab9e8d96d4501babf07c/numpy-2.5.2-cp315-cp315t-win32.whl", hash = "sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251", size = 6269775, upload-time = "2026-08-09T13:48:17.543Z" }, + { url = "https://files.pythonhosted.org/packages/f1/18/195d6b86cd72dbbc501edfa778005fa6b87afd34c153e46028cd3a0938f4/numpy-2.5.2-cp315-cp315t-win_amd64.whl", hash = "sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12", size = 12782559, upload-time = "2026-08-09T13:48:21.023Z" }, + { url = "https://files.pythonhosted.org/packages/b4/07/458c344f0f0c178f4481dad5cca790626ffe4c34eabf9467069d06ee4999/numpy-2.5.2-cp315-cp315t-win_arm64.whl", hash = "sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e", size = 10748103, upload-time = "2026-08-09T13:48:24.21Z" }, +] + +[[package]] +name = "packaging" +version = "26.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pygments" +version = "2.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" }, +] + +[[package]] +name = "pyslim" +version = "1.1.2.dev19" +source = { git = "https://github.com/tskit-dev/pyslim?rev=main#d24770c3236d1f2356a2cf80b0fed6e6b7649b9b" } +dependencies = [ + { name = "msprime" }, + { name = "numpy" }, + { name = "tskit" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "pytest-xdist" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "execnet" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, +] + +[[package]] +name = "rpds-py" +version = "2026.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/9e/b818ee580026ec578138e961027a68820c40afeb1ec8f6819b54fb99e196/rpds_py-2026.6.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3cfe765c1da0072636ca06628261e0ea05688e160d5c8a03e0217c3854037223", size = 343012, upload-time = "2026-06-30T07:15:36.005Z" }, + { url = "https://files.pythonhosted.org/packages/f3/6b/686d9dc4359a8f163cfbbf89ee0b4e586431de22fe8248edb63a8cf50d49/rpds_py-2026.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4d78253f6996be4901669ad25319f842f740eccf4d58e3c7f3dd39e6dde1d8f", size = 338203, upload-time = "2026-06-30T07:15:37.462Z" }, + { url = "https://files.pythonhosted.org/packages/9e/9b/069aa329940f8207615e091f5eedbbd40e1e15eac68a0790fd05ccdf796c/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f", size = 367984, upload-time = "2026-06-30T07:15:39.008Z" }, + { url = "https://files.pythonhosted.org/packages/14/db/34c203e4becff3703e4d3bc121842c00b8689197f398161203a880052f4e/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7", size = 374815, upload-time = "2026-06-30T07:15:40.253Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7d/8071067d2cc453d916ad836e828c943f575e8a44612537759002a1e07381/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6", size = 490545, upload-time = "2026-06-30T07:15:41.729Z" }, + { url = "https://files.pythonhosted.org/packages/a3/42/da06c5aa8f0484ff07f270787434204d9f4535e2f8c3b51ed402267e63c3/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af", size = 382828, upload-time = "2026-06-30T07:15:43.327Z" }, + { url = "https://files.pythonhosted.org/packages/57/d7/fe978efc2ae50abe48eb7464668ea99f53c010c60aeebb7b35ad27f23661/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf", size = 365678, upload-time = "2026-06-30T07:15:44.992Z" }, + { url = "https://files.pythonhosted.org/packages/69/9d/1d8922e1990b2a6eb532b6ff53d3e73d2b3bbffc84116c75826bee73dfc6/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885", size = 377811, upload-time = "2026-06-30T07:15:46.523Z" }, + { url = "https://files.pythonhosted.org/packages/b1/3d/198dceafb4fb034a6a47347e1b0735d34e0bd4a50be4e898d408ee66cb14/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4", size = 395382, upload-time = "2026-06-30T07:15:47.955Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f1/13968e49655d40b6b19d8b9140296bbc6f1d86b3f0f6c346cf9f1adddf4b/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7", size = 543832, upload-time = "2026-06-30T07:15:49.33Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ab/289bcb1b90bd3e40a2900c561fa0e2087345ecbb094f0b870f2345142b7c/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d", size = 611011, upload-time = "2026-06-30T07:15:50.847Z" }, + { url = "https://files.pythonhosted.org/packages/1e/16/5043105e679436ccfbc8e5e0dd2d663ed18a8b8113515fd06a5e5d77c83e/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97", size = 572431, upload-time = "2026-06-30T07:15:52.394Z" }, + { url = "https://files.pythonhosted.org/packages/85/ed/adab103321c0a6565d5ae1c2998349bc3ee175b82ccc5ae8fc04cc413075/rpds_py-2026.6.3-cp313-cp313-win32.whl", hash = "sha256:8c3d1e9c15b9d51ca0391e13da1a25a0a4df3c58a37c9dc368e0736cf7f69df0", size = 201710, upload-time = "2026-06-30T07:15:53.894Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/a03b09668e74e5dabbf2e211f6468e1820c0552f7b0500082da31841bf7b/rpds_py-2026.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:9250a9a0a6fd4648b3f868da8d91a4c52b5811a62df58e753d50ae4454a36f80", size = 219454, upload-time = "2026-06-30T07:15:55.25Z" }, + { url = "https://files.pythonhosted.org/packages/27/17/b8642c12930b71bc2b25831f6708ccf0f75abcd11883932ec9ce54ba3a78/rpds_py-2026.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:900a67df3fd1660b035a4761c4ce73c382ea6b35f90f9863c36c6fd8bf8b09bb", size = 215063, upload-time = "2026-06-30T07:15:56.573Z" }, + { url = "https://files.pythonhosted.org/packages/b6/36/7fbe9dcdaf857fb3f63c2a2284b62492d95f5e8334e947e5fb6e7f68c9be/rpds_py-2026.6.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:931908d9fc855d8f74783377822be318edb6dcb19e47169dc038f9a1bf60b06e", size = 344510, upload-time = "2026-06-30T07:15:57.921Z" }, + { url = "https://files.pythonhosted.org/packages/ba/54/f785cc3d3f60839ca57a5af4927a9f347b07b2799c373fc20f7949f87c7e/rpds_py-2026.6.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7469697dce35be237db177d42e2a2ee26e6dcc5fc052078a6fefabd288c6edd", size = 339495, upload-time = "2026-06-30T07:15:59.238Z" }, + { url = "https://files.pythonhosted.org/packages/63/ef/d4cdaf309e6b095b43597103cf8c0b951d6cca2acce68c474f75ec12e0c7/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcfbcf66006befb9fd2aeaa9e01feaf881b4dc330a02ba07d2322b1c11be7b5d", size = 369454, upload-time = "2026-06-30T07:16:01.021Z" }, + { url = "https://files.pythonhosted.org/packages/96/4a/9559a68b7ee15db09d7981212e8c2e219d2a1d6d4faa0391d813c3496a36/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847927daf4cffbd4e90e42bc890069897101edd015f956cb8721b3473372edda", size = 374583, upload-time = "2026-06-30T07:16:02.287Z" }, + { url = "https://files.pythonhosted.org/packages/ef/75/8964aa7d2c6e8ac43eba8eb6e6b0fdda1f46d39f2fc3e6aa9f2cb17f485d/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c1ef08a82bfe327cc156da694660f599923e2e6665b6d81c9c2d0ac9ffc8", size = 492919, upload-time = "2026-06-30T07:16:03.723Z" }, + { url = "https://files.pythonhosted.org/packages/8f/97/6908094ac804115e65aedfd90f1b5fee4eebebd3f6c4cfc5419939267565/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae50181a047c871561212bb97f7932a2d45fb53e947bd9b57ebad85b529cbc53", size = 383725, upload-time = "2026-06-30T07:16:05.305Z" }, + { url = "https://files.pythonhosted.org/packages/d1/9c/0d1fdc2e7aba23e290d603bc494e97bd205bae262ce33c6b32a69768ed5e/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc319e5a1de4b6913aac94bf6a2f9e847371e0a140a43dd4991db1a09bc2d504", size = 367255, upload-time = "2026-06-30T07:16:07.086Z" }, + { url = "https://files.pythonhosted.org/packages/c4/fe/f0209ca4a9ed074bc8acb44dfd0e81c3122e94c9689f5645b7973a866719/rpds_py-2026.6.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e4316bf32babbed84e691e352faf967ce2f0f024174a8643c37c94a1080374fc", size = 379060, upload-time = "2026-06-30T07:16:08.525Z" }, + { url = "https://files.pythonhosted.org/packages/c6/8d/f1cc54c616b9d8897de8738aac148d20afca93f68187475fe194d09a71b9/rpds_py-2026.6.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8c6e5a2f750cc71c3e3b11d71661f21d6f9bc6cebc6564b1466417a1ec03ec77", size = 395960, upload-time = "2026-06-30T07:16:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/fb/04/aafff00f73aeca2945f734f1d483c64ab8f472d0864ab02377fd8e89c3b2/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4470ce197d4090875cf6affbf1f853338387428df97c4fb7b7106317b8214698", size = 545356, upload-time = "2026-06-30T07:16:11.816Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cc/e229663b9e4ddac5a4acbe9085dd80a71af2a5d356b8b39d6bff233f24b0/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea964164cc9afa72d4d9b23cc28dafae93693c0a53e0b42acbff15b22c3f9ddd", size = 612319, upload-time = "2026-06-30T07:16:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7a/8a0e6d3e6cd066af108b71b43122c3fe158dd9eb86acac626593a2582eb1/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:639c8929aa0afe81be836b04de888460d6bed38b9c54cfc18da8f6bfabf5af5d", size = 573508, upload-time = "2026-06-30T07:16:15.23Z" }, + { url = "https://files.pythonhosted.org/packages/87/03/2a69ab618a789cf6cf85c86bb844c62d090e700ab1a2aa676b3741b6c516/rpds_py-2026.6.3-cp314-cp314-win32.whl", hash = "sha256:882076c00c0a608b131187055ddc5ae29f2e7eaf870d6168980420d58528a5c8", size = 202504, upload-time = "2026-06-30T07:16:16.893Z" }, + { url = "https://files.pythonhosted.org/packages/85/62/a3892ba945f4e24c78f352e5de3c7620d8479f73f211406a97263d13c7d2/rpds_py-2026.6.3-cp314-cp314-win_amd64.whl", hash = "sha256:0be972be84cfcaf46c8c6edf690ca0f154ac17babf1f6a955a51579b34ad2dc5", size = 220380, upload-time = "2026-06-30T07:16:18.108Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e7/c2bd44dc831931815ad11ebb5f430b5a0a4d3caa9de837107876c30c3432/rpds_py-2026.6.3-cp314-cp314-win_arm64.whl", hash = "sha256:2a9c6f195058cb45335e8cc3802745c603d716eb96bc9625950c1aac71c0c703", size = 215976, upload-time = "2026-06-30T07:16:19.654Z" }, + { url = "https://files.pythonhosted.org/packages/79/9c/fff7b74bce9a091ec9a012a03f9ff5f69364eaf9451060dfc4486da2ffdd/rpds_py-2026.6.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:f90938e92afda60266da758ee7d363447f7f0138c9559f9e1811629580582d90", size = 346840, upload-time = "2026-06-30T07:16:21.268Z" }, + { url = "https://files.pythonhosted.org/packages/e9/44/77bcb1168b33704908295533d27f10eb811e9e3e193e8993dc99572211d3/rpds_py-2026.6.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec829541c45bca16e61c7ae50c20501f213605beb75d1aba91a6ee37fbbb56a4", size = 340282, upload-time = "2026-06-30T07:16:22.875Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/7a9081c7c9e645b39efe19e4ffbeccd80add246327cd9b888aecffd72317/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd70d95892096cdb26f15a00c45907b17817577aa8d1c76b2dcc2788391f9e9", size = 370403, upload-time = "2026-06-30T07:16:24.415Z" }, + { url = "https://files.pythonhosted.org/packages/f7/69/af47021eb7dad6ff3396cb001c08f0f3c4d06c20253f75be6421a59fe6b7/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29dfa0533a5d4c94d4dfa1b694fcb56c9c63aad8330ffdd816fd225d0a7a162f", size = 376055, upload-time = "2026-06-30T07:16:26.111Z" }, + { url = "https://files.pythonhosted.org/packages/81/fc/a3bcf517084396a6dd258c592567a3c011ba4557f2fde23dceaf26e74f2e/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af05d726809bff6b141be124d4c7ce998f9c9c7f30edb1f46c07aa103d540b41", size = 494419, upload-time = "2026-06-30T07:16:27.596Z" }, + { url = "https://files.pythonhosted.org/packages/c9/eb/13d529d1788135425c7bf207f8463458ca5d92e43f3f701365b83e9dffc1/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9826217f048f620d9a712672818bf231442c1b35d96b227a07eabd11b4bb6945", size = 384848, upload-time = "2026-06-30T07:16:29.183Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f4/b7ac49f30013aba8f7b9566b1dd07e81de95e708c1374b7bacc5b9bc5c9c/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536bceea4fa4acf7e1c61da2b5786304367c816c8895be71b8f537c480b0ea1f", size = 371369, upload-time = "2026-06-30T07:16:30.912Z" }, + { url = "https://files.pythonhosted.org/packages/31/86/6260bafa622f788b07ddec0e52d810305c8b9b0b8c27f58a2ab04bf62b4f/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:bc0011654b91cc4fb2ae701bec0a0ba1e552c0714247fa7af6c59e0ccfa3a4e1", size = 379673, upload-time = "2026-06-30T07:16:32.486Z" }, + { url = "https://files.pythonhosted.org/packages/19/c3/03f1ee79a047b48daeca157c89a18509cde22b6b951d642b9b0af1be660a/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:539d75de9e0d536c84ff18dfeb805398e58227001ce09231a26a08b9aed1ee0e", size = 397500, upload-time = "2026-06-30T07:16:34.471Z" }, + { url = "https://files.pythonhosted.org/packages/f0/95/8ed0cd8c377dca12aea498f119fe639fc474d1461545c39d2b5872eb1c0f/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:166cf54d9f44fc6ceb53c7860258dde44a81406646de79f8ed3234fca3b6e538", size = 545978, upload-time = "2026-06-30T07:16:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f2/0eb57f0eaa83f8fc152a7e03de968ab77e1f00732bebc892b190c6eebde7/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d34c20167764fbcf927194d532dd7e0c56772f0a5f943fa5ef9e9afbba8fb9db", size = 613350, upload-time = "2026-06-30T07:16:38.213Z" }, + { url = "https://files.pythonhosted.org/packages/5b/de/e0674bdbc3ef7634989b3f854c3f34bc1f587d36e5bfdc5c378d57034619/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea7bb13b7c9a29791f87a0387ba7d3ad3a6d783d827e4d3f27b40a0ff44495e2", size = 576486, upload-time = "2026-06-30T07:16:39.797Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f6/21101359743cd136ada781e8210a85769578422ba460672eea0e29739200/rpds_py-2026.6.3-cp314-cp314t-win32.whl", hash = "sha256:6de4744d05bd1aa1be4ed7ea1189e3979196808008113bbbf899a460966b925e", size = 201068, upload-time = "2026-06-30T07:16:41.316Z" }, + { url = "https://files.pythonhosted.org/packages/a6/b2/9574d4d44f7760c2aa32d92a0a4f41698e33f5b204a0bf5c9758f52c79d5/rpds_py-2026.6.3-cp314-cp314t-win_amd64.whl", hash = "sha256:c7b9a2f8f4d8e90af72571d3d495deebdd7e3c75451f5b41719aee166e940fc2", size = 220600, upload-time = "2026-06-30T07:16:43.091Z" }, + { url = "https://files.pythonhosted.org/packages/08/ae/f23a2697e6ee6340a578b0f136be6483657bef0c6f9497b752bb5c0964bb/rpds_py-2026.6.3-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:e059c5dde6452b44424bd1834557556c226b57781dee1227af23518459722b13", size = 344726, upload-time = "2026-06-30T07:16:44.5Z" }, + { url = "https://files.pythonhosted.org/packages/c3/63/e7b3a1a5358dd32c930a1062d8e15b67fd6e8922e81df9e91706d66ee5c8/rpds_py-2026.6.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2f7c26fbc5acd2522b95d4177fe4710ffd8e9b20529e703ffbf8db4d93903f05", size = 339587, upload-time = "2026-06-30T07:16:46.255Z" }, + { url = "https://files.pythonhosted.org/packages/ec/64/10a85681916ca55fffb91b0a211f84e34297c109243484dd6394660a8a7c/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3086b538543802f84c843911242db20447de00d8752dd0efc936dbcf02218ba", size = 369585, upload-time = "2026-06-30T07:16:48.101Z" }, + { url = "https://files.pythonhosted.org/packages/76/c2/baf95c7c38823e12ba34407c5f5767a89e5cf2233895e56f608167ae9493/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2e5c5ee828d42cb11760761c0af6507927bec42d0ad5458f97c9203b054617", size = 375479, upload-time = "2026-06-30T07:16:49.93Z" }, + { url = "https://files.pythonhosted.org/packages/6a/94/0aad06c72d65101e11d33528d438cda99a39ce0da99466e156158f2541d3/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0c1e5d10cdc7135537988c74a0188da68e2f3c30813ba3744ab1e42e0480f9", size = 492418, upload-time = "2026-06-30T07:16:51.641Z" }, + { url = "https://files.pythonhosted.org/packages/b5/17/de3f5a479a1f056535d7489819639d8cd591ea6281d700390b43b1abd745/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c2642a7603ec0b16ed77da4555db3b4b472341904873788327c0b0d7b95f1bb", size = 384123, upload-time = "2026-06-30T07:16:53.622Z" }, + { url = "https://files.pythonhosted.org/packages/46/7d/bf09bd1b145bb2671c03e1e6d1ab8651858d90d8c7dfeadd85a37a934fd8/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4320744c1ffdd95a603def63344bfab2d33edeab301c5007e7de9f9f5b3885", size = 367351, upload-time = "2026-06-30T07:16:55.241Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ea/1bb734f314b8be319149ddee80b18bd41372bdcfbdf88d28131c0cd37719/rpds_py-2026.6.3-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:a9f4645593036b81bbdb36b9c8e0ea0d1c3fee968c4d59db0344c14087ef143a", size = 378827, upload-time = "2026-06-30T07:16:56.841Z" }, + { url = "https://files.pythonhosted.org/packages/4b/93/d9611e5b25e26df9a3649813ed66193ace9347a7c7fc4ab7cf70e94851c0/rpds_py-2026.6.3-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e55d236be29255554da47abe5c577637db7c24a02b8b46f0ca9524c855801868", size = 395966, upload-time = "2026-06-30T07:16:58.557Z" }, + { url = "https://files.pythonhosted.org/packages/c3/cb/99d77e16e5534ae1d90629bbe419ba6ee170833a6a85e3aa1cc41726fbbc/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:24e9c5386e16669b674a69c156c8eeefcb578f3b3397b713b08e6d60f3c7b187", size = 545680, upload-time = "2026-06-30T07:17:00.164Z" }, + { url = "https://files.pythonhosted.org/packages/59/15/11a29755f790cef7a2f755e8e14f4f0c33f39489e1893a632a2eee59672b/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c60924535c75f1566b6eb75b5c31a48a43fef04fa2d0d201acbad8a9969c6107", size = 611853, upload-time = "2026-06-30T07:17:01.962Z" }, + { url = "https://files.pythonhosted.org/packages/68/86/0c27547e21644da938fb530f7e1a8148dd24d02db07e7a5f2567a17ce710/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:38a2fea2787428f811719ceb9114cb78964a3138838320c29ac39526c79c16ba", size = 573715, upload-time = "2026-06-30T07:17:03.693Z" }, + { url = "https://files.pythonhosted.org/packages/29/71/4d8fcf700931815594bce892255bbd973b94efaf0fc1932b0590df18d886/rpds_py-2026.6.3-cp315-cp315-win32.whl", hash = "sha256:d483fe17f01ad64b7bf7cc38fcefff1ca9fb83f8c2b2542b68f97ffe0611b369", size = 202864, upload-time = "2026-06-30T07:17:05.746Z" }, + { url = "https://files.pythonhosted.org/packages/eb/62/b577562de0edbb55b2be85ce5fd09c33e386b9b13eee09833af4240fd5c4/rpds_py-2026.6.3-cp315-cp315-win_amd64.whl", hash = "sha256:67e3a721ffc5d8d2210d3671872298c4a84e4b8035cfe42ffd7cde35d772b146", size = 220430, upload-time = "2026-06-30T07:17:07.471Z" }, + { url = "https://files.pythonhosted.org/packages/c8/95/d6d0b2509825141eef60669a5739eec88dbc6a48053d6c92993a5704defe/rpds_py-2026.6.3-cp315-cp315-win_arm64.whl", hash = "sha256:6e84adbcf4bf841aed8116a8264b9f50b4cb3e7bd89b516122e616ac56ca269e", size = 215877, upload-time = "2026-06-30T07:17:09.008Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bf/f3ea278f0afd615c1d0f19cb69043a41526e2bb600c2b536eb192218eb27/rpds_py-2026.6.3-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:ae6dd8f10bd17aad820876d24caec9efdafd80a318d16c0a48edb5e136902c6b", size = 346933, upload-time = "2026-06-30T07:17:10.762Z" }, + { url = "https://files.pythonhosted.org/packages/9d/29/9907bdf1c5346763cf10b7f6852aad86652168c259def904cbe0082c5864/rpds_py-2026.6.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bdbd97738551fca3917c1bd7188bec1920bb520104f28e7e1007f9ceb17b7690", size = 340274, upload-time = "2026-06-30T07:17:12.266Z" }, + { url = "https://files.pythonhosted.org/packages/6f/2c/8e03767b5778ef25cebf74a7a91a2c3806f8eced4c92cb7406bbe060756d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b95977e7211527ab0ba576e286d023389fbeeb32a6b7b771665d333c60e5342", size = 370763, upload-time = "2026-06-30T07:17:14.107Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e1/df2a7e1ba2efd796af26194250b8d42c821b46592311595162af9ef0528d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15fde0e6fb0d88a60d221204873743e5d9f0b7d29165e62cd86d0413ad74ba6", size = 376467, upload-time = "2026-06-30T07:17:15.76Z" }, + { url = "https://files.pythonhosted.org/packages/6b/de/8a0814d1946af29cb068fb259aa8622f856df1d0bab58429448726b537f5/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a136d453475ac0fcbda502ef1e6504bd28d6d904700915d278deeab0d00fe140", size = 496689, upload-time = "2026-06-30T07:17:17.308Z" }, + { url = "https://files.pythonhosted.org/packages/df/f3/f19e0c852ba13694f5a79f3b719331051573cb5693feacf8a88ffffc3a71/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f826877d462181e5eb1c26a0026b8d0cab05d99844ecb6d8bf3627a2ca0c0442", size = 385340, upload-time = "2026-06-30T07:17:18.928Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ae/7ec3a9d2d4351f99e37bcb06b6b6f954512646bfdbf9742e1de727865daf/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79486287de1730dbaff3dbd124d0ca4d2ef7f9d29bf2544f1f93c09b5bcbbd12", size = 372179, upload-time = "2026-06-30T07:17:20.539Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ac/9cee911dff2aaa9a5a8354f6610bf2e6a616de9197c5fff4f54f82585f1e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:808345f53cb952433ca2816f1604ff3515608a81784954f38d4452acfe8e61d5", size = 379993, upload-time = "2026-06-30T07:17:22.212Z" }, + { url = "https://files.pythonhosted.org/packages/83/6b/7c2a07ba88d1e9a936612f7a5d067467ed03d971d5a06f7d309dff044a7e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1967debc37f64f2c4dc90a7f563aec558b471966e12adcac4e1c4240496b6ebf", size = 398909, upload-time = "2026-06-30T07:17:23.66Z" }, + { url = "https://files.pythonhosted.org/packages/97/0b/776ffcb66783637b0031f6d58d6fb55913c8b5abf00aeecd46bf933fb477/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f0840b5b17057f7fd918b76183a4b5a0635f43e14eb2ce60dce1d4ee4707ea00", size = 546584, upload-time = "2026-06-30T07:17:25.264Z" }, + { url = "https://files.pythonhosted.org/packages/55/33/ba3bc04d7092bd553c9b2b195624992d2cc4f3de1f380b7b93cbee67bd79/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:faa679d19a6696fd54259ad321251ad77a13e70e03dd834daa762a44fb6196ef", size = 614357, upload-time = "2026-06-30T07:17:26.888Z" }, + { url = "https://files.pythonhosted.org/packages/8b/71/14edf065f04630b1a8472f7653cad03f6c478bcf95ea0e6aed55451e33ea/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:23a439f31ccbeff1574e24889128821d1f7917470e830cf6544dced1c662262a", size = 576533, upload-time = "2026-06-30T07:17:28.546Z" }, + { url = "https://files.pythonhosted.org/packages/ba/76/65002b08596c389105720a8c0d22298b8dc25a4baf89b2ce431343c8b1de/rpds_py-2026.6.3-cp315-cp315t-win32.whl", hash = "sha256:913ca42ccad3f8cc6e292b587ae8ae49c8c823e5dce51a736252fc7c7cdfa577", size = 201204, upload-time = "2026-06-30T07:17:30.193Z" }, + { url = "https://files.pythonhosted.org/packages/8c/97/d855d6b3c322d1f27e26f5241c42016b56cf01377ea8ed348285f54652f0/rpds_py-2026.6.3-cp315-cp315t-win_amd64.whl", hash = "sha256:ae3d4fe8c0b9213624fdce7279d70e3b148b682ca20719ebd193a23ebfa47324", size = 220719, upload-time = "2026-06-30T07:17:31.788Z" }, +] + +[[package]] +name = "ruamel-yaml" +version = "0.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/3b/ebda527b56beb90cb7652cb1c7e4f91f48649fbcd8d2eb2fb6e77cd3329b/ruamel_yaml-0.19.1.tar.gz", hash = "sha256:53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993", size = 142709, upload-time = "2026-01-02T16:50:31.84Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl", hash = "sha256:27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93", size = 118102, upload-time = "2026-01-02T16:50:29.201Z" }, +] + +[[package]] +name = "setuptools" +version = "84.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/44/f5da03a8ef95d369145c5bb53050e7877c9f3d312e128605fd9504829143/setuptools-84.0.0.tar.gz", hash = "sha256:f4695c21257f0d9b537ec2692c941d02ee143b7cc1276941349a546573b2ef73", size = 1168449, upload-time = "2026-08-08T18:27:58.365Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl", hash = "sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670", size = 818216, upload-time = "2026-08-08T18:27:56.719Z" }, +] + +[[package]] +name = "slim-python-tests" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "filelock" }, + { name = "msprime" }, + { name = "numpy" }, + { name = "pyslim" }, + { name = "pytest" }, + { name = "pytest-xdist" }, + { name = "setuptools" }, + { name = "tskit" }, +] + +[package.metadata] +requires-dist = [ + { name = "filelock", specifier = ">=3.32.4" }, + { name = "msprime", specifier = ">=1.4.4" }, + { name = "numpy", specifier = ">=2.5.2" }, + { name = "pyslim", git = "https://github.com/tskit-dev/pyslim?rev=main" }, + { name = "pytest", specifier = ">=9.1.1" }, + { name = "pytest-xdist", specifier = ">=3.8.0" }, + { name = "setuptools", specifier = ">=84.0.0" }, + { name = "tskit", specifier = ">=0.4.1" }, +] + +[[package]] +name = "tskit" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonschema" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/c23333b3ffd86cbe79520bbee85f050f815c16a625b014dbacbe486fb6c2/tskit-1.0.3.tar.gz", hash = "sha256:8a305b3bcf4145688be17962f6ea2ac20aa65db440ed0c02b49f9b4a3c00836b", size = 933435, upload-time = "2026-05-14T18:20:16.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/10/aa8cc65060669b911946649cd1802f29640998c5b6ca78c4c845fb3c473d/tskit-1.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d52e2ad0eb79e3b21da8a236d0f5eb888f9b18569e48f4b84a3875523e80ee22", size = 528459, upload-time = "2026-05-14T18:19:58.156Z" }, + { url = "https://files.pythonhosted.org/packages/eb/42/34d981123a335d80e3030e9b0a81a41f654c9cf1c5db0ac630d6b20d8bfd/tskit-1.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5bd1744a020a518e5835b85971fea14ca827d76f778650eb37e3f44c6db0a711", size = 496838, upload-time = "2026-05-14T18:19:59.909Z" }, + { url = "https://files.pythonhosted.org/packages/65/9c/09b072c01b8e58a3137011851d4761daf957f2f86447bc2a2c25e0d5aa4a/tskit-1.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:405c20fad5256edd6abd1f8b514c5bc653d808102f509c4512c9b174507dbe84", size = 1399080, upload-time = "2026-05-14T18:20:01.353Z" }, + { url = "https://files.pythonhosted.org/packages/d0/bb/789b91f7a2deca4d50f649b685e2b3dca4b3358e36bf7a5b2b84709bb8d5/tskit-1.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bc1c97f00ce8e79460aa9ff3b36987daf70f2dc267e36a32db77018dbefc822b", size = 1378631, upload-time = "2026-05-14T18:20:03.273Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8b/3b2b19246b2ba3159456e4068887e505d7a2ec857ecd7ae7606d6c129fda/tskit-1.0.3-cp313-cp313-win32.whl", hash = "sha256:53444ef3b2fd7ea9ca863e562c33402e46a55e645887dd4d983686b607e3f788", size = 449996, upload-time = "2026-05-14T18:20:04.788Z" }, + { url = "https://files.pythonhosted.org/packages/23/fc/53ef7ad8b3f2183584af81b0ff046a660c3164530a1f768770dbd4d60cb7/tskit-1.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:721ae7f02730ed91233a6da2a9d4b59632d1512877cd0d6fe948ea5d9ddc17e9", size = 496006, upload-time = "2026-05-14T18:20:06.577Z" }, + { url = "https://files.pythonhosted.org/packages/66/b9/91194216907ebf278d7a58288f3e64881e11a0eedcca7125a49e0bbdafdd/tskit-1.0.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:62a45d5e57f5a9181eb113c0dd478783ef3c4829856c0831ea2eba2cdf00a8de", size = 528594, upload-time = "2026-05-14T18:20:08.032Z" }, + { url = "https://files.pythonhosted.org/packages/6e/2c/0a888f4f140922c7a3945dbca5e444fa8052a620c784359673fe9eb1eda7/tskit-1.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8df716837129652fc82d095d80fd4e23a728213a4b18de9233f3aebb073b60b4", size = 496866, upload-time = "2026-05-14T18:20:09.34Z" }, + { url = "https://files.pythonhosted.org/packages/2f/ce/56aa69b768734ede0b8b36c5ea2ce842d50c786b74cfefdfc036a1fd29da/tskit-1.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:151eefbbae9a339f3ea64980937fa89d6ac9fb371dba880a9b30791a461753ad", size = 1397616, upload-time = "2026-05-14T18:20:10.762Z" }, + { url = "https://files.pythonhosted.org/packages/6e/5a/b05eab4a4a32bce6a51f991033ed460a836aafc1f406eebc624831558d9b/tskit-1.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2170cacd8ade47fd8f1510aca78549e09e9ba875c25496f0ccfb755e09c0b06b", size = 1377477, upload-time = "2026-05-14T18:20:12.649Z" }, + { url = "https://files.pythonhosted.org/packages/ea/c5/116419617468dc06428e507001d0a7b212116e9e8d336bd8c05a6531b2a0/tskit-1.0.3-cp314-cp314-win32.whl", hash = "sha256:24f8fffc1e1dd4154654e91bb7bac22078b3cadd9837e5c490225aa5c313b819", size = 455586, upload-time = "2026-05-14T18:20:14.165Z" }, + { url = "https://files.pythonhosted.org/packages/6e/7f/61818ed922629178abb07e45439d0af3bb5867b629fe392e9864df58ce5c/tskit-1.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:cbe791757cbd4d060a9c06c270bbcacc932f60ce1d77e98dcea35c931d0b0aa9", size = 505409, upload-time = "2026-05-14T18:20:15.527Z" }, +] From 6617a3d5ae71389b0b7bc4297011bbc356370ab4 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 3 Sep 2026 15:50:51 -0700 Subject: [PATCH 2/2] ditch conda for uv? --- .github/workflows/tests.yml | 77 +++++++++++-------------------------- 1 file changed, 23 insertions(+), 54 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 374f18a46..df22a4d3f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -62,38 +62,24 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Setup Miniforge - uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 + + - name: Install uv and set the python version + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: - miniforge-version: latest - activate-environment: anaconda-client-env - python-version: ${{ matrix.python }} + python-version: ${{ inputs.python-version }} + version: "0.10.0" + - name: Get Date id: get-date run: echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT shell: bash - - name: Cache Conda env - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: ${{ env.CONDA }}/envs - key: - conda-${{ runner.os }}--python-${{ matrix.python }}--${{ runner.arch }}--${{ - steps.get-date.outputs.today }}-${{ - hashFiles('treerec/tests/environment.yml') }}-${{ env.CACHE_NUMBER}} - env: - # Increase this value to reset cache if - # treerec/tests/environment.yml has not changed - CACHE_NUMBER: 0 - id: cache - - name: Install uv and dependencies - if: steps.cache.outputs.cache-hit != 'true' - run: | - pip install uv + - name: Workaround for gcc-11 if: startsWith(matrix.os, 'ubuntu') && matrix.gcc == 11 run: | sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && \ sudo apt-get update -y + - name: Set up default GCC (in Ubuntu) if: startsWith(matrix.os, 'ubuntu') run: | @@ -101,6 +87,7 @@ jobs: sudo update-alternatives \ --install /usr/bin/gcc gcc /usr/bin/gcc-${{ matrix.gcc }} 100 \ --slave /usr/bin/g++ g++ /usr/bin/g++-${{ matrix.gcc }} + - name: Build and test (Debug) run: | mkdir Debug && \ @@ -109,6 +96,7 @@ jobs: make -j 2 && \ # Show any output from the test program whenever the test fails env CTEST_OUTPUT_ON_FAILURE=1 make test + - name: Build and test (Release) run: | mkdir Release && \ @@ -117,10 +105,10 @@ jobs: make -j 2 && \ # Show any output from the test program whenever the test fails env CTEST_OUTPUT_ON_FAILURE=1 make test + - name: Treesequence tests shell: bash -el {0} run: | - conda activate anaconda-client-env && \ export PATH=$PATH:$PWD/Release && \ echo $PATH && \ cd treerec/tests && uv run pytest -xv @@ -138,8 +126,10 @@ jobs: run: shell: msys2 {0} steps: + - name: Check out repository code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Setup MSYS2 ${{matrix.sys}} uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2.32.0 with: @@ -151,40 +141,19 @@ jobs: msys2-devel mingw-w64-${{matrix.env}}-toolchain mingw-w64-${{matrix.env}}-cmake - - name: Setup Miniforge - uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 - with: - miniforge-version: latest - activate-environment: anaconda-client-env - auto-update-conda: true - python-version: ${{ matrix.python }} + - name: Get Date id: get-date run: echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT shell: bash - - name: Cache Conda env - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - env: - # Increase this value to reset cache if treerec/tests/environment.yml has not changed - CACHE_NUMBER: 0 - with: - # Use faster GNU tar - enableCrossOsArchive: true - path: D:\conda_pkgs_dir - key: - conda-${{ runner.os }}--python-${{ matrix.python }}--${{ runner.arch }}--${{ - steps.get-date.outputs.today }}-${{ - hashFiles('treerec/tests/environment.yml') }}-${{ env.CACHE_NUMBER}} - id: cache - - uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 - with: - activate-environment: anaconda-client-env - pkgs-dirs: D:\conda_pkgs_dir - - name: Install uv and dependencies + + - name: Install uv and set the python version + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 shell: bash -el {0} - if: steps.cache.outputs.cache-hit != 'true' - run: | - pip install uv + with: + python-version: ${{ inputs.python-version }} + version: "0.10.0" + - name: Build and test (Debug) run: | cd windows_compat/gnulib && \ @@ -196,6 +165,7 @@ jobs: make -j 2 && \ # Show any output from the test program whenever the test fails env CTEST_OUTPUT_ON_FAILURE=1 make test + - name: Build and test (Release) run: | cd windows_compat/gnulib && \ @@ -207,11 +177,10 @@ jobs: make -j 2 && \ # Show any output from the test program whenever the test fails env CTEST_OUTPUT_ON_FAILURE=1 make test + - name: Treesequence tests shell: bash -el {0} run: | - conda activate anaconda-client-env && \ - pip install git+https://github.com/tskit-dev/pyslim@main && \ export PATH=$PATH:$PWD/Release && \ echo $PATH && \ cd treerec/tests && uv run pytest -xv