Commit 874e9f7e authored by Andreas Tille's avatar Andreas Tille
Browse files

Use 2to3 to port to Python3

parent 3c484663
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
mapdamage (2.0.9+dfsg-2) UNRELEASED; urgency=medium

  * Use 2to3 to port to Python3
    Closes: #936989

 -- Andreas Tille <tille@debian.org>  Tue, 03 Sep 2019 11:02:34 +0200

mapdamage (2.0.9+dfsg-1) unstable; urgency=medium

  * New upstream version
+3 −3
Original line number Diff line number Diff line
@@ -4,9 +4,9 @@ Uploaders: Andreas Tille <tille@debian.org>
Section: science
Priority: optional
Build-Depends: debhelper (>= 11~),
               python-all,
               python3-all,
               dh-python,
               python-setuptools
               python3-setuptools
Standards-Version: 4.2.1
Vcs-Browser: https://salsa.debian.org/med-team/mapdamage
Vcs-Git: https://salsa.debian.org/med-team/mapdamage.git
@@ -21,7 +21,7 @@ Depends: ${python:Depends},
         r-cran-ggplot2,
         r-cran-inline,
         seqtk,
         python-pysam,
         python3-pysam,
         r-cran-rcpp,
         r-cran-rcppgsl,
         libopenblas-dev | libblas-dev   | libatlas-base-dev | libblas.so,
+411 −0
Original line number Diff line number Diff line
Description: Use 2to3 to port to Python3
Bug-Debian: https://bugs.debian.org/936989
Author: Andreas Tille <tille@debian.org>
Last-Update: Tue, 03 Sep 2019 11:02:34 +0200

--- a/bin/mapDamage
+++ b/bin/mapDamage
@@ -1,7 +1,7 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 # -*- coding: utf-8 -*-
 
-from __future__ import print_function
+
 
 import logging
 import random
@@ -45,7 +45,7 @@ MODULE = "pysam"
 URL = "http://code.google.com/p/pysam/"
 try:
     __import__(MODULE)
-except ImportError, e:
+except ImportError as e:
     sys.stderr.write("Error: Could not import required module '%s':\n\t- %s\n" % (MODULE, e))
     sys.stderr.write("       If module is not installed, please download from '%s'.\n" % URL)
     sys.stderr.write("       A local install may be performed using the following command:\n")
@@ -98,7 +98,7 @@ def _downsample_to_fixed_number(bamfile,
             if index >= downsample_to:
                 continue
         sample[index] = record
-    return filter(None, sample)
+    return [_f for _f in sample if _f]
 
 
 def _read_bamfile(bamfile, options):
@@ -121,7 +121,7 @@ def _check_mm_option():
     in mapdamage.parseoptions
     """
     path_to_mm = None
-    for nr,arg in zip(xrange(len(sys.argv)),sys.argv):
+    for nr,arg in zip(range(len(sys.argv)),sys.argv):
         if arg.startswith("--mapdamage-modules"):
             try:
                 if "=" in arg:
@@ -230,7 +230,7 @@ def main():
         in_bam = pysam.Samfile(options.filename)
 
 
-    reflengths = dict(zip(in_bam.references, in_bam.lengths))
+    reflengths = dict(list(zip(in_bam.references, in_bam.lengths)))
     # check if references in SAM/BAM are the same in the fasta reference file
     fai_lengths = mapdamage.seq.read_fasta_index(options.ref + ".fai")
     if not fai_lengths:
--- a/mapdamage/__init__.py
+++ b/mapdamage/__init__.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
 
 import mapdamage.parseoptions
 import mapdamage.seq
--- a/mapdamage/align.py
+++ b/mapdamage/align.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
 
 import itertools
 import mapdamage
@@ -84,7 +84,7 @@ def get_mis(read, seq, refseq, ref, leng
   std = '-' if read.is_reverse else '+'
   subtable = tab[ref][end][std]
 
-  for (i, nt_seq, nt_ref) in itertools.izip(xrange(length), seq, refseq):
+  for (i, nt_seq, nt_ref) in zip(range(length), seq, refseq):
     if (nt_seq in "ACGT-") and (nt_ref in "ACGT-"):
       if nt_ref != "-":
         # record base composition in the reference, only A, C, G, T
--- a/mapdamage/composition.py
+++ b/mapdamage/composition.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
 
 import mapdamage
 import itertools
@@ -10,8 +10,8 @@ def count_ref_comp(read, chrom, before,
   """ record basae composition in external genomic regions """
   std = '-' if read.is_reverse else '+'
 
-  _update_table(comp[chrom]['5p'][std], before, xrange(-len(before), 0))
-  _update_table(comp[chrom]['3p'][std], after,  xrange(1, len(after) + 1))
+  _update_table(comp[chrom]['5p'][std], before, range(-len(before), 0))
+  _update_table(comp[chrom]['3p'][std], after,  range(1, len(after) + 1))
 
 
 def count_read_comp(read, chrom, length, comp):
@@ -20,12 +20,12 @@ def count_read_comp(read, chrom, length,
   if read.is_reverse:
     std, seq = '-', mapdamage.seq.revcomp(seq)
 
-  _update_table(comp[chrom]['5p'][std], seq,           xrange(1, length + 1))
-  _update_table(comp[chrom]['3p'][std], reversed(seq), xrange(-1, - length - 1, -1))
+  _update_table(comp[chrom]['5p'][std], seq,           range(1, length + 1))
+  _update_table(comp[chrom]['3p'][std], reversed(seq), range(-1, - length - 1, -1))
 
 
 def _update_table(table, sequence, indices):
-  for (index, nt) in itertools.izip(indices, sequence):
+  for (index, nt) in zip(indices, sequence):
     if nt in table:
       table[nt][index] += 1
 
@@ -47,7 +47,7 @@ def get_base_comp(filename,destination=F
             bases["C"] = bases["C"] + int(tabs[3])
             bases["G"] = bases["G"] + int(tabs[4])
             bases["T"] = bases["T"] + int(tabs[5])
-    except (OSError, ValueError), error:
+    except (OSError, ValueError) as error:
         sys.stderr.write("Error: Seqtk failed: %s\n" % (error,))
         sys.exit(1)
     # get the base frequencies
--- a/mapdamage/parseoptions.py
+++ b/mapdamage/parseoptions.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
 
 from optparse import OptionParser, OptionGroup, SUPPRESS_HELP
 import os
@@ -235,12 +235,12 @@ def options():
 
     if os.path.isdir(options.folder):
         if not options.quiet and not options.plot_only:
-            print("Warning, %s already exists" % options.folder)
+            print(("Warning, %s already exists" % options.folder))
         if options.plot_only:
             if not file_exist(options.folder+"/dnacomp.txt") or not file_exist(options.folder+"/misincorporation.txt"):
                 parser.error('folder %s is not a valid result folder' % options.folder)
     else:
-        os.makedirs(options.folder, mode = 0750)
+        os.makedirs(options.folder, mode = 0o750)
         if options.plot_only or options.stats_only or options.rescale_only:
             sys.stderr.write("Error, %s does not exist while plot/stats/rescale only was used\n" % options.folder)
             return None
--- a/mapdamage/rescale.py
+++ b/mapdamage/rescale.py
@@ -31,14 +31,14 @@ def get_corr_prob(folder, rescale_length
         fi_handle = csv.DictReader(open(full_path))
         corr_prob = {}
         for line in fi_handle:
-            if (corr_prob.has_key(line["Position"])):
+            if (line["Position"] in corr_prob):
                 sys.exit('This file has multiple position definitions %s, line %d: %s' % \
                     (folder, fi_handle.line_num, corr_prob[line["Position"]]))
             else:
                 corr_prob[int(line["Position"])] = {'C.T':float(line["C.T"]), 'G.A':float(line["G.A"])}
 
         # Exclude probabilities for positions outside of user-specified region
-        for key in corr_prob.keys():
+        for key in list(corr_prob.keys()):
             if key < -rescale_length_3p or key > rescale_length_5p:
                 corr_prob.pop(key)
 
@@ -75,13 +75,13 @@ def corr_this_base(corr_prob, nt_seq, nt
     back_pos = pos-length-1 
     # position from 3' end
 
-    if corr_prob.has_key(pos):
+    if pos in corr_prob:
         p5_corr = corr_prob[pos][subs]
         # correction from 5' end
     else:
         p5_corr = 0
 
-    if corr_prob.has_key(back_pos):
+    if back_pos in corr_prob:
         p3_corr = corr_prob[back_pos][subs]
         # correction from 3' end
     else:
@@ -104,7 +104,7 @@ def corr_this_base(corr_prob, nt_seq, nt
 
 def initialize_subs():
     """Initialize a substitution table, to track the expected substitution counts"""
-    per_qual = dict(zip(range(0,130),[0]*130))
+    per_qual = dict(list(zip(list(range(0,130)),[0]*130)))
     subs = {"CT-before":per_qual.copy(),\
             "TC-before":per_qual.copy(),\
             "GA-before":per_qual.copy(),\
@@ -164,7 +164,7 @@ def qual_summary_subs(subs):
             for qv in subs[i]:
                 if qv >= lv :
                     key = i+"-Q"+str(lv)
-                    if subs.has_key(key):
+                    if key in subs:
                         subs[key] += subs[i][qv]
                     else:
                         subs[key] = subs[i][qv]
@@ -174,32 +174,32 @@ def print_subs(subs):
     print("\tThe expected substition frequencies before and after scaling using the scaled qualities as probalities:")
     if subs["C"]!=0:
         # the special case of no substitutions
-        print("\tCT\t"+str(subs["CT-pvals_before"]/subs["C"])+"\t\t"+str(subs["CT-pvals"]/subs["C"]))
+        print(("\tCT\t"+str(subs["CT-pvals_before"]/subs["C"])+"\t\t"+str(subs["CT-pvals"]/subs["C"])))
     else: 
         print("\tCT\tNA\t\tNA")
     if subs["T"]!=0:
-        print("\tTC\t"+str(subs["TC-pvals"]/subs["T"])+"\t\t"+str(subs["TC-pvals"]/subs["T"]))
+        print(("\tTC\t"+str(subs["TC-pvals"]/subs["T"])+"\t\t"+str(subs["TC-pvals"]/subs["T"])))
     else:
         print("\tTC\tNA\t\tNA")
     if subs["G"]!=0:
-        print("\tGA\t"+str(subs["GA-pvals_before"]/subs["G"])+"\t\t"+str(subs["GA-pvals"]/subs["G"]))
+        print(("\tGA\t"+str(subs["GA-pvals_before"]/subs["G"])+"\t\t"+str(subs["GA-pvals"]/subs["G"])))
     else:
         print("\tGA\tNA\t\tNA")
     if subs["A"]!=0:
-        print("\tAG\t"+str(subs["AG-pvals"]/subs["A"])+"\t\t"+str(subs["AG-pvals"]/subs["A"]))
+        print(("\tAG\t"+str(subs["AG-pvals"]/subs["A"])+"\t\t"+str(subs["AG-pvals"]/subs["A"])))
     else:
         print("\tAG\tNA\t\tNA")
     print("\tQuality metrics before and after scaling")
-    print("\tCT-Q0 \t"+str(subs["CT-before-Q0"])+"\t\t"+str(subs["CT-after-Q0"]))
-    print("\tCT-Q10 \t"+str(subs["CT-before-Q10"])+"\t\t"+str(subs["CT-after-Q10"]))
-    print("\tCT-Q20 \t"+str(subs["CT-before-Q20"])+"\t\t"+str(subs["CT-after-Q20"]))
-    print("\tCT-Q30 \t"+str(subs["CT-before-Q30"])+"\t\t"+str(subs["CT-after-Q30"]))
-    print("\tCT-Q40 \t"+str(subs["CT-before-Q40"])+"\t\t"+str(subs["CT-after-Q40"]))
-    print("\tGA-Q0 \t"+str(subs["GA-before-Q0"])+"\t\t"+str(subs["GA-after-Q0"]))
-    print("\tGA-Q10 \t"+str(subs["GA-before-Q10"])+"\t\t"+str(subs["GA-after-Q10"]))
-    print("\tGA-Q20 \t"+str(subs["GA-before-Q20"])+"\t\t"+str(subs["GA-after-Q20"]))
-    print("\tGA-Q30 \t"+str(subs["GA-before-Q30"])+"\t\t"+str(subs["GA-after-Q30"]))
-    print("\tGA-Q40 \t"+str(subs["GA-before-Q40"])+"\t\t"+str(subs["GA-after-Q40"]))
+    print(("\tCT-Q0 \t"+str(subs["CT-before-Q0"])+"\t\t"+str(subs["CT-after-Q0"])))
+    print(("\tCT-Q10 \t"+str(subs["CT-before-Q10"])+"\t\t"+str(subs["CT-after-Q10"])))
+    print(("\tCT-Q20 \t"+str(subs["CT-before-Q20"])+"\t\t"+str(subs["CT-after-Q20"])))
+    print(("\tCT-Q30 \t"+str(subs["CT-before-Q30"])+"\t\t"+str(subs["CT-after-Q30"])))
+    print(("\tCT-Q40 \t"+str(subs["CT-before-Q40"])+"\t\t"+str(subs["CT-after-Q40"])))
+    print(("\tGA-Q0 \t"+str(subs["GA-before-Q0"])+"\t\t"+str(subs["GA-after-Q0"])))
+    print(("\tGA-Q10 \t"+str(subs["GA-before-Q10"])+"\t\t"+str(subs["GA-after-Q10"])))
+    print(("\tGA-Q20 \t"+str(subs["GA-before-Q20"])+"\t\t"+str(subs["GA-after-Q20"])))
+    print(("\tGA-Q30 \t"+str(subs["GA-before-Q30"])+"\t\t"+str(subs["GA-after-Q30"])))
+    print(("\tGA-Q40 \t"+str(subs["GA-before-Q40"])+"\t\t"+str(subs["GA-after-Q40"])))
     
 
 def rescale_qual_read(bam, read, ref, corr_prob,subs, debug = False,direction="both"):
@@ -237,7 +237,7 @@ def rescale_qual_read(bam, read, ref, co
     new_qual = [-100]*length_read
     pos_on_read = 0
     number_of_rescaled_bases = 0.0
-    for (i, nt_seq, nt_ref, nt_qual) in itertools.izip(xrange(length_align), seq, refseq, qual):
+    for (i, nt_seq, nt_ref, nt_qual) in zip(range(length_align), seq, refseq, qual):
         # rescale the quality according to the triplet position, 
         # pair of the reference and the sequence
         if ((nt_seq == "T" and nt_ref =="C") or (nt_seq == "A" and nt_ref =="G")):
--- a/mapdamage/rescale_test.py
+++ b/mapdamage/rescale_test.py
@@ -1,6 +1,6 @@
 import unittest
 import optparse
-import rescale
+from . import rescale
 import pysam
 import filecmp
 
--- a/mapdamage/rscript.py
+++ b/mapdamage/rscript.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
 
 import os
 import subprocess
@@ -35,11 +35,11 @@ def plot(opt):
   script = construct_path("mapDamage.R") 
   call = ["Rscript", script, fcomp, title, opt.refplot, fmut, opt.readplot, \
       opt.ymax, opt.folder, opt.title, __version__]
-  code = subprocess.call(map(str, call))
+  code = subprocess.call(list(map(str, call)))
 
   if code == 0:
     if not opt.quiet:
-      print("pdf %s generated" % title)
+      print(("pdf %s generated" % title))
     return 0
   else:
     print("Error: plotting with R failed")
@@ -58,7 +58,7 @@ def opt_plots(opt):
   script = construct_path("lengths.R") 
   call = ["Rscript", script, flength, output, fmut, opt.length, \
       opt.title, __version__, bool_to_int(opt.quiet)]
-  code = subprocess.call(map(str, call))
+  code = subprocess.call(list(map(str, call)))
   if code == 0:
     return 0
   else:
@@ -90,11 +90,11 @@ def check_R_lib():
     if len(missing_lib) > 1:
         # Grammar Nazi has arrived
         last_ele = missing_lib.pop()
-        print ("Missing the following R libraries '" + "', '".join(missing_lib) \
-            + "' and '" + last_ele + "'")
+        print(("Missing the following R libraries '" + "', '".join(missing_lib) \
+            + "' and '" + last_ele + "'"))
         return 1
     elif len(missing_lib) == 1:
-        print ("Missing the following R library "+missing_lib[0])
+        print(("Missing the following R library "+missing_lib[0]))
         return 1
     else :
         # No missing libraries
--- a/mapdamage/seq.py
+++ b/mapdamage/seq.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
 import sys
 import string
 
--- a/mapdamage/tables.py
+++ b/mapdamage/tables.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
 
 import os
 import collections
@@ -16,7 +16,7 @@ def initialize_mut(ref, length):
       for std in ('+','-'):
         tab_std = tab_end[std] = {}
         for mut in mapdamage.seq.HEADER:
-          tab_std[mut] = dict.fromkeys(xrange(length), 0)
+          tab_std[mut] = dict.fromkeys(range(length), 0)
   
   return tab
 
@@ -26,8 +26,8 @@ def print_mut(mut, opt, out):
 
 
 def initialize_comp(ref, around, length):
-  keys = {"3p" : range(-length, 0) + range(1, around + 1),
-          "5p" : range(-around, 0) + range(1, length + 1)}
+  keys = {"3p" : list(range(-length, 0)) + list(range(1, around + 1)),
+          "5p" : list(range(-around, 0)) + list(range(1, length + 1))}
 
   tab = {}
   for contig in ref:
@@ -74,8 +74,8 @@ def check_table_and_warn_if_dmg_freq_is_
   total = 0.0
   for filename in ("5pCtoT_freq.txt", "3pGtoA_freq.txt"):
     if not os.path.exists(folder+"/"+filename):
-      print("Error: Required table has not been created ('%s'), bayesian computation cannot be performed" \
-            % filename)
+      print(("Error: Required table has not been created ('%s'), bayesian computation cannot be performed" \
+            % filename))
       return True
 
     with open(os.path.join(folder, filename)) as handle:
@@ -85,12 +85,12 @@ def check_table_and_warn_if_dmg_freq_is_
           total += float(freq[1])
           break
       else:
-        print("Error: Could not find pos = 1 in table '%s', bayesian computation cannot be performed" \
-              % filename)
+        print(("Error: Could not find pos = 1 in table '%s', bayesian computation cannot be performed" \
+              % filename))
         return True
 
   if total < 0.01:
-    print("Warning: DNA damage levels are too low, the Bayesian computation should not be performed (%f < 0.01)\n" % total)
+    print(("Warning: DNA damage levels are too low, the Bayesian computation should not be performed (%f < 0.01)\n" % total))
 
   return False
 
@@ -103,9 +103,9 @@ def _print_freq_table(table, columns, op
   out.write("# Chr: reference from sam/bam header, End: from which termini of DNA sequences, Std: strand of reads\n")
   out.write("Chr\tEnd\tStd\tPos\t%s\n" % ("\t".join(columns)))
 
-  for (reference, ends) in sorted(table.iteritems()):
-    for (end, strands) in sorted(ends.iteritems()):
-      for (strand, subtable) in sorted(strands.iteritems()):
+  for (reference, ends) in sorted(table.items()):
+    for (end, strands) in sorted(ends.items()):
+      for (strand, subtable) in sorted(strands.items()):
         subtable["Total"] = {}
         for index in sorted(subtable[columns[0]]):
           subtable["Total"][index] = sum(subtable[letter][index] for letter in mapdamage.seq.LETTERS)
--- a/mapdamage/version.py
+++ b/mapdamage/version.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
 try:
     from mapdamage._version import __version__
 except ImportError:
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
 # -*- coding: utf-8 -*-
 
 from distutils.core import setup
@@ -16,7 +16,7 @@ def setup_version():
         with open(os.path.join("mapdamage", "_version.py"), "w") as handle:
             handle.write("#!/usr/bin/env python\n")
             handle.write("__version__ = %r\n" % (version.strip(),))
-    except (subprocess.CalledProcessError, OSError), error:
+    except (subprocess.CalledProcessError, OSError) as error:
         raise SystemExit("Could not determine mapDamage version: %s" % (error,))
 
 
+1 −0
Original line number Diff line number Diff line
use_debian_packaged_seqtk.patch
fix_quantile_na_rm.patch
2to3.patch
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ include /usr/share/dpkg/default.mk
TESTDIR        := debian/$(DEB_SOURCE)/usr/share/doc/$(DEB_SOURCE)/tests

%:
	dh $@ --with python2
	dh $@ --with python3

override_dh_fixperms:
	dh_fixperms