From 5cd8df89be20c826732add9c039a45e783ea092c Mon Sep 17 00:00:00 2001 From: Markus Rosenstihl Date: Sun, 12 Jul 2026 10:54:06 +0200 Subject: [PATCH] Fix file handle leaks (Fixes #35) --- src/damaris/data/ADC_Result.py | 51 +++++++++++++++--------------- src/damaris/data/Accumulation.py | 53 +++++++++++++++++--------------- 2 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/damaris/data/ADC_Result.py b/src/damaris/data/ADC_Result.py index d7fe4a3..e5b6ae7 100644 --- a/src/damaris/data/ADC_Result.py +++ b/src/damaris/data/ADC_Result.py @@ -220,26 +220,25 @@ class ADC_Result(Resultable, Drawable, DamarisFFT, Signalpath): destination can be a file or a filename suitable for further processing """ - # write sorted - the_destination=destination - if type(destination) in (str,): - the_destination=open(destination, "w") + if isinstance(destination, str): + with open(destination, "w") as f: + self._write_to_csv_dest(f, delimiter) + else: + self._write_to_csv_dest(destination, delimiter) - the_destination.write("# adc_result\n") - the_destination.write("# t y0 y1 ...\n") + def _write_to_csv_dest(self, dest, delimiter): + dest.write("# adc_result\n") + dest.write("# t y0 y1 ...\n") self.lock.acquire() try: xdata=self.get_xdata() ch_no=self.get_number_of_channels() ydata=list(map(self.get_ydata, range(ch_no))) - #yerr=map(self.get_yerr, xrange(ch_no)) for i in range(len(xdata)): - the_destination.write("%e"%xdata[i]) + dest.write("%e"%xdata[i]) for j in range(ch_no): - the_destination.write("%s%e"%(delimiter, ydata[j][i])) - the_destination.write("\n") - the_destination=None - xdata=ydata=None + dest.write("%s%e"%(delimiter, ydata[j][i])) + dest.write("\n") finally: self.lock.release() @@ -249,28 +248,28 @@ class ADC_Result(Resultable, Drawable, DamarisFFT, Signalpath): for further processing with the NMRnotebook software; destination can be a file or a filename """ - # write sorted - the_destination=destination - if type(destination) in (str,): - the_destination=open(destination, "w") + if isinstance(destination, str): + with open(destination, "w") as f: + self._write_to_simpson_dest(f, delimiter) + else: + self._write_to_simpson_dest(destination, delimiter) + def _write_to_simpson_dest(self, dest, delimiter): self.lock.acquire() try: xdata=self.get_xdata() - the_destination.write("SIMP\n") - the_destination.write("%s%i%s"%("NP=", len(xdata), "\n")) - the_destination.write("%s%i%s"%("SW=", self.get_sampling_rate(), "\n")) - the_destination.write("TYPE=FID\n") - the_destination.write("DATA\n") + dest.write("SIMP\n") + dest.write("%s%i%s"%("NP=", len(xdata), "\n")) + dest.write("%s%i%s"%("SW=", self.get_sampling_rate(), "\n")) + dest.write("TYPE=FID\n") + dest.write("DATA\n") ch_no=self.get_number_of_channels() ydata=list(map(self.get_ydata, range(ch_no))) for i in range(len(xdata)): for j in range(ch_no): - the_destination.write("%g%s"%(ydata[j][i], delimiter)) - the_destination.write("\n") - the_destination.write("END\n") - the_destination=None - xdata=ydata=None + dest.write("%g%s"%(ydata[j][i], delimiter)) + dest.write("\n") + dest.write("END\n") finally: self.lock.release() diff --git a/src/damaris/data/Accumulation.py b/src/damaris/data/Accumulation.py index 53ff562..15a7787 100644 --- a/src/damaris/data/Accumulation.py +++ b/src/damaris/data/Accumulation.py @@ -248,38 +248,41 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath): writes the data to a file. destination can be a filehandle or a filename, default sys.stdout """ - the_destination=destination if isinstance(destination, str): - the_destination=open(destination, "w") + with open(destination, "w") as f: + self._write_to_csv_dest(f, delimiter) + else: + self._write_to_csv_dest(destination, delimiter) - the_destination.write("# accumulation %d\n"%self.n) + def _write_to_csv_dest(self, dest, delimiter): + dest.write("# accumulation %d\n"%self.n) self.lock.acquire() try: if self.common_descriptions is not None: for (key,value) in self.common_descriptions.items(): - the_destination.write("# %s : %s\n"%(key, str(value))) - the_destination.write("# t") + dest.write("# %s : %s\n"%(key, str(value))) + dest.write("# t") ch_no=self.get_number_of_channels() if self.use_error: for i in range(ch_no): - the_destination.write(" ch%d_mean ch%d_err"%(i,i)) + dest.write(" ch%d_mean ch%d_err"%(i,i)) else: for i in range(ch_no): - the_destination.write(" ch%d_mean"%i) - the_destination.write("\n") + dest.write(" ch%d_mean"%i) + dest.write("\n") xdata=self.get_xdata() ydata=list(map(self.get_ydata, range(ch_no))) yerr=None if self.use_error: yerr=list(map(self.get_yerr, range(ch_no))) for i in range(len(xdata)): - the_destination.write("%e"%xdata[i]) + dest.write("%e"%xdata[i]) for j in range(ch_no): if self.use_error: - the_destination.write("%s%e%s%e"%(delimiter, ydata[j][i], delimiter, yerr[j][i])) + dest.write("%s%e%s%e"%(delimiter, ydata[j][i], delimiter, yerr[j][i])) else: - the_destination.write("%s%e"%(delimiter,ydata[j][i])) - the_destination.write("\n") + dest.write("%s%e"%(delimiter,ydata[j][i])) + dest.write("\n") finally: self.lock.release() @@ -290,27 +293,29 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath): for further processing with the NMRnotebook software; destination can be a file or a filename """ - the_destination=destination if isinstance(destination, str): - the_destination=open(destination, "w") + with open(destination, "w") as f: + self._write_to_simpson_dest(f, delimiter, frequency) + else: + self._write_to_simpson_dest(destination, delimiter, frequency) + def _write_to_simpson_dest(self, dest, delimiter, frequency): self.lock.acquire() try: xdata=self.get_xdata() - the_destination.write("SIMP\n") - the_destination.write("%s%i%s"%("NP=", len(xdata), "\n")) - the_destination.write("%s%i%s"%("SW=", self.get_sampling_rate(), "\n")) - the_destination.write("%s%i%s"%("REF=", frequency, "\n")) - the_destination.write("TYPE=FID\n") - the_destination.write("DATA\n") + dest.write("SIMP\n") + dest.write("%s%i%s"%("NP=", len(xdata), "\n")) + dest.write("%s%i%s"%("SW=", self.get_sampling_rate(), "\n")) + dest.write("%s%i%s"%("REF=", frequency, "\n")) + dest.write("TYPE=FID\n") + dest.write("DATA\n") ch_no=self.get_number_of_channels() ydata=list(map(self.get_ydata, range(ch_no))) for i in range(len(xdata)): for j in range(ch_no): - the_destination.write("%g%s"%(ydata[j][i], delimiter)) - the_destination.write("\n") - the_destination.write("END\n") - the_destination.close() + dest.write("%g%s"%(ydata[j][i], delimiter)) + dest.write("\n") + dest.write("END\n") finally: self.lock.release()