Repository: cogent3/cogent3
Pull request #2272 (2025-03-27 05:53:06)

REL: 2025.3.22a3


Patch:
diff --git a/README.md b/README.md
index 1597f8fee..ea5d18553 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,9 @@
 [![CodeQL](https://github.com/cogent3/cogent3/actions/workflows/codeql.yml/badge.svg)](https://github.com/cogent3/cogent3/actions/workflows/codeql.yml)
 [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e80e3441de59449bb1a4d8ad1fdea4fa)](https://app.codacy.com/gh/cogent3/cogent3/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
 
+[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.15067121.svg)](https://doi.org/10.5281/zenodo.15067121)
+
+
 `cogent3` is a mature python library for analysis of genomic sequence data. We endeavour to provide a first-class experience within Jupyter notebooks, but the algorithms also support parallel execution on compute systems with 1000's of processors.
 
 ## 📣 Feature Announcements 📣
@@ -46,8 +49,6 @@ Speaking of plugins, our first major third-party plugin is [piqtree](https://pyp
 
 </details>
 
-
-=
 ## Who is it for?
 
 ### Anyone who wants to analyse sequence divergence using robust statistical models
diff --git a/changelog.md b/changelog.md
index b2f825e8f..5897ae0b0 100755
--- a/changelog.md
+++ b/changelog.md
@@ -1,4 +1,15 @@
 
+<a id='changelog-2025.3.22a3'></a>
+# Changes in release "2025.3.22a3"
+
+This is a minor bug-fix release.
+
+## BUG
+
+- New type Alignment methods could fail when on a instance that
+  had sequences renamed. We were passing the incorrect values for
+  constructing the new AlignSeqsData instance.
+
 <a id='changelog-2025.3.22a2'></a>
 # Changes in release "2025.3.22a2"
 
diff --git a/pyproject.toml b/pyproject.toml
index 229c91f98..52deff16f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -50,7 +50,7 @@ Changelog = "https://github.com/cogent3/cogent3/blob/develop/changelog.md"
 
 [project.optional-dependencies]
 test = [
-    "ruff==0.11.0",
+    "ruff==0.11.2",
     "kaleido",
     "pandas",
     "plotly",
diff --git a/src/cogent3/_version.py b/src/cogent3/_version.py
index 9c1b5490a..202001e44 100644
--- a/src/cogent3/_version.py
+++ b/src/cogent3/_version.py
@@ -1,1 +1,1 @@
-__version__ = "2025.3.22a2"
+__version__ = "2025.3.22a3"
diff --git a/src/cogent3/core/new_alignment.py b/src/cogent3/core/new_alignment.py
index 7c545656a..21590e4eb 100644
--- a/src/cogent3/core/new_alignment.py
+++ b/src/cogent3/core/new_alignment.py
@@ -5061,7 +5061,7 @@ class Alignment(SequenceCollection):
         new = self.array_seqs[:, indices]
 
         new_seq_data = self._seqs_data.from_names_and_array(
-            names=self.names,
+            names=self._name_map.values(),
             data=new,
             alphabet=self.moltype.most_degen_alphabet(),
         )
@@ -5215,10 +5215,11 @@ class Alignment(SequenceCollection):
 
             motif_valid = indices.reshape(num_motif, motif_length).all(axis=1).flatten()
             indices = numpy.repeat(motif_valid, motif_length)
+
         selected = array_pos[indices].T
 
         aligned_seqs_data = self._seqs_data.from_names_and_array(
-            names=self.names,
+            names=self._name_map.values(),
             data=selected,
             alphabet=self.moltype.most_degen_alphabet(),
         )
@@ -5313,7 +5314,7 @@ class Alignment(SequenceCollection):
         selected = positions[indices, :].T
 
         aligned_seqs_data = self._seqs_data.from_names_and_array(
-            names=self.names,
+            names=self._name_map.values(),
             data=selected,
             alphabet=alpha,
         )


Test patch:
diff --git a/tests/test_core/test_new_alignment.py b/tests/test_core/test_new_alignment.py
index 930c8e514..2e5758a90 100644
--- a/tests/test_core/test_new_alignment.py
+++ b/tests/test_core/test_new_alignment.py
@@ -4682,7 +4682,8 @@ def test_filtered_drop_remainder():
     assert len(got) == 4
 
 
-def test_no_degenerates():
+@pytest.mark.parametrize("renamed", [True, False])
+def test_no_degenerates(renamed):
     """no_degenerates correctly excludes columns containing IUPAC ambiguity codes"""
     data = {
         "s1": "AAA CCC GGG TTT".replace(" ", ""),
@@ -4690,7 +4691,7 @@ def test_no_degenerates():
         "s3": "GGR YTT AAA CCC".replace(" ", ""),
     }
     aln = new_alignment.make_aligned_seqs(data, moltype="dna")
-
+    aln = aln.rename_seqs(lambda x: x.upper()) if renamed else aln
     # motif length of 1, defaults - no gaps allowed
     result = aln.no_degenerates().to_dict()
     expect = {
@@ -4698,6 +4699,7 @@ def test_no_degenerates():
         "s2": "CC GG TT AAA".replace(" ", ""),
         "s3": "GG TT AA CCC".replace(" ", ""),
     }
+    expect = {k.upper(): v for k, v in expect.items()} if renamed else expect
     assert result == expect
 
     # allow gaps
@@ -4707,6 +4709,7 @@ def test_no_degenerates():
         "s2": "CC GG T-T AAA".replace(" ", ""),
         "s3": "GG TT AAA CCC".replace(" ", ""),
     }
+    expect = {k.upper(): v for k, v in expect.items()} if renamed else expect
     assert result == expect
 
     # motif length of 3, defaults - no gaps allowed
@@ -4716,6 +4719,7 @@ def test_no_degenerates():
         "s2": "AAA".replace(" ", ""),
         "s3": "CCC".replace(" ", ""),
     }
+    expect = {k.upper(): v for k, v in expect.items()} if renamed else expect
     assert result == expect
 
     # allow gaps
@@ -4725,8 +4729,12 @@ def test_no_degenerates():
         "s2": "T-T AAA".replace(" ", ""),
         "s3": "AAA CCC".replace(" ", ""),
     }
+    expect = {k.upper(): v for k, v in expect.items()} if renamed else expect
     assert result == expect
 
+
+@pytest.mark.parametrize("renamed", [True, False])
+def test_no_degenerates_non_divisible_length(renamed):
     # for length non-divisible by motif_length
     data = {
         "s1": "AAA CCC GGG TTT T".replace(" ", ""),
@@ -4734,12 +4742,15 @@ def test_no_degenerates():
         "s3": "GGR YTT AAA CCC C".replace(" ", ""),
     }
     aln = new_alignment.make_aligned_seqs(data, moltype="dna")
+    aln = aln.rename_seqs(lambda x: x.upper()) if renamed else aln
     result = aln.no_degenerates(motif_length=3, allow_gap=False).to_dict()
     expect = {
         "s1": "TTT".replace(" ", ""),
         "s2": "AAA".replace(" ", ""),
         "s3": "CCC".replace(" ", ""),
     }
+    expect = {k.upper(): v for k, v in expect.items()} if renamed else expect
+    assert result == expect
 
 
 def test_no_degenerates_bad_moltype_raises():
@@ -4749,7 +4760,8 @@ def test_no_degenerates_bad_moltype_raises():
         _ = aln.no_degenerates()
 
 
-def test_omit_gap_pos_motif_length():
+@pytest.mark.parametrize("renamed", [True, False])
+def test_omit_gap_pos_motif_length(renamed):
     """consistency with different motif_length values"""
     data = {
         "seq1": "CAGGTCGACCTCGGC---------CACGAC",
@@ -4760,6 +4772,7 @@ def test_omit_gap_pos_motif_length():
         "seq6": "GCC---------------------------",
     }
     aln = new_alignment.make_aligned_seqs(data, moltype="dna")
+    aln = aln.rename_seqs(lambda x: x.upper()) if renamed else aln
     got1 = aln.omit_gap_pos(motif_length=1)
     got3 = aln.omit_gap_pos(motif_length=3)
     assert len(got3) == len(got1)