From 4fc147557e60b96998a0befdc42395b68a1b78ad Mon Sep 17 00:00:00 2001 From: Sebbe Blokhuizen Date: Wed, 29 Oct 2025 16:13:45 +0100 Subject: [PATCH 1/3] ruff linting --- waveform_editor/base_waveform.py | 3 +-- waveform_editor/derived_waveform.py | 3 +-- waveform_editor/exporter.py | 6 ++++-- waveform_editor/gui/editor.py | 3 +-- waveform_editor/gui/io/filebrowser.py | 2 +- waveform_editor/gui/selector/selection_group.py | 4 ++-- waveform_editor/pcssp_exporter.py | 2 +- waveform_editor/tendencies/base.py | 3 +-- waveform_editor/tendencies/constant.py | 4 +--- waveform_editor/tendencies/linear.py | 4 +--- waveform_editor/tendencies/periodic/sawtooth_wave.py | 4 +--- waveform_editor/tendencies/periodic/sine_wave.py | 4 +--- waveform_editor/tendencies/periodic/square_wave.py | 4 +--- waveform_editor/tendencies/periodic/triangle_wave.py | 4 +--- waveform_editor/tendencies/piecewise.py | 4 +--- waveform_editor/tendencies/repeat.py | 4 +--- waveform_editor/tendencies/smooth.py | 4 +--- waveform_editor/waveform.py | 5 ++--- 18 files changed, 23 insertions(+), 44 deletions(-) diff --git a/waveform_editor/base_waveform.py b/waveform_editor/base_waveform.py index 348374bd..6d88084b 100644 --- a/waveform_editor/base_waveform.py +++ b/waveform_editor/base_waveform.py @@ -1,5 +1,4 @@ from abc import ABC, abstractmethod -from typing import Optional import imas import numpy as np @@ -21,7 +20,7 @@ def __init__(self, yaml_str, name, dd_version): @abstractmethod def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: raise NotImplementedError diff --git a/waveform_editor/derived_waveform.py b/waveform_editor/derived_waveform.py index 22930027..79d623da 100644 --- a/waveform_editor/derived_waveform.py +++ b/waveform_editor/derived_waveform.py @@ -1,5 +1,4 @@ import ast -from typing import Optional import numpy as np from asteval import Interpreter @@ -127,7 +126,7 @@ def _build_eval_context(self, time: np.ndarray) -> dict: return eval_context def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Evaluate the derived waveform expression at specified times. diff --git a/waveform_editor/exporter.py b/waveform_editor/exporter.py index 751b937e..de041df0 100644 --- a/waveform_editor/exporter.py +++ b/waveform_editor/exporter.py @@ -193,7 +193,9 @@ def _fill_waveforms(self, ids, waveforms): # Here, phase/angle should be filled for all 4 beams. # However, certain niche cases involving multiple slices for different waveforms # might still not be handled correctly. - for waveform, (path, values) in zip(waveforms, values_per_waveform): + for waveform, (path, values) in zip( + waveforms, values_per_waveform, strict=False + ): logger.debug(f"Filling {waveform.name}...") self._fill_nodes_recursively(ids, path, values) self._increment_progress() @@ -228,7 +230,7 @@ def _fill_nodes_recursively(self, node, path, values, path_index=0, fill=True): if node.metadata.type.is_dynamic and part != path.parts[-1]: if len(node) != len(values): node.resize(len(values), keep=True) - for item, value in zip(node, values): + for item, value in zip(node, values, strict=False): self._fill_nodes_recursively(item, path, value, next_index) else: self._fill_nodes_recursively(node, path, values, next_index) diff --git a/waveform_editor/gui/editor.py b/waveform_editor/gui/editor.py index 4e0b6c3c..75c7083d 100644 --- a/waveform_editor/gui/editor.py +++ b/waveform_editor/gui/editor.py @@ -1,5 +1,4 @@ import textwrap -from typing import Optional import panel as pn import param @@ -53,7 +52,7 @@ def __init__(self, config): # Initialize empty self.set_waveform(None) - def set_waveform(self, waveform: Optional[str]) -> None: + def set_waveform(self, waveform: str | None) -> None: """Start editing a waveform. Args: diff --git a/waveform_editor/gui/io/filebrowser.py b/waveform_editor/gui/io/filebrowser.py index af3833d6..5b432c52 100644 --- a/waveform_editor/gui/io/filebrowser.py +++ b/waveform_editor/gui/io/filebrowser.py @@ -147,7 +147,7 @@ def _update_files( paths.insert(0, "..") abbreviated.insert(0, "⬆ ..") - options = dict(zip(abbreviated, paths)) + options = dict(zip(abbreviated, paths, strict=False)) self._selector.options = options self._selector.value = [s for s in selected if s in paths] diff --git a/waveform_editor/gui/selector/selection_group.py b/waveform_editor/gui/selector/selection_group.py index d566d6bb..7332101f 100644 --- a/waveform_editor/gui/selector/selection_group.py +++ b/waveform_editor/gui/selector/selection_group.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING import panel as pn import param @@ -20,7 +20,7 @@ class SelectionGroup(Viewer): def __init__( self, selector: "WaveformSelector", - group: Union[WaveformConfiguration, WaveformGroup], + group: WaveformConfiguration | WaveformGroup, path: list[str], ) -> None: name = getattr(group, "name", "") diff --git a/waveform_editor/pcssp_exporter.py b/waveform_editor/pcssp_exporter.py index f543c13e..5661bc8b 100644 --- a/waveform_editor/pcssp_exporter.py +++ b/waveform_editor/pcssp_exporter.py @@ -79,5 +79,5 @@ def _add_trajectories(self, segment): ET.SubElement(trajectory, "EXIT_RULE", {"is": "Last"}) reference = ET.SubElement(trajectory, "REFERENCE") values = waveform.get_value(self.times)[1] - for t, v in zip(self.times, values): + for t, v in zip(self.times, values, strict=False): ET.SubElement(reference, "POINT", {"time": str(t), "value": str(v)}) diff --git a/waveform_editor/tendencies/base.py b/waveform_editor/tendencies/base.py index 71ed7977..cd12e11e 100644 --- a/waveform_editor/tendencies/base.py +++ b/waveform_editor/tendencies/base.py @@ -1,5 +1,4 @@ from abc import abstractmethod -from typing import Optional import numpy as np import param @@ -228,7 +227,7 @@ def _get_value_and_derivative(self, time): @abstractmethod def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array.""" raise NotImplementedError() diff --git a/waveform_editor/tendencies/constant.py b/waveform_editor/tendencies/constant.py index fa976d05..6b1cd4af 100644 --- a/waveform_editor/tendencies/constant.py +++ b/waveform_editor/tendencies/constant.py @@ -1,5 +1,3 @@ -from typing import Optional - import numpy as np import param from param import depends @@ -22,7 +20,7 @@ def __init__(self, **kwargs): super().__init__(**kwargs) def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array. If no time array is provided, a constant line containing the start and end points will be generated. diff --git a/waveform_editor/tendencies/linear.py b/waveform_editor/tendencies/linear.py index 27d96078..752f7cf4 100644 --- a/waveform_editor/tendencies/linear.py +++ b/waveform_editor/tendencies/linear.py @@ -1,5 +1,3 @@ -from typing import Optional - import numpy as np import param from param import depends @@ -36,7 +34,7 @@ def __init__(self, **kwargs): super().__init__(**kwargs) def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array. If no time array is provided, a line containing the start and end points will be generated. diff --git a/waveform_editor/tendencies/periodic/sawtooth_wave.py b/waveform_editor/tendencies/periodic/sawtooth_wave.py index 54ad09ae..aad60cfb 100644 --- a/waveform_editor/tendencies/periodic/sawtooth_wave.py +++ b/waveform_editor/tendencies/periodic/sawtooth_wave.py @@ -1,5 +1,3 @@ -from typing import Optional - import numpy as np from waveform_editor.tendencies.periodic.periodic_base import PeriodicBaseTendency @@ -9,7 +7,7 @@ class SawtoothWaveTendency(PeriodicBaseTendency): """A tendency representing a sawtooth wave.""" def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array. If no time array is provided, a time array will be created from the start to the end of the diff --git a/waveform_editor/tendencies/periodic/sine_wave.py b/waveform_editor/tendencies/periodic/sine_wave.py index f4c24a2f..2d6dddea 100644 --- a/waveform_editor/tendencies/periodic/sine_wave.py +++ b/waveform_editor/tendencies/periodic/sine_wave.py @@ -1,5 +1,3 @@ -from typing import Optional - import numpy as np from waveform_editor.tendencies.periodic.periodic_base import PeriodicBaseTendency @@ -9,7 +7,7 @@ class SineWaveTendency(PeriodicBaseTendency): """A tendency representing a sine wave.""" def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array. If no time array is provided, a linearly spaced time array will be generated from the start to the diff --git a/waveform_editor/tendencies/periodic/square_wave.py b/waveform_editor/tendencies/periodic/square_wave.py index 501a6ee8..365b7859 100644 --- a/waveform_editor/tendencies/periodic/square_wave.py +++ b/waveform_editor/tendencies/periodic/square_wave.py @@ -1,5 +1,3 @@ -from typing import Optional - import numpy as np from waveform_editor.tendencies.periodic.periodic_base import PeriodicBaseTendency @@ -9,7 +7,7 @@ class SquareWaveTendency(PeriodicBaseTendency): """A tendency representing a square wave.""" def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array. If no time array is provided, a time array will be created from the start to the end of the diff --git a/waveform_editor/tendencies/periodic/triangle_wave.py b/waveform_editor/tendencies/periodic/triangle_wave.py index fc8c3a90..2de79bd3 100644 --- a/waveform_editor/tendencies/periodic/triangle_wave.py +++ b/waveform_editor/tendencies/periodic/triangle_wave.py @@ -1,5 +1,3 @@ -from typing import Optional - import numpy as np from waveform_editor.tendencies.periodic.periodic_base import PeriodicBaseTendency @@ -9,7 +7,7 @@ class TriangleWaveTendency(PeriodicBaseTendency): """A tendency representing a triangle wave.""" def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array. If no time array is provided, a time array will be created from the start to the end of the diff --git a/waveform_editor/tendencies/piecewise.py b/waveform_editor/tendencies/piecewise.py index aa6e6ee9..6386c293 100644 --- a/waveform_editor/tendencies/piecewise.py +++ b/waveform_editor/tendencies/piecewise.py @@ -1,5 +1,3 @@ -from typing import Optional - import numpy as np import param @@ -38,7 +36,7 @@ def __init__(self, user_time=None, user_value=None, **kwargs): self.param.update(values_changed=True) def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array. If a time array is provided, the values will be linearly interpolated between the piecewise linear diff --git a/waveform_editor/tendencies/repeat.py b/waveform_editor/tendencies/repeat.py index 48218295..68a87c8a 100644 --- a/waveform_editor/tendencies/repeat.py +++ b/waveform_editor/tendencies/repeat.py @@ -1,5 +1,3 @@ -from typing import Optional - import numpy as np import param @@ -84,7 +82,7 @@ def _set_period(self): self.annotations.add(self.line_number, error_msg, is_warning=True) def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array. If no time array is provided, the individual tendencies are responsible for creating a time array, diff --git a/waveform_editor/tendencies/smooth.py b/waveform_editor/tendencies/smooth.py index 9c20700d..54ad4e16 100644 --- a/waveform_editor/tendencies/smooth.py +++ b/waveform_editor/tendencies/smooth.py @@ -1,5 +1,3 @@ -from typing import Optional - import numpy as np import param from param import depends @@ -28,7 +26,7 @@ def __init__(self, **kwargs): super().__init__(**kwargs) def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array. If no time array is provided, a linearly spaced time array will be generated from the start to the diff --git a/waveform_editor/waveform.py b/waveform_editor/waveform.py index 2cb10ece..4838f362 100644 --- a/waveform_editor/waveform.py +++ b/waveform_editor/waveform.py @@ -1,5 +1,4 @@ import io -from typing import Optional import numpy as np from ruamel.yaml import YAML @@ -51,7 +50,7 @@ def __init__( self._process_waveform(waveform) def get_value( - self, time: Optional[np.ndarray] = None + self, time: np.ndarray | None = None ) -> tuple[np.ndarray, np.ndarray]: """Get the tendency values at the provided time array. If no time array is provided, the individual tendencies are responsible for creating a time array, @@ -67,7 +66,7 @@ def get_value( return np.array([]), np.array([]) if time is None: - time, values = zip(*(t.get_value() for t in self.tendencies)) + time, values = zip(*(t.get_value() for t in self.tendencies), strict=False) time = np.concatenate(time) values = np.concatenate(values) else: From 7442aa43942b4d1e82391f90dc7fb3d4b82fa288 Mon Sep 17 00:00:00 2001 From: Sebbe Blokhuizen Date: Thu, 30 Oct 2025 15:23:44 +0100 Subject: [PATCH 2/3] add minimal python version in pyproject.toml --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 045f3513..6ca94b0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,7 @@ authors = [ classifiers = [ ] license = {file = "LICENSE.txt"} +requires-python = ">=3.10" dependencies = [ "numpy", "pandas", From cf95371602ef848be74e5d86d319d0e09a25611e Mon Sep 17 00:00:00 2001 From: Sebbe Blokhuizen Date: Fri, 31 Oct 2025 11:08:41 +0100 Subject: [PATCH 3/3] update zip to strict --- waveform_editor/exporter.py | 4 ++-- waveform_editor/gui/io/filebrowser.py | 2 +- waveform_editor/pcssp_exporter.py | 2 +- waveform_editor/waveform.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/waveform_editor/exporter.py b/waveform_editor/exporter.py index de041df0..2882d8ce 100644 --- a/waveform_editor/exporter.py +++ b/waveform_editor/exporter.py @@ -194,7 +194,7 @@ def _fill_waveforms(self, ids, waveforms): # However, certain niche cases involving multiple slices for different waveforms # might still not be handled correctly. for waveform, (path, values) in zip( - waveforms, values_per_waveform, strict=False + waveforms, values_per_waveform, strict=True ): logger.debug(f"Filling {waveform.name}...") self._fill_nodes_recursively(ids, path, values) @@ -230,7 +230,7 @@ def _fill_nodes_recursively(self, node, path, values, path_index=0, fill=True): if node.metadata.type.is_dynamic and part != path.parts[-1]: if len(node) != len(values): node.resize(len(values), keep=True) - for item, value in zip(node, values, strict=False): + for item, value in zip(node, values, strict=True): self._fill_nodes_recursively(item, path, value, next_index) else: self._fill_nodes_recursively(node, path, values, next_index) diff --git a/waveform_editor/gui/io/filebrowser.py b/waveform_editor/gui/io/filebrowser.py index 5b432c52..4ed44a31 100644 --- a/waveform_editor/gui/io/filebrowser.py +++ b/waveform_editor/gui/io/filebrowser.py @@ -147,7 +147,7 @@ def _update_files( paths.insert(0, "..") abbreviated.insert(0, "⬆ ..") - options = dict(zip(abbreviated, paths, strict=False)) + options = dict(zip(abbreviated, paths, strict=True)) self._selector.options = options self._selector.value = [s for s in selected if s in paths] diff --git a/waveform_editor/pcssp_exporter.py b/waveform_editor/pcssp_exporter.py index 5661bc8b..8d90d815 100644 --- a/waveform_editor/pcssp_exporter.py +++ b/waveform_editor/pcssp_exporter.py @@ -79,5 +79,5 @@ def _add_trajectories(self, segment): ET.SubElement(trajectory, "EXIT_RULE", {"is": "Last"}) reference = ET.SubElement(trajectory, "REFERENCE") values = waveform.get_value(self.times)[1] - for t, v in zip(self.times, values, strict=False): + for t, v in zip(self.times, values, strict=True): ET.SubElement(reference, "POINT", {"time": str(t), "value": str(v)}) diff --git a/waveform_editor/waveform.py b/waveform_editor/waveform.py index 4838f362..17011175 100644 --- a/waveform_editor/waveform.py +++ b/waveform_editor/waveform.py @@ -66,7 +66,7 @@ def get_value( return np.array([]), np.array([]) if time is None: - time, values = zip(*(t.get_value() for t in self.tendencies), strict=False) + time, values = zip(*(t.get_value() for t in self.tendencies), strict=True) time = np.concatenate(time) values = np.concatenate(values) else: