diff --git a/modules/base/pymod/table.py b/modules/base/pymod/table.py index bb7714f03affe139664797561202ad259a14e062..8697d63d08eb8e6f3101002a2973663981a99675 100644 --- a/modules/base/pymod/table.py +++ b/modules/base/pymod/table.py @@ -880,8 +880,10 @@ Statistics for column %(col)s def _LoadOST(stream_or_filename): fieldname_pattern=re.compile(r'(?P<name>[^[]+)(\[(?P<type>\w+)\])?') values_pattern=re.compile("([^\" ]+|\"[^\"]*\")+") + file_opened=False if not hasattr(stream_or_filename, 'read'): stream=open(stream_or_filename, 'r') + file_opened=True else: stream=stream_or_filename header=False @@ -904,10 +906,18 @@ Statistics for column %(col)s else: fieldtypes.append('string') fieldnames.append(match.group('name')) - tab=Table(fieldnames, fieldtypes) + try: + tab=Table(fieldnames, fieldtypes) + except Exception as e: + # potentially fails if we read in crap... clean up and pass on error + if file_opened: + stream.close() + raise e header=True continue tab.AddRow([x.strip('"') for x in values_pattern.findall(line)]) + if file_opened: + stream.close() if num_lines==0: raise IOError("Cannot read table from empty stream") return tab @@ -921,8 +931,10 @@ Statistics for column %(col)s @staticmethod def _LoadCSV(stream_or_filename, sep): + file_opened=False if not hasattr(stream_or_filename, 'read'): stream=open(stream_or_filename, 'r') + file_opened=True else: stream=stream_or_filename reader=csv.reader(stream, delimiter=sep) @@ -935,6 +947,8 @@ Statistics for column %(col)s first=False else: tab.AddRow(row) + if file_opened: + stream.close() if first: raise IOError('trying to load table from empty CSV stream/file') @@ -943,11 +957,16 @@ Statistics for column %(col)s @staticmethod def _LoadPickle(stream_or_filename): + file_opened=False if not hasattr(stream_or_filename, 'read'): stream=open(stream_or_filename, 'rb') + file_opened=True else: stream=stream_or_filename - return pickle.load(stream) + tab = pickle.load(stream) + if file_opened: + stream.close() + return tab @staticmethod def _GuessFormat(filename): @@ -2210,9 +2229,13 @@ Statistics for column %(col)s raise ValueError('unknown format "%s"' % format) def _SavePickle(self, stream): + file_opened=False if not hasattr(stream, 'write'): stream=open(stream, 'wb') + file_opened=True pickle.dump(self, stream, pickle.HIGHEST_PROTOCOL) + if file_opened: + stream.close() def _SaveHTML(self, stream_or_filename): def _escape(s): @@ -2288,8 +2311,10 @@ Statistics for column %(col)s stream.close() def _SaveCSV(self, stream, sep): + file_opened=False if not hasattr(stream, 'write'): stream=open(stream, 'w') + file_opened=True writer=csv.writer(stream, delimiter=sep) writer.writerow(['%s' % n for n in self.col_names]) @@ -2299,13 +2324,18 @@ Statistics for column %(col)s if c==None: row[i]='NA' writer.writerow(row) + if file_opened: + stream.close() + def _SaveOST(self, stream): + file_opened=False if hasattr(stream, 'write'): writer=csv.writer(stream, delimiter=' ') else: stream=open(stream, 'w') writer=csv.writer(stream, delimiter=' ') + file_opened=True if self.comment: stream.write(''.join(['# %s\n' % l for l in self.comment.split('\n')])) writer.writerow(['%s[%s]' % t for t in zip(self.col_names, self.col_types)]) @@ -2315,7 +2345,9 @@ Statistics for column %(col)s if c==None: row[i]='NA' writer.writerow(row) - + if file_opened: + stream.close() + def GetNumpyMatrix(self, *args): ''' diff --git a/modules/base/tests/test_table.py b/modules/base/tests/test_table.py index 640e7c3663517d5843631843e6c3927eb059d38c..5d56f67ee49732ce6f875ecfc169908162d81d5f 100644 --- a/modules/base/tests/test_table.py +++ b/modules/base/tests/test_table.py @@ -907,6 +907,7 @@ class TestTable(unittest.TestCase): self.assertRaises(IOError, Table.Load, os.path.join('testfiles','emptytable.tab')) in_stream = open(os.path.join('testfiles','emptytable.csv'), 'r') self.assertRaises(IOError, Table.Load, in_stream) + in_stream.close() def testSaveLoadTableOSTWithSpaces(self): tab = self.CreateTestTable() diff --git a/modules/bindings/pymod/blast.py b/modules/bindings/pymod/blast.py index 80409f492957991a942d8e4f13ec9d2fc2f428ad..89893323a6787f0ef40183a9d1a2ae4321cd534a 100644 --- a/modules/bindings/pymod/blast.py +++ b/modules/bindings/pymod/blast.py @@ -166,9 +166,10 @@ def CreateDB(infasta, dbout, mkdb_cmd=None): else: raise IOError('mkdb command must either be the path to formatdb or makeblastdb!') - cmd=' '.join(args) - ost.LogInfo('creating blast DB (%s)' % cmd) - os.system(cmd) + ost.LogInfo('creating blast DB (%s)' % ' '.join(args)) + blast_pipe=subprocess.Popen(args, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + blast_pipe.communicate() def BlastVersion(blast_location=None): """ diff --git a/modules/bindings/pymod/cadscore.py b/modules/bindings/pymod/cadscore.py index 362325c87bed18910ba802240fb941f853eee723..193bfc87f274f723e6396df461d7a2496159d48a 100644 --- a/modules/bindings/pymod/cadscore.py +++ b/modules/bindings/pymod/cadscore.py @@ -186,7 +186,7 @@ def _RunCAD(tmp_dir, mode, cad_bin_path, old_regime): "cadtemp")) ps1=subprocess.Popen(command1, shell=True, stdout=subprocess.PIPE) - ps1.wait() + ps1.communicate() ps2=subprocess.Popen(command2, shell=True, stdout=subprocess.PIPE) stdout,_ = ps2.communicate() lines=stdout.decode().splitlines() @@ -232,7 +232,8 @@ def _RunCAD(tmp_dir, mode, cad_bin_path, old_regime): except: raise RuntimeError("CAD calculation failed") try: - localAA = _ParseVoronotaLocal(open(local_score_filename).readlines()) + with open(local_score_filename) as f: + localAA = _ParseVoronotaLocal(f.readlines()) except: raise RuntimeError("CAD calculation failed") diff --git a/modules/bindings/pymod/clustalw.py b/modules/bindings/pymod/clustalw.py index 7ed4e8259d70868b9d1c66a865a5cd26d220f449..0741992832e14f2d6bc65f5473d6ab02b2f8872c 100644 --- a/modules/bindings/pymod/clustalw.py +++ b/modules/bindings/pymod/clustalw.py @@ -129,8 +129,8 @@ def ClustalW(seq1, seq2=None, clustalw=None, keep_files=False, nopgap=False, if clustalw_option_string!=False: command=command+" "+clustalw_option_string #see useful flags: http://toolkit.tuebingen.mpg.de/clustalw/help_params - ps=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) - ps.wait() + with subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) as ps: + ps.wait() aln=io.LoadAlignment(out) diff --git a/modules/bindings/pymod/kclust.py b/modules/bindings/pymod/kclust.py index edcbc4797f6a33669587701652b0871c728e2c38..076141f6bd55c6b895cf2a860fdd68f8ca2e618c 100644 --- a/modules/bindings/pymod/kclust.py +++ b/modules/bindings/pymod/kclust.py @@ -56,8 +56,10 @@ def _CleanupFiles(tmp_dir_name): def _ParseOutput(tmp_dir_name): - header_data=open(os.path.join(tmp_dir_name,'headers.dmp'),'r').readlines() - cluster_data=open(os.path.join(tmp_dir_name,'clusters.dmp'),'r').readlines() + with open(os.path.join(tmp_dir_name,'headers.dmp'),'r') as f: + header_data=f.readlines() + with open(os.path.join(tmp_dir_name,'clusters.dmp'),'r') as f: + cluster_data=f.readlines() sequences=io.LoadSequenceList(os.path.join(tmp_dir_name,'fastadb.fasta')) clusters=dict() diff --git a/modules/bindings/tests/test_blast.py b/modules/bindings/tests/test_blast.py index fbadfccb1dd17559f9dd2db309f87fd20ff776f8..9be501b00856249910d3fb45e962035e891fe7cb 100644 --- a/modules/bindings/tests/test_blast.py +++ b/modules/bindings/tests/test_blast.py @@ -52,7 +52,8 @@ class TestBlastBindings(unittest.TestCase): def testBlastParseOutput(self): - raw_out=open('testfiles/raw_blastout.txt','r').read() + with open('testfiles/raw_blastout.txt','r') as f: + raw_out=f.read() parsed_out=blast.ParseBlastOutput(raw_out) diff --git a/modules/bindings/tests/test_hhblits.py b/modules/bindings/tests/test_hhblits.py index eaff9a3f78927711865be248cfe8a0958b5de988..1bc6b3652dee18736ffc03050862483c262726ad 100644 --- a/modules/bindings/tests/test_hhblits.py +++ b/modules/bindings/tests/test_hhblits.py @@ -129,10 +129,10 @@ class TestHHblitsBindings(unittest.TestCase): os.remove(self.tmpfile) hhfile = self.hh.A3MToProfile("testfiles/testali.a3m", hhm_file=self.tmpfile) - tfh = open(hhfile) - efh = open("testfiles/test.hmm") - elst = efh.readlines() - tlst = tfh.readlines() + with open(hhfile) as tfh: + tlst = tfh.readlines() + with open("testfiles/test.hmm") as efh: + elst = efh.readlines() self.assertEqual(len(elst), len(tlst)) for i in range(0, len(elst)): if not elst[i].startswith(('FILE', 'COM', 'DATE')): @@ -147,10 +147,10 @@ class TestHHblitsBindings(unittest.TestCase): 'TSKYR') self.hh = hhblits.HHblits(query_seq, self.hhroot) hhfile = self.hh.A3MToProfile("testfiles/testali.a3m") - tfh = open(hhfile) - efh = open("testfiles/test.hmm") - elst = efh.readlines() - tlst = tfh.readlines() + with open(hhfile) as tfh: + tlst = tfh.readlines() + with open("testfiles/test.hmm") as efh: + elst = efh.readlines() self.assertEqual(len(elst), len(tlst)) for i in range(0, len(elst)): if not elst[i].startswith(('FILE', 'COM', 'DATE')): @@ -244,10 +244,12 @@ class TestHHblitsBindings(unittest.TestCase): self.hh = hhblits.HHblits(query_seq, self.hhroot) search_file = self.hh.Search("testfiles/testali.a3m", 'testfiles/hhblitsdb/hhblitsdb') - tfh = open(search_file) - efh = open("testfiles/test.hhr") - elst = efh.readlines() - tlst = tfh.readlines() + + with open(search_file) as tfh: + tlst = tfh.readlines() + with open("testfiles/test.hhr") as efh: + elst = efh.readlines() + self.assertEqual(len(elst), len(tlst)) for i in range(0, len(elst)): if not elst[i].startswith(('Date', 'Command')): @@ -286,7 +288,8 @@ class TestHHblitsBindings(unittest.TestCase): def testParseHHMNotWorking(self): # get info from an HHM file with self.assertRaises(IOError) as ioe: - hhblits.ParseHHM(open('testfiles/testali.a3m')) + with open('testfiles/testali.a3m') as f: + hhblits.ParseHHM(f) self.assertEqual(ioe.exception.args[0], 'Profile file "testfiles/testali.a3m" is missing '+ 'the "Consensus" section') @@ -317,7 +320,8 @@ class TestHHblitsBindings(unittest.TestCase): self.assertAlmostEqual(hit.ss_score, 34.1) def testParseHHblitsOutput(self): - header, hits = hhblits.ParseHHblitsOutput(open("testfiles/test.hhr")) + with open("testfiles/test.hhr") as f: + header, hits = hhblits.ParseHHblitsOutput(f) self.assertEqual(header.query, 'Test') self.assertEqual(header.match_columns, 141) self.assertEqual(header.n_eff, 9.4)