Repository: cogent3/cogent3
Pull request #2030 (2024-10-04 00:01:06)

MAINT: new_moltype IUPAC symbol type consistency
[CHANGED] We had a tuple, list and frozen set between
    DNA, RNA and PROTEIN IUPAC characters! Now all are tuples,
    so their order is unchanged between runs and immutable.


Patch:
diff --git a/src/cogent3/core/new_moltype.py b/src/cogent3/core/new_moltype.py
index 6af06d3f3..c0222a45c 100644
--- a/src/cogent3/core/new_moltype.py
+++ b/src/cogent3/core/new_moltype.py
@@ -71,7 +71,7 @@ DNA_STANDARD_PAIRS = {
 }
 
 # note change in standard order from DNA
-IUPAC_RNA_chars = ["U", "C", "A", "G"]
+IUPAC_RNA_chars = "U", "C", "A", "G"
 IUPAC_RNA_ambiguities = {
     "N": frozenset(("A", "C", "U", "G")),
     "R": frozenset(("A", "G")),
@@ -265,68 +265,64 @@ IUPAC_PROTEIN_code_aa = {
     "*": "STOP",
 }
 
-IUPAC_PROTEIN_chars = frozenset(
-    [
-        "A",
-        "C",
-        "D",
-        "E",
-        "F",
-        "G",
-        "H",
-        "I",
-        "K",
-        "L",
-        "M",
-        "N",
-        "P",
-        "Q",
-        "R",
-        "S",
-        "T",
-        "U",
-        "V",
-        "W",
-        "Y",
-    ]
+IUPAC_PROTEIN_chars = (
+    "A",
+    "C",
+    "D",
+    "E",
+    "F",
+    "G",
+    "H",
+    "I",
+    "K",
+    "L",
+    "M",
+    "N",
+    "P",
+    "Q",
+    "R",
+    "S",
+    "T",
+    "U",
+    "V",
+    "W",
+    "Y",
 )
 
-PROTEIN_WITH_STOP_chars = frozenset(
-    [
-        "A",
-        "C",
-        "D",
-        "E",
-        "F",
-        "G",
-        "H",
-        "I",
-        "K",
-        "L",
-        "M",
-        "N",
-        "P",
-        "Q",
-        "R",
-        "S",
-        "T",
-        "U",
-        "V",
-        "W",
-        "Y",
-        "*",
-    ]
+PROTEIN_WITH_STOP_chars = (
+    "A",
+    "C",
+    "D",
+    "E",
+    "F",
+    "G",
+    "H",
+    "I",
+    "K",
+    "L",
+    "M",
+    "N",
+    "P",
+    "Q",
+    "R",
+    "S",
+    "T",
+    "U",
+    "V",
+    "W",
+    "Y",
+    "*",
 )
 
 IUPAC_PROTEIN_ambiguities = {
     "B": frozenset(["N", "D"]),
-    "X": IUPAC_PROTEIN_chars,
+    "X": frozenset(IUPAC_PROTEIN_chars),
     "Z": frozenset(["Q", "E"]),
 }
 
 PROTEIN_WITH_STOP_ambiguities = {
     "B": frozenset(["N", "D"]),
-    "X": PROTEIN_WITH_STOP_chars,
+    "X": frozenset(PROTEIN_WITH_STOP_chars),
     "Z": frozenset(["Q", "E"]),
 }
 


Test patch:
diff --git a/tests/test_core/test_new_moltype.py b/tests/test_core/test_new_moltype.py
index 96bf95197..c83ba2d6a 100644
--- a/tests/test_core/test_new_moltype.py
+++ b/tests/test_core/test_new_moltype.py
@@ -555,3 +555,20 @@ def test_degenerate_from_seq():
     assert p("ABD") == "X"
     assert p("ACX") == "X"
     assert p("AC-") == "?"
+
+
+@pytest.mark.parametrize(
+    "moltype,zero,second,last",
+    (
+        ("DNA", "T", "A", "G"),
+        ("RNA", "U", "A", "G"),
+        ("PROTEIN", "A", "D", "Y"),
+        ("PROTEIN_WITH_STOP", "A", "D", "*"),
+    ),
+)
+def test_char_order(moltype, zero, second, last):
+    prefix = "IUPAC_" if "STOP" not in moltype else ""
+    attr = getattr(new_moltype, f"{prefix}{moltype}_chars")
+    assert attr[0] == zero
+    assert attr[2] == second
+    assert attr[-1] == last