fix return-value/deprecated API bugs, accumulation lock leaks, code cleanup
Build Debian Packages / build (bookworm, debian12) (push) Successful in 8m56s
Build Debian Packages / build (trixie, debian13) (push) Successful in 9m3s

- raise instead of silent None for unsupported operands and empty negation
- validate before acquiring lock in Accumulation operators (no RLock leak)
- Accumulation._copy_provenance helper, ADC_Result._copy_metadata for all result paths
- shared _sandbox_stdout_redirect contextmanager for sandboxed scripts
- TemperatureMonitor dead code removal (gtk helper, traceback, unused properties)
- new unit tests incl. lock-freedom regression test
- gitignore sphinx generated doc/_autosummary/ and doc/damaris/
This commit is contained in:
markusro committed 2026-10-17 19:17:43 +02:00
1 parent 91ade4376c
commit f9d8de7697
26 files changed
+590 -236

No files matched your search

+36 -26
View File
@@ -102,6 +102,14 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
else:
raise ValueError("Wrong usage of __init__!")
def _copy_provenance(self, r):
r.is_clipped = self.is_clipped
r.job_id = self.job_id
r.job_ids = self.job_ids.copy()
r.time_period = self.time_period[:] if self.time_period is not None else None
if self.common_descriptions is not None:
r.common_descriptions = self.common_descriptions.copy()
def get_accu_by_index(self, index: int):
self.lock.acquire()
try:
@@ -637,12 +645,7 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
r = Accumulation(x = numpy.array(self.x, dtype="float32"), y = tmp_y, y_2 = tmp_ysquare, n = self.n, index = self.index, sampl_freq = self.sampling_rate, error = self.use_error)
else:
r = Accumulation(x = numpy.array(self.x, dtype="float32"), y = tmp_y, n = self.n, index = self.index, sampl_freq = self.sampling_rate, error = self.use_error)
r.is_clipped = self.is_clipped
r.job_id = self.job_id
r.job_ids = self.job_ids.copy()
r.time_period = self.time_period[:] if self.time_period is not None else None
if self.common_descriptions is not None:
r.common_descriptions = self.common_descriptions.copy()
self._copy_provenance(r)
self.lock.release()
return r
@@ -678,8 +681,6 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
# Other and self not empty (self + other ADC_Result)
else:
self.lock.acquire()
if self.sampling_rate != other.get_sampling_rate():
raise ValueError("Accumulation: You cant add ADC_Results with different sampling-rates")
if len(self.y[0]) != len(other):
@@ -690,6 +691,8 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
if self.index[i] != other.get_index_bounds(i):
raise ValueError("Accumulation: You cant add ADC_Results with different indexing")
self.lock.acquire()
tmp_y = []
tmp_ysquare = []
@@ -706,7 +709,7 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
r.time_period=[min(self.time_period[0],other.job_date),
max(self.time_period[1],other.job_date)]
r.job_id = other.job_id
r.job_ids = self.job_ids
r.job_ids = self.job_ids.copy()
r.job_ids[other.job_id] = other.get_job_date()
if self.common_descriptions is not None:
@@ -725,33 +728,29 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
# Self empty (copy)
if not self.contains_data():
if self.uses_statistics() and not other.uses_statistics():
raise ValueError("Accumulation: You cant add non-error accumulations to accumulations with error")
self.lock.acquire()
tmp_y = []
tmp_ysquare = []
self.lock.acquire()
for i in range(other.get_number_of_channels()):
tmp_y.append(numpy.array(other.y[i], dtype="float32"))
if other.uses_statistics():
tmp_ysquare.append(numpy.array(other.y_square[i], dtype="float32"))
if self.uses_statistics():
r = Accumulation(x = numpy.array(other.x, dtype="float32"), y = tmp_y, y_2 = tmp_ysquare, n = other.n, index = other.index, sampl_freq = other.sampling_rate, error = True)
else:
r = Accumulation(x = numpy.array(other.x, dtype="float32"), y = tmp_y, n = other.n, index = other.index, sampl_freq = other.sampling_rate, error = False)
for i in range(other.get_number_of_channels()):
tmp_y.append(other.y[i])
tmp_ysquare.append(other.y_square[i])
r.time_period=other.time_period[:]
r.job_id = other.job_id
r.job_ids = other.job_ids
if other.common_descriptions is not None:
r.common_descriptions=other.common_descriptions.copy()
else:
r.common_descriptions=None
other._copy_provenance(r)
self.lock.release()
return r
# Other and self not empty (self + other)
else:
self.lock.acquire()
if self.sampling_rate != other.get_sampling_rate():
raise ValueError("Accumulation: You cant add accumulations with different sampling-rates")
if len(self.y[0]) != len(other):
@@ -764,6 +763,8 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
if self.uses_statistics() and not other.uses_statistics():
raise ValueError("Accumulation: You cant add non-error accumulations to accumulations with error")
self.lock.acquire()
tmp_y = []
tmp_ysquare = []
@@ -780,6 +781,7 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
r.time_period=[min(self.time_period[0],other.time_period[0]),
max(self.time_period[1],other.time_period[1])]
r.job_id = other.job_id
r.job_ids = self.job_ids.copy()
for i in other.job_ids:
r.job_ids[i] = other.job_ids[i]
r.common_descriptions={}
@@ -793,6 +795,12 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
return r
elif other is None:
# Convenience: ignore add of None
return self + 0
else:
raise ValueError("can not add "+repr(type(other))+" to Accumulation")
def __radd__(self, other):
"""Redefining other + self"""
return self.__add__(other)
@@ -992,8 +1000,6 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
# Other and self not empty (self + other/ADC_Result)
else:
self.lock.acquire()
if self.sampling_rate != other.get_sampling_rate():
raise ValueError("Accumulation: You can't add ADC-Results with different sampling-rates")
if len(self.y[0]) != len(other):
@@ -1004,6 +1010,8 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
if self.index[i] != other.get_index_bounds(i):
raise ValueError("Accumulation: You can't add ADC-Results with different indexing")
self.lock.acquire()
for i in range(self.get_number_of_channels()):
self.y[i] += other.y[i]
if self.uses_statistics():
@@ -1062,7 +1070,6 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
# Other and self not empty (self + other)
else:
self.lock.acquire()
if self.sampling_rate != other.get_sampling_rate():
raise ValueError("Accumulation: You cant add accumulations with different sampling-rates")
if len(self.y[0]) != len(other):
@@ -1074,6 +1081,8 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
raise ValueError("Accumulation: You cant add accumulations with different indexing")
if self.uses_statistics() and not other.uses_statistics():
raise ValueError("Accumulation: You cant add non-error accumulations to accumulations with error")
self.lock.acquire()
for i in range(self.get_number_of_channels()):
self.y[i] += other.y[i]
@@ -1123,7 +1132,7 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
"""Redefining -self"""
if not self.contains_data():
return
raise ValueError("Accumulation: You cant negate an empty accumulation")
tmp_y = []
@@ -1135,6 +1144,7 @@ class Accumulation(Errorable, Drawable, DamarisFFT, Signalpath):
r = Accumulation(x = numpy.array(self.x, dtype="float32"), y = tmp_y, y_2 = numpy.array(self.y_square), n = self.n, index = self.index, sampl_freq = self.sampling_rate, error = True)
else:
r = Accumulation(x = numpy.array(self.x, dtype="float32"), y = tmp_y, n = self.n, index = self.index, sampl_freq = self.sampling_rate, error = False)
self._copy_provenance(r)
self.lock.release()
return r