File support-new-biopython.patch of Package python-pymol

From 575ca59625944287c80675464d10cec343fc8a45 Mon Sep 17 00:00:00 2001
From: Thomas Holder <thomas@thomas-holder.de>
Date: Sat, 31 May 2025 19:46:52 +0200
Subject: [PATCH] Eliminate two Biopython deprecation warnings

- Bio.pairwise2 has been deprecated
  -> Use Bio.Align.PairwiseAligner instead
- SeqRecord constructor: Using a string as the sequence is deprecated
  -> Convert to Seq

The changes are based on
https://github.com/speleo3/pymol-psico/blob/ae2b92c262bc/psico/seqalign.py
---
 modules/pymol/seqalign.py | 39 ++++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/modules/pymol/seqalign.py b/modules/pymol/seqalign.py
index d938a3978..45e4928a8 100644
--- a/modules/pymol/seqalign.py
+++ b/modules/pymol/seqalign.py
@@ -11,6 +11,25 @@
 
 from pymol import cmd, CmdException
 
+import functools
+from typing import TYPE_CHECKING
+
+if TYPE_CHECKING:
+    import Bio.Align
+
+
+@functools.cache
+def _get_aligner_BLOSUM62() -> "Bio.Align.PairwiseAligner":
+    from Bio.Align import PairwiseAligner, substitution_matrices
+    blosum62 = substitution_matrices.load("BLOSUM62")
+    missing_codes = ''.join(set('JUO-.?').difference(blosum62.alphabet))
+    blosum62 = blosum62.select(blosum62.alphabet + missing_codes)
+    aligner = PairwiseAligner(internal_open_gap_score=-10,
+                              extend_gap_score=-.5,
+                              substitution_matrix=blosum62)
+    assert aligner.mode == "global"
+    return aligner
+
 
 def needle_alignment(s1, s2):
     '''
@@ -19,26 +38,16 @@ def needle_alignment(s1, s2):
     Does a Needleman-Wunsch Alignment of sequence s1 and s2 and
     returns a Bio.Align.MultipleSeqAlignment object.
     '''
-    from Bio import pairwise2
     from Bio.Align import MultipleSeqAlignment
     from Bio.SeqRecord import SeqRecord
-    try:
-        from Bio.Align import substitution_matrices
-    except ImportError:
-        from Bio.SubsMat.MatrixInfo import blosum62
-    else:
-        blosum62 = substitution_matrices.load("BLOSUM62")
-
-    def match_callback(c1, c2):
-        return blosum62.get((c1, c2), 1 if c1 == c2 else -4)
+    from Bio.Seq import Seq
 
-    alns = pairwise2.align.globalcs(s1, s2,
-            match_callback, -10., -.5,
-            one_alignment_only=True)
+    aligner = _get_aligner_BLOSUM62()
+    alns = aligner.align(s1, s2)
 
     a = MultipleSeqAlignment([])
-    s1 = SeqRecord(alns[0][0], id="s1")
-    s2 = SeqRecord(alns[0][1], id="s2")
+    s1 = SeqRecord(Seq(alns[0][0]), id="s1")
+    s2 = SeqRecord(Seq(alns[0][1]), id="s2")
     a.extend([s1, s2])
     return a
 
openSUSE Build Service is sponsored by