diff --git a/python-biopython-1.76_python39.patch b/python-biopython-1.76_python39.patch new file mode 100644 index 0000000..5f5fabe --- /dev/null +++ b/python-biopython-1.76_python39.patch @@ -0,0 +1,617 @@ +--- a/Bio/SeqIO/UniprotIO.orig.py 2020-02-29 21:32:54.957544008 +0100 ++++ b/Bio/SeqIO/UniprotIO.py 2020-02-29 21:38:42.446966155 +0100 +@@ -252,11 +252,11 @@ def _parse_comment(element): + + if element.attrib["type"] in simple_comments: + ann_key = "comment_%s" % element.attrib["type"].replace(" ", "") +- for text_element in element.getiterator(NS + "text"): ++ for text_element in element.iter(NS + "text"): + if text_element.text: + append_to_annotations(ann_key, text_element.text) + elif element.attrib["type"] == "subcellular location": +- for subloc_element in element.getiterator(NS + "subcellularLocation"): ++ for subloc_element in element.iter(NS + "subcellularLocation"): + for el in subloc_element: + if el.text: + ann_key = "comment_%s_%s" % ( +@@ -265,21 +265,21 @@ def _parse_comment(element): + ) + append_to_annotations(ann_key, el.text) + elif element.attrib["type"] == "interaction": +- for interact_element in element.getiterator(NS + "interactant"): ++ for interact_element in element.iter(NS + "interactant"): + ann_key = "comment_%s_intactId" % element.attrib["type"] + append_to_annotations(ann_key, interact_element.attrib["intactId"]) + elif element.attrib["type"] == "alternative products": +- for alt_element in element.getiterator(NS + "isoform"): ++ for alt_element in element.iter(NS + "isoform"): + ann_key = "comment_%s_isoform" % element.attrib["type"].replace( + " ", "" + ) +- for id_element in alt_element.getiterator(NS + "id"): ++ for id_element in alt_element.iter(NS + "id"): + append_to_annotations(ann_key, id_element.text) + elif element.attrib["type"] == "mass spectrometry": + ann_key = "comment_%s" % element.attrib["type"].replace(" ", "") + start = end = 0 +- for el in element.getiterator(NS + "location"): +- pos_els = list(el.getiterator(NS + "position")) ++ for el in element.iter(NS + "location"): ++ pos_els = list(el.iter(NS + "position")) + # this try should be avoided, maybe it is safer to skip position parsing for mass spectrometry + try: + if pos_els: +@@ -287,12 +287,10 @@ def _parse_comment(element): + start = end - 1 + else: + start = int( +- list(el.getiterator(NS + "begin"))[0].attrib["position"] ++ list(el.iter(NS + "begin"))[0].attrib["position"] + ) + start -= 1 +- end = int( +- list(el.getiterator(NS + "end"))[0].attrib["position"] +- ) ++ end = int(list(el.iter(NS + "end"))[0].attrib["position"]) + except (ValueError, KeyError): + # undefined positions or erroneously mapped + pass +@@ -307,9 +305,9 @@ def _parse_comment(element): + elif element.attrib["type"] == "sequence caution": + pass # not parsed: few information, complex structure + elif element.attrib["type"] == "online information": +- for link_element in element.getiterator(NS + "link"): ++ for link_element in element.iter(NS + "link"): + ann_key = "comment_%s" % element.attrib["type"].replace(" ", "") +- for id_element in link_element.getiterator(NS + "link"): ++ for id_element in link_element.iter(NS + "link"): + append_to_annotations( + ann_key, + "%s@%s" +From 9c2879e5a91935e675de0a5774ad23e7368e0764 Mon Sep 17 00:00:00 2001 +From: Karthikeyan Singaravelan +Date: Sun, 1 Mar 2020 18:35:57 +0530 +Subject: [PATCH] Use list()/iteration instead of getchildren for Python 3.9 +compatibility. + +--- + Bio/KEGG/KGML/KGML_parser.py | 8 ++++---- + Bio/Phylo/NeXMLIO.py | 6 +++--- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/Bio/KEGG/KGML/KGML_parser.py b/Bio/KEGG/KGML/KGML_parser.py +index c0d9f12e88..662cde36bd 100644 +--- a/Bio/KEGG/KGML/KGML_parser.py ++++ b/Bio/KEGG/KGML/KGML_parser.py +@@ -115,7 +115,7 @@ def _parse_entry(element): + new_entry = Entry() + for k, v in element.attrib.items(): + new_entry.__setattr__(k, v) +- for subelement in element.getchildren(): ++ for subelement in element: + if subelement.tag == "graphics": + _parse_graphics(subelement, new_entry) + elif subelement.tag == "component": +@@ -138,7 +138,7 @@ def _parse_reaction(element): + new_reaction = Reaction() + for k, v in element.attrib.items(): + new_reaction.__setattr__(k, v) +- for subelement in element.getchildren(): ++ for subelement in element: + if subelement.tag == "substrate": + new_reaction.add_substrate(int(subelement.attrib["id"])) + elif subelement.tag == "product": +@@ -150,7 +150,7 @@ def _parse_relation(element): + new_relation.entry1 = int(element.attrib["entry1"]) + new_relation.entry2 = int(element.attrib["entry2"]) + new_relation.type = element.attrib["type"] +- for subtype in element.getchildren(): ++ for subtype in element: + name, value = subtype.attrib["name"], subtype.attrib["value"] + if name in ("compound", "hidden compound"): + new_relation.subtypes.append((name, int(value))) +@@ -163,7 +163,7 @@ def _parse_relation(element): + self.pathway = Pathway() + # Get information about the pathway itself + _parse_pathway(self.entry.attrib) +- for element in self.entry.getchildren(): ++ for element in self.entry: + if element.tag == "entry": + _parse_entry(element) + elif element.tag == "reaction": +diff --git a/Bio/Phylo/NeXMLIO.py b/Bio/Phylo/NeXMLIO.py +index 8b173d6528..e18364824a 100644 +--- a/Bio/Phylo/NeXMLIO.py ++++ b/Bio/Phylo/NeXMLIO.py +@@ -138,7 +138,7 @@ def parse(self, values_are_confidence=False, rooted=False): + node_children = {} + root = None + +- child_tags = node.getchildren() ++ child_tags = list(node) + nodes = [] + edges = [] + for child in child_tags: +@@ -155,7 +155,7 @@ def parse(self, values_are_confidence=False, rooted=False): + if "root" in node.attrib and node.attrib["root"] == "true": + root = node_id + +- for child in node.getchildren(): ++ for child in node: + if child.tag == qUri("nex:meta"): + self.add_annotation(node_dict[node_id], child) + +@@ -176,7 +176,7 @@ def parse(self, values_are_confidence=False, rooted=False): + ): + node_dict[tar]["confidence"] = float(edge.attrib["content"]) + +- for child in edge.getchildren(): ++ for child in edge: + if child.tag == qUri("nex:meta"): + self.add_annotation(node_dict[tar], child) + +From ba893ee4afdcb6bf8e763f3e09ffab1698276ebd Mon Sep 17 00:00:00 2001 +From: Chris Rands +Date: Sun, 19 Jan 2020 21:23:17 +0100 +Subject: [PATCH] drop redudant arg + +--- + Bio/AlignIO/__init__.py | 4 ++-- + Bio/PDB/PDBParser.py | 2 +- + Bio/SCOP/Cla.py | 4 ++-- + Bio/SearchIO/__init__.py | 2 +- + Bio/SeqIO/AceIO.py | 6 +++--- + Bio/SeqIO/FastaIO.py | 4 ++-- + Bio/SeqIO/IgIO.py | 2 +- + Bio/SeqIO/PdbIO.py | 8 ++++---- + Bio/SeqIO/PhdIO.py | 2 +- + Bio/SeqIO/PirIO.py | 2 +- + Bio/SeqIO/QualityIO.py | 30 +++++++++++++++--------------- + Bio/SeqIO/SwissIO.py | 2 +- + Bio/SeqIO/TabIO.py | 2 +- + Bio/SeqIO/UniprotIO.py | 2 +- + Bio/phenotype/__init__.py | 2 +- + Tests/test_KGML_graphics.py | 2 +- + Tests/test_KGML_graphics_online.py | 2 +- + Tests/test_KGML_nographics.py | 4 ++-- + Tests/test_PDB.py | 2 +- + 19 files changed, 42 insertions(+), 42 deletions(-) + +diff --git a/Bio/AlignIO/__init__.py b/Bio/AlignIO/__init__.py +index fc92dc161c..963a424f91 100644 +--- a/Bio/AlignIO/__init__.py ++++ b/Bio/AlignIO/__init__.py +@@ -364,7 +364,7 @@ def parse(handle, format, seq_count=None, alphabet=None): + if seq_count is not None and not isinstance(seq_count, int): + raise TypeError("Need integer for seq_count (sequences per alignment)") + +- with as_handle(handle, "rU") as fp: ++ with as_handle(handle) as fp: + # Map the file format to a sequence iterator: + if format in _FormatToIterator: + iterator_generator = _FormatToIterator[format] +@@ -471,7 +471,7 @@ def convert(in_file, in_format, out_file, out_format, alphabet=None): + """ + # TODO - Add optimised versions of important conversions + # For now just off load the work to SeqIO parse/write +- with as_handle(in_file, "rU") as in_handle: ++ with as_handle(in_file) as in_handle: + # Don't open the output file until we've checked the input is OK: + alignments = parse(in_handle, in_format, None, alphabet) + +diff --git a/Bio/PDB/PDBParser.py b/Bio/PDB/PDBParser.py +index bc78486b0e..c85b4bb612 100644 +--- a/Bio/PDB/PDBParser.py ++++ b/Bio/PDB/PDBParser.py +@@ -89,7 +89,7 @@ def get_structure(self, id, file): + # Make a StructureBuilder instance (pass id of structure as parameter) + self.structure_builder.init_structure(id) + +- with as_handle(file, mode="rU") as handle: ++ with as_handle(file) as handle: + lines = handle.readlines() + if not lines: + raise ValueError("Empty file.") +diff --git a/Bio/SCOP/Cla.py b/Bio/SCOP/Cla.py +index 50ee85e029..3546eaa587 100644 +--- a/Bio/SCOP/Cla.py ++++ b/Bio/SCOP/Cla.py +@@ -103,7 +103,7 @@ def __init__(self, filename): + """ + dict.__init__(self) + self.filename = filename +- with open(self.filename, "rU") as f: ++ with open(self.filename) as f: + position = 0 + while True: + line = f.readline() +@@ -121,7 +121,7 @@ def __getitem__(self, key): + """Return an item from the indexed file.""" + position = dict.__getitem__(self, key) + +- with open(self.filename, "rU") as f: ++ with open(self.filename) as f: + f.seek(position) + line = f.readline() + record = Record(line) +diff --git a/Bio/SearchIO/__init__.py b/Bio/SearchIO/__init__.py +index 04ef42fa81..1f7b5768e9 100755 +--- a/Bio/SearchIO/__init__.py ++++ b/Bio/SearchIO/__init__.py +@@ -314,7 +314,7 @@ + handle_kwargs["encoding"] = "utf-8" + + # and start iterating +- with as_handle(handle, "rU", **handle_kwargs) as source_file: ++ with as_handle(handle, **handle_kwargs) as source_file: + generator = iterator(source_file, **kwargs) + + for qresult in generator: +diff --git a/Bio/SeqIO/AceIO.py b/Bio/SeqIO/AceIO.py +index 516759a520..b8923543ef 100644 +--- a/Bio/SeqIO/AceIO.py ++++ b/Bio/SeqIO/AceIO.py +@@ -32,7 +32,7 @@ def AceIterator(handle): + letter_annotations dictionary under the "phred_quality" key. + + >>> from Bio import SeqIO +- >>> with open("Ace/consed_sample.ace", "rU") as handle: ++ >>> with open("Ace/consed_sample.ace") as handle: + ... for record in SeqIO.parse(handle, "ace"): + ... print("%s %s... %i" % (record.id, record.seq[:10], len(record))) + ... print(max(record.letter_annotations["phred_quality"])) +@@ -47,7 +47,7 @@ def AceIterator(handle): + prevented output of the gapped sequence as FASTQ format. + + >>> from Bio import SeqIO +- >>> with open("Ace/contig1.ace", "rU") as handle: ++ >>> with open("Ace/contig1.ace") as handle: + ... for record in SeqIO.parse(handle, "ace"): + ... print("%s ...%s..." % (record.id, record.seq[85:95])) + ... print(record.letter_annotations["phred_quality"][85:95]) +@@ -60,7 +60,7 @@ def AceIterator(handle): + 90 + + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + + for ace_contig in Ace.parse(handle): + # Convert the ACE contig record into a SeqRecord... +diff --git a/Bio/SeqIO/FastaIO.py b/Bio/SeqIO/FastaIO.py +index f5fbe94b61..7baf92c2ed 100644 +--- a/Bio/SeqIO/FastaIO.py ++++ b/Bio/SeqIO/FastaIO.py +@@ -174,7 +174,7 @@ def FastaIterator(handle, alphabet=single_letter_alphabet, title2ids=None): + DELTA + + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + if title2ids: + for title, sequence in SimpleFastaParser(handle): + id, name, descr = title2ids(title) +@@ -210,7 +210,7 @@ def FastaTwoLineIterator(handle, alphabet=single_letter_alphabet): + Only the default title to ID/name/description parsing offered + by the relaxed FASTA parser is offered. + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + for title, sequence in FastaTwoLineParser(handle): + try: + first_word = title.split(None, 1)[0] +diff --git a/Bio/SeqIO/IgIO.py b/Bio/SeqIO/IgIO.py +index 10d71a84af..f5157c7b7b 100644 +--- a/Bio/SeqIO/IgIO.py ++++ b/Bio/SeqIO/IgIO.py +@@ -59,7 +59,7 @@ def IgIterator(handle, alphabet=single_letter_alphabet): + SYK_SYK length 330 + + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + + # Skip any file header text before the first record (;; lines) + while True: +diff --git a/Bio/SeqIO/PdbIO.py b/Bio/SeqIO/PdbIO.py +index 165673d309..6214e63d97 100644 +--- a/Bio/SeqIO/PdbIO.py ++++ b/Bio/SeqIO/PdbIO.py +@@ -148,7 +148,7 @@ def PdbSeqresIterator(handle): + + chains = collections.defaultdict(list) + metadata = collections.defaultdict(list) +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + for line in handle: + empty = False + rec_name = line[0:6].strip() +@@ -283,7 +283,7 @@ def PdbAtomIterator(handle): + # Only import PDB when needed, to avoid/delay NumPy dependency in SeqIO + from Bio.PDB import PDBParser + +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + struct = PDBParser().get_structure(None, handle) + pdb_id = struct.header["idcode"] + if not pdb_id: +@@ -368,7 +368,7 @@ def CifSeqresIterator(handle): + # Only import PDB when needed, to avoid/delay NumPy dependency in SeqIO + from Bio.PDB.MMCIF2Dict import MMCIF2Dict + +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + + chains = collections.defaultdict(list) + metadata = collections.defaultdict(list) +@@ -498,7 +498,7 @@ def CifAtomIterator(handle): + # file. We copy the contents of the handle into a StringIO buffer first, + # so that both MMCIF2Dict and MMCIFParser can consume the handle. + buffer = StringIO() +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + shutil.copyfileobj(handle, buffer) + + # check if file is empty +diff --git a/Bio/SeqIO/PhdIO.py b/Bio/SeqIO/PhdIO.py +index 27ba7a8395..3c2dedfa52 100644 +--- a/Bio/SeqIO/PhdIO.py ++++ b/Bio/SeqIO/PhdIO.py +@@ -65,7 +65,7 @@ def PhdIterator(handle): + + This uses the Bio.Sequencing.Phd module to do the hard work. + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + phd_records = Phd.parse(handle) + for phd_record in phd_records: + # Convert the PHY record into a SeqRecord... +diff --git a/Bio/SeqIO/PirIO.py b/Bio/SeqIO/PirIO.py +index d4ed6c0703..aa462032b1 100644 +--- a/Bio/SeqIO/PirIO.py ++++ b/Bio/SeqIO/PirIO.py +@@ -141,7 +141,7 @@ def PirIterator(handle): + HLA:HLA01083 length 188 + + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + # Skip any text before the first record (e.g. blank lines, comments) + while True: + line = handle.readline() +diff --git a/Bio/SeqIO/QualityIO.py b/Bio/SeqIO/QualityIO.py +index 9516313070..73152d5b10 100644 +--- a/Bio/SeqIO/QualityIO.py ++++ b/Bio/SeqIO/QualityIO.py +@@ -888,7 +888,7 @@ def FastqGeneralIterator(handle): + Using this tricky example file as input, this short bit of code demonstrates + what this parsing function would return: + +- >>> with open("Quality/tricky.fastq", "rU") as handle: ++ >>> with open("Quality/tricky.fastq") as handle: + ... for (title, sequence, quality) in FastqGeneralIterator(handle): + ... print(title) + ... print("%s %s" % (sequence, quality)) +@@ -909,7 +909,7 @@ def FastqGeneralIterator(handle): + is that (provided there are no line breaks in the quality sequence) it + would prevent the above problem with the "@" character. + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + # We need to call handle.readline() at least four times per record, + # so we'll save a property look up each time: + handle_readline = handle.readline +@@ -1016,7 +1016,7 @@ def FastqPhredIterator(handle, alphabet=single_letter_alphabet, title2ids=None): + + Using this module directly you might run: + +- >>> with open("Quality/example.fastq", "rU") as handle: ++ >>> with open("Quality/example.fastq") as handle: + ... for record in FastqPhredIterator(handle): + ... print("%s %s" % (record.id, record.seq)) + EAS54_6_R1_2_1_413_324 CCCTTCTTGTCTTCAGCGTTTCTCC +@@ -1027,7 +1027,7 @@ def FastqPhredIterator(handle, alphabet=single_letter_alphabet, title2ids=None): + (or "fastq-sanger") as the format: + + >>> from Bio import SeqIO +- >>> with open("Quality/example.fastq", "rU") as handle: ++ >>> with open("Quality/example.fastq") as handle: + ... for record in SeqIO.parse(handle, "fastq"): + ... print("%s %s" % (record.id, record.seq)) + EAS54_6_R1_2_1_413_324 CCCTTCTTGTCTTCAGCGTTTCTCC +@@ -1111,7 +1111,7 @@ def FastqSolexaIterator(handle, alphabet=single_letter_alphabet, title2ids=None) + + Using this module directly you might run: + +- >>> with open("Quality/solexa_example.fastq", "rU") as handle: ++ >>> with open("Quality/solexa_example.fastq") as handle: + ... for record in FastqSolexaIterator(handle): + ... print("%s %s" % (record.id, record.seq)) + SLXA-B3_649_FC8437_R1_1_1_610_79 GATGTGCAATACCTTTGTAGAGGAA +@@ -1124,7 +1124,7 @@ def FastqSolexaIterator(handle, alphabet=single_letter_alphabet, title2ids=None) + "fastq-solexa" as the format: + + >>> from Bio import SeqIO +- >>> with open("Quality/solexa_example.fastq", "rU") as handle: ++ >>> with open("Quality/solexa_example.fastq") as handle: + ... for record in SeqIO.parse(handle, "fastq-solexa"): + ... print("%s %s" % (record.id, record.seq)) + SLXA-B3_649_FC8437_R1_1_1_610_79 GATGTGCAATACCTTTGTAGAGGAA +@@ -1160,7 +1160,7 @@ def FastqSolexaIterator(handle, alphabet=single_letter_alphabet, title2ids=None) + use the Bio.SeqIO.read() function: + + >>> from Bio import SeqIO +- >>> with open("Quality/solexa_faked.fastq", "rU") as handle: ++ >>> with open("Quality/solexa_faked.fastq") as handle: + ... record = SeqIO.read(handle, "fastq-solexa") + >>> print("%s %s" % (record.id, record.seq)) + slxa_0001_1_0001_01 ACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTNNNNNN +@@ -1300,7 +1300,7 @@ def QualPhredIterator(handle, alphabet=single_letter_alphabet, title2ids=None): + + Using this module directly you might run: + +- >>> with open("Quality/example.qual", "rU") as handle: ++ >>> with open("Quality/example.qual") as handle: + ... for record in QualPhredIterator(handle): + ... print("%s %s" % (record.id, record.seq)) + EAS54_6_R1_2_1_413_324 ????????????????????????? +@@ -1311,7 +1311,7 @@ def QualPhredIterator(handle, alphabet=single_letter_alphabet, title2ids=None): + as the format: + + >>> from Bio import SeqIO +- >>> with open("Quality/example.qual", "rU") as handle: ++ >>> with open("Quality/example.qual") as handle: + ... for record in SeqIO.parse(handle, "qual"): + ... print("%s %s" % (record.id, record.seq)) + EAS54_6_R1_2_1_413_324 ????????????????????????? +@@ -1327,7 +1327,7 @@ def QualPhredIterator(handle, alphabet=single_letter_alphabet, title2ids=None): + + >>> from Bio import SeqIO + >>> from Bio.Alphabet import generic_dna +- >>> with open("Quality/example.qual", "rU") as handle: ++ >>> with open("Quality/example.qual") as handle: + ... for record in SeqIO.parse(handle, "qual", alphabet=generic_dna): + ... print("%s %s" % (record.id, record.seq)) + EAS54_6_R1_2_1_413_324 NNNNNNNNNNNNNNNNNNNNNNNNN +@@ -1350,7 +1350,7 @@ def QualPhredIterator(handle, alphabet=single_letter_alphabet, title2ids=None): + scores but will replace them with the lowest possible PHRED score of zero. + This will trigger a warning, previously it raised a ValueError exception. + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + # Skip any text before the first record (e.g. blank lines, comments) + while True: + line = handle.readline() +@@ -1882,8 +1882,8 @@ def PairedFastaQualIterator( + can't be used to read the two files together - but this function can! + For example, + +- >>> with open("Quality/example.fasta", "rU") as f: +- ... with open("Quality/example.qual", "rU") as q: ++ >>> with open("Quality/example.fasta") as f: ++ ... with open("Quality/example.qual") as q: + ... for record in PairedFastaQualIterator(f, q): + ... print("%s %s" % (record.id, record.seq)) + ... +@@ -1903,8 +1903,8 @@ def PairedFastaQualIterator( + this function to convert paired FASTA and QUAL files into FASTQ files: + + >>> from Bio import SeqIO +- >>> with open("Quality/example.fasta", "rU") as f: +- ... with open("Quality/example.qual", "rU") as q: ++ >>> with open("Quality/example.fasta") as f: ++ ... with open("Quality/example.qual") as q: + ... SeqIO.write(PairedFastaQualIterator(f, q), "Quality/temp.fastq", "fastq") + ... + 3 +diff --git a/Bio/SeqIO/SwissIO.py b/Bio/SeqIO/SwissIO.py +index c2e5be16b8..b9730dcff0 100644 +--- a/Bio/SeqIO/SwissIO.py ++++ b/Bio/SeqIO/SwissIO.py +@@ -73,7 +73,7 @@ def SwissIterator(handle): + Rather than calling it directly, you are expected to use this + parser via Bio.SeqIO.parse(..., format="swiss") instead. + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + swiss_records = SwissProt.parse(handle) + + for swiss_record in swiss_records: +diff --git a/Bio/SeqIO/TabIO.py b/Bio/SeqIO/TabIO.py +index 3f99fe40ac..686046c134 100644 +--- a/Bio/SeqIO/TabIO.py ++++ b/Bio/SeqIO/TabIO.py +@@ -73,7 +73,7 @@ def TabIterator(handle, alphabet=single_letter_alphabet): + gi|45478721|ref|NP_995576.1| length 90 + + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + for line in handle: + try: + title, seq = line.split("\t") # will fail if more than one tab! +diff --git a/Bio/SeqIO/UniprotIO.py b/Bio/SeqIO/UniprotIO.py +index c8307beaa9..ff75ab8268 100644 +--- a/Bio/SeqIO/UniprotIO.py ++++ b/Bio/SeqIO/UniprotIO.py +@@ -43,7 +43,7 @@ def UniprotIterator( + return_raw_comments = True --> comment fields are returned as complete XML to allow further processing + skip_parsing_errors = True --> if parsing errors are found, skip to next entry + """ +- with as_handle(handle, "rU") as handle: ++ with as_handle(handle) as handle: + + # check if file is empty + if handle.readline() == "": +diff --git a/Bio/phenotype/__init__.py b/Bio/phenotype/__init__.py +index 03b1d3926b..df70bb745d 100644 +--- a/Bio/phenotype/__init__.py ++++ b/Bio/phenotype/__init__.py +@@ -178,7 +178,7 @@ def parse(handle, format): + if format != format.lower(): + raise ValueError("Format string '%s' should be lower case" % format) + +- with as_handle(handle, "rU") as fp: ++ with as_handle(handle) as fp: + # Map the file format to a sequence iterator: + if format in _FormatToIterator: + iterator_generator = _FormatToIterator[format] +diff --git a/Tests/test_KGML_graphics.py b/Tests/test_KGML_graphics.py +index cb05c29249..f66e089ff8 100644 +--- a/Tests/test_KGML_graphics.py ++++ b/Tests/test_KGML_graphics.py +@@ -108,7 +108,7 @@ def test_render_KGML_basic(self): + # We test rendering of the original KEGG KGML using only local + # files. + for p in self.data: +- with open(p.infilename, "rU") as f: ++ with open(p.infilename) as f: + pathway = read(f) + pathway.image = p.pathway_image + kgml_map = KGMLCanvas(pathway) +diff --git a/Tests/test_KGML_graphics_online.py b/Tests/test_KGML_graphics_online.py +index 22d923daf0..3c101df913 100644 +--- a/Tests/test_KGML_graphics_online.py ++++ b/Tests/test_KGML_graphics_online.py +@@ -74,7 +74,7 @@ def test_render_KGML_import_map(self): + """ + # We test rendering of the original KEGG KGML using imported files + for p in self.data: +- with open(p.infilename, "rU") as f: ++ with open(p.infilename) as f: + pathway = read(f) + kgml_map = KGMLCanvas(pathway, import_imagemap=True) + kgml_map.draw(p.output_stem + "_importmap.pdf") +diff --git a/Tests/test_KGML_nographics.py b/Tests/test_KGML_nographics.py +index 105a7be415..8102af4ade 100644 +--- a/Tests/test_KGML_nographics.py ++++ b/Tests/test_KGML_nographics.py +@@ -83,7 +83,7 @@ def test_read_and_write_KGML_files(self): + """ + for p in self.data: + # Test opening file +- with open(p.infilename, "rU") as f: ++ with open(p.infilename) as f: + pathway = read(f) + # Do we have the correct number of elements of each type + self.assertEqual((len(pathway.entries), +@@ -95,7 +95,7 @@ def test_read_and_write_KGML_files(self): + with open(p.outfilename, "w") as f: + f.write(pathway.get_KGML()) + # Can we read the file we wrote? +- with open(p.outfilename, "rU") as f: ++ with open(p.outfilename) as f: + pathway = read(f) + # Do we have the correct number of elements of each type + self.assertEqual((len(pathway.entries), +--- a/Tests/test_PDB.py.python39 2019-12-20 13:37:02.000000000 +0100 ++++ b/Tests/test_PDB.py 2020-03-01 14:58:17.590202068 +0100 +@@ -538,7 +538,7 @@ + try: + io.save(filename) + # Check if there are lines besides 'ATOM', 'TER' and 'END' +- with open(filename, "rU") as handle: ++ with open(filename) as handle: + record_set = {l[0:6] for l in handle} + record_set -= {"ATOM ", "HETATM", "MODEL ", "ENDMDL", "TER\n", "TER ", "END\n", "END "} + self.assertEqual(record_set, set()) diff --git a/python-biopython.spec b/python-biopython.spec index f1bca55..6f0c7ae 100644 --- a/python-biopython.spec +++ b/python-biopython.spec @@ -26,10 +26,12 @@ Name: python-biopython Version: 1.76 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Python tools for computational molecular biology Source0: https://files.pythonhosted.org/packages/source/b/%{module}/%{module}-%{version}.tar.gz +Patch0: %{name}-1.76_python39.patch + # Starting from biopython-1.69, BioPython is released under the # "Biopython License Agreement"; it looks like a MIT variant # rhbz #1440337 @@ -176,6 +178,11 @@ cp -a %{module}-%{version} python2 %if 0%{?with_python3} cp -a %{module}-%{version} python3 +%if 0%{?python3_version_nodots} == 39 +pushd python3 +%patch0 -p1 -b .python39 +popd +%endif %endif # with_python3 @@ -312,6 +319,9 @@ popd %license %{module}-%{version}/LICENSE.rst %changelog +* Sat Feb 29 2020 Antonio Trande - 1.76-3 +- Patched for Python-3.9 + * Thu Jan 30 2020 Fedora Release Engineering - 1.76-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild