diff --git a/src/NanoVNASaver/Analysis/BandPassAnalysis.py b/src/NanoVNASaver/Analysis/BandPassAnalysis.py index dfb362e..2d304fa 100644 --- a/src/NanoVNASaver/Analysis/BandPassAnalysis.py +++ b/src/NanoVNASaver/Analysis/BandPassAnalysis.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import logging import math -from typing import Dict, List from PyQt6 import QtWidgets @@ -158,13 +157,13 @@ class BandPassAnalysis(Analysis): self.set_result(f"Analysis complete ({len(s21)} points)") def derive_60dB( - self, cutoff_pos: Dict[str, int], cutoff_freq: Dict[str, float] + self, cutoff_pos: dict[str, int], cutoff_freq: dict[str, float] ): """derive 60dB cutoff if needed an possible Args: - cutoff_pos (Dict[str, int]) - cutoff_freq (Dict[str, float]) + cutoff_pos (dict[str, int]) + cutoff_freq (dict[str, float]) """ if ( math.isnan(cutoff_freq["60.0dB_l"]) @@ -191,7 +190,7 @@ class BandPassAnalysis(Analysis): ) ) - def find_center(self, gains: List[float]) -> int: + def find_center(self, gains: list[float]) -> int: marker = self.app.markers[0] if marker.location <= 0 or marker.location >= len(gains) - 1: logger.debug( @@ -207,8 +206,8 @@ class BandPassAnalysis(Analysis): return peak def find_bounderies( - self, gains: List[float], peak: int, peak_db: float - ) -> Dict[str, int]: + self, gains: list[float], peak: int, peak_db: float + ) -> dict[str, int]: cutoff_pos = {} for attn in CUTOFF_VALS: cutoff_pos[f"{attn:.1f}dB_l"] = at.cut_off_left( diff --git a/src/NanoVNASaver/Analysis/BandStopAnalysis.py b/src/NanoVNASaver/Analysis/BandStopAnalysis.py index da4395f..41ca94b 100644 --- a/src/NanoVNASaver/Analysis/BandStopAnalysis.py +++ b/src/NanoVNASaver/Analysis/BandStopAnalysis.py @@ -17,7 +17,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging -from typing import Dict, List import NanoVNASaver.AnalyticTools as at from NanoVNASaver.Analysis.Base import CUTOFF_VALS @@ -31,12 +30,12 @@ class BandStopAnalysis(BandPassAnalysis): super().__init__(app) self.set_titel("Band stop filter analysis") - def find_center(self, gains: List[float]) -> int: + def find_center(self, gains: list[float]) -> int: return max(enumerate(gains), key=lambda i: i[1])[0] def find_bounderies( - self, gains: List[float], _: int, peak_db: float - ) -> Dict[str, int]: + self, gains: list[float], _: int, peak_db: float + ) -> dict[str, int]: cutoff_pos = {} for attn in CUTOFF_VALS: ( diff --git a/src/NanoVNASaver/Analysis/Base.py b/src/NanoVNASaver/Analysis/Base.py index db7e77b..8da74cf 100644 --- a/src/NanoVNASaver/Analysis/Base.py +++ b/src/NanoVNASaver/Analysis/Base.py @@ -17,7 +17,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging -from typing import Dict from PyQt6 import QtWidgets logger = logging.getLogger(__name__) @@ -34,7 +33,7 @@ class QHLine(QtWidgets.QFrame): class Analysis: def __init__(self, app: QtWidgets.QWidget): self.app = app - self.label: Dict[str, QtWidgets.QLabel] = { + self.label: dict[str, QtWidgets.QLabel] = { "titel": QtWidgets.QLabel(), "result": QtWidgets.QLabel(), } diff --git a/src/NanoVNASaver/Analysis/HighPassAnalysis.py b/src/NanoVNASaver/Analysis/HighPassAnalysis.py index 4ae3c8a..fbe9711 100644 --- a/src/NanoVNASaver/Analysis/HighPassAnalysis.py +++ b/src/NanoVNASaver/Analysis/HighPassAnalysis.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import logging import math -from typing import Dict, List from PyQt6 import QtWidgets @@ -109,7 +108,7 @@ class HighPassAnalysis(Analysis): self.set_result(f"Analysis complete ({len(s21)}) points)") - def find_level(self, gains: List[float]) -> int: + def find_level(self, gains: list[float]) -> int: marker = self.app.markers[0] logger.debug("Pass band location: %d", marker.location) if marker.location < 0: @@ -118,8 +117,8 @@ class HighPassAnalysis(Analysis): return at.center_from_idx(gains, marker.location) def find_cutoffs( - self, gains: List[float], peak: int, peak_db: float - ) -> Dict[str, int]: + self, gains: list[float], peak: int, peak_db: float + ) -> dict[str, int]: return { f"{attn:.1f}dB": at.cut_off_left(gains, peak, peak_db, attn) for attn in CUTOFF_VALS diff --git a/src/NanoVNASaver/Analysis/LowPassAnalysis.py b/src/NanoVNASaver/Analysis/LowPassAnalysis.py index 764e791..a96e61c 100644 --- a/src/NanoVNASaver/Analysis/LowPassAnalysis.py +++ b/src/NanoVNASaver/Analysis/LowPassAnalysis.py @@ -17,7 +17,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging -from typing import Dict, List import NanoVNASaver.AnalyticTools as at from NanoVNASaver.Analysis.Base import CUTOFF_VALS @@ -33,8 +32,8 @@ class LowPassAnalysis(HighPassAnalysis): self.set_titel("Lowpass filter analysis") def find_cutoffs( - self, gains: List[float], peak: int, peak_db: float - ) -> Dict[str, int]: + self, gains: list[float], peak: int, peak_db: float + ) -> dict[str, int]: return { f"{attn:.1f}dB": at.cut_off_right(gains, peak, peak_db, attn) for attn in CUTOFF_VALS diff --git a/src/NanoVNASaver/Analysis/ResonanceAnalysis.py b/src/NanoVNASaver/Analysis/ResonanceAnalysis.py index 4a6068d..c65f28f 100644 --- a/src/NanoVNASaver/Analysis/ResonanceAnalysis.py +++ b/src/NanoVNASaver/Analysis/ResonanceAnalysis.py @@ -19,7 +19,6 @@ import os import csv import logging -from typing import List from PyQt6 import QtWidgets @@ -44,7 +43,7 @@ def vswr_transformed(z, ratio=49) -> float: class ResonanceAnalysis(Analysis): def __init__(self, app): super().__init__(app) - self.crossings: List[int] = [] + self.crossings: list[int] = [] self.filename = "" self._widget = QtWidgets.QWidget() self.layout = QtWidgets.QFormLayout() diff --git a/src/NanoVNASaver/Analysis/SimplePeakSearchAnalysis.py b/src/NanoVNASaver/Analysis/SimplePeakSearchAnalysis.py index 52bf25c..80e152b 100644 --- a/src/NanoVNASaver/Analysis/SimplePeakSearchAnalysis.py +++ b/src/NanoVNASaver/Analysis/SimplePeakSearchAnalysis.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging -from typing import Callable, List, Tuple +from typing import Callable from PyQt6 import QtWidgets import numpy as np @@ -102,7 +102,7 @@ class SimplePeakSearchAnalysis(Analysis): if self.button["move_marker"].isChecked() and self.app.markers: self.app.markers[0].setFrequency(f"{s11[idx_peak].freq}") - def data_and_format(self) -> Tuple[List[float], Callable]: + def data_and_format(self) -> tuple[list[float], Callable]: s11 = self.app.data.s11 s21 = self.app.data.s21 diff --git a/src/NanoVNASaver/Analysis/VSWRAnalysis.py b/src/NanoVNASaver/Analysis/VSWRAnalysis.py index 23769e4..2f6853f 100644 --- a/src/NanoVNASaver/Analysis/VSWRAnalysis.py +++ b/src/NanoVNASaver/Analysis/VSWRAnalysis.py @@ -17,7 +17,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging -from typing import List from PyQt6 import QtWidgets @@ -54,7 +53,7 @@ class VSWRAnalysis(Analysis): self.results_label = QtWidgets.QLabel("Results") self.layout.addRow(self.results_label) - self.minimums: List[int] = [] + self.minimums: list[int] = [] def runAnalysis(self): if not self.app.data.s11: diff --git a/src/NanoVNASaver/AnalyticTools.py b/src/NanoVNASaver/AnalyticTools.py index c68b8b3..90ede24 100644 --- a/src/NanoVNASaver/AnalyticTools.py +++ b/src/NanoVNASaver/AnalyticTools.py @@ -18,7 +18,7 @@ # along with this program. If not, see . import itertools as it import math -from typing import Callable, List, Tuple +from typing import Callable import numpy as np @@ -28,14 +28,14 @@ from scipy.signal import find_peaks from NanoVNASaver.RFTools import Datapoint -def zero_crossings(data: List[float]) -> List[int]: +def zero_crossings(data: list[float]) -> list[int]: """find zero crossings Args: - data (List[float]): data list execute + data (list[float]): data list execute Returns: - List[int]: sorted indices of zero crossing points + list[int]: sorted indices of zero crossing points """ if not data: return [] @@ -54,27 +54,27 @@ def zero_crossings(data: List[float]) -> List[int]: return sorted(real_zeros + crossings) -def maxima(data: List[float], threshold: float = 0.0) -> List[int]: +def maxima(data: list[float], threshold: float = 0.0) -> list[int]: """maxima Args: - data (List[float]): data list to execute + data (list[float]): data list to execute Returns: - List[int]: indices of maxima + list[int]: indices of maxima """ peaks = find_peaks(data, width=2, distance=3, prominence=1)[0].tolist() return [i for i in peaks if data[i] > threshold] if threshold else peaks -def minima(data: List[float], threshold: float = 0.0) -> List[int]: +def minima(data: list[float], threshold: float = 0.0) -> list[int]: """minima Args: - data (List[float]): data list to execute + data (list[float]): data list to execute Returns: - List[int]: indices of minima + list[int]: indices of minima """ bottoms = find_peaks(-np.array(data), width=2, distance=3, prominence=1)[ 0 @@ -83,18 +83,18 @@ def minima(data: List[float], threshold: float = 0.0) -> List[int]: def take_from_idx( - data: List[float], idx: int, predicate: Callable -) -> List[int]: + data: list[float], idx: int, predicate: Callable +) -> list[int]: """take_from_center Args: - data (List[float]): data list to execute + data (list[float]): data list to execute idx (int): index of a start position predicate (Callable): predicate on which elements to take from center. (e.g. lambda i: i[1] < threshold) Returns: - List[int]: indices of element matching predicate left + list[int]: indices of element matching predicate left and right from index """ lower = list( @@ -111,11 +111,11 @@ def take_from_idx( return lower + upper -def center_from_idx(gains: List[float], idx: int, delta: float = 3.0) -> int: +def center_from_idx(gains: list[float], idx: int, delta: float = 3.0) -> int: """find maximum from index postion of gains in a attn dB gain span Args: - gains (List[float]): gain values + gains (list[float]): gain values idx (int): start position to search from delta (float, optional): max gain delta from start. Defaults to 3.0. @@ -128,13 +128,13 @@ def center_from_idx(gains: List[float], idx: int, delta: float = 3.0) -> int: def cut_off_left( - gains: List[float], idx: int, peak_gain: float, attn: float = 3.0 + gains: list[float], idx: int, peak_gain: float, attn: float = 3.0 ) -> int: """find first position in list where gain in attn lower then peak left from index Args: - gains (List[float]): gain values + gains (list[float]): gain values idx (int): start position to search from peak_gain (float): reference gain value attn (float, optional): attenuation to search position for. @@ -149,13 +149,13 @@ def cut_off_left( def cut_off_right( - gains: List[float], idx: int, peak_gain: float, attn: float = 3.0 + gains: list[float], idx: int, peak_gain: float, attn: float = 3.0 ) -> int: """find first position in list where gain in attn lower then peak right from index Args: - gains (List[float]): gain values + gains (list[float]): gain values idx (int): start position to search from peak_gain (float): reference gain value attn (float, optional): attenuation to search position for. @@ -171,15 +171,15 @@ def cut_off_right( def dip_cut_offs( - gains: List[float], peak_gain: float, attn: float = 3.0 -) -> Tuple[int, int]: + gains: list[float], peak_gain: float, attn: float = 3.0 +) -> tuple[int, int]: rng = np.where(np.array(gains) < (peak_gain - attn))[0].tolist() return (rng[0], rng[-1]) if rng else (math.nan, math.nan) def calculate_rolloff( - s21: List[Datapoint], idx_1: int, idx_2: int -) -> Tuple[float, float]: + s21: list[Datapoint], idx_1: int, idx_2: int +) -> tuple[float, float]: if idx_1 == idx_2: return (math.nan, math.nan) freq_1, freq_2 = s21[idx_1].freq, s21[idx_2].freq diff --git a/src/NanoVNASaver/Calibration.py b/src/NanoVNASaver/Calibration.py index 2ab6979..377de55 100644 --- a/src/NanoVNASaver/Calibration.py +++ b/src/NanoVNASaver/Calibration.py @@ -23,7 +23,6 @@ import os import re from collections import defaultdict, UserDict from dataclasses import dataclass -from typing import List from scipy.interpolate import interp1d @@ -235,7 +234,7 @@ class CalDataSet(UserDict): setattr(self.data[freq], name, (dp.z)) self.data[freq].freq = freq - def frequencies(self) -> List[int]: + def frequencies(self) -> list[int]: return sorted(self.data.keys()) def get(self, key: int, default: CalData = None) -> CalData: @@ -276,7 +275,7 @@ class Calibration: self.source = "Manual" - def insert(self, name: str, data: List[Datapoint]): + def insert(self, name: str, data: list[Datapoint]): for dp in data: self.dataset.insert(name, dp) diff --git a/src/NanoVNASaver/Charts/CLogMag.py b/src/NanoVNASaver/Charts/CLogMag.py index 7db9a71..cde140e 100644 --- a/src/NanoVNASaver/Charts/CLogMag.py +++ b/src/NanoVNASaver/Charts/CLogMag.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import math import logging -from typing import List from PyQt6 import QtGui @@ -33,11 +32,11 @@ class CombinedLogMagChart(LogMagChart): def __init__(self, name=""): super().__init__(name) - self.data11: List[Datapoint] = [] - self.data21: List[Datapoint] = [] + self.data11: list[Datapoint] = [] + self.data21: list[Datapoint] = [] - self.reference11: List[Datapoint] = [] - self.reference21: List[Datapoint] = [] + self.reference11: list[Datapoint] = [] + self.reference21: list[Datapoint] = [] def setCombinedData(self, data11, data21): self.data11 = data11 diff --git a/src/NanoVNASaver/Charts/Chart.py b/src/NanoVNASaver/Charts/Chart.py index 6ab7a17..5ec26de 100644 --- a/src/NanoVNASaver/Charts/Chart.py +++ b/src/NanoVNASaver/Charts/Chart.py @@ -19,7 +19,7 @@ import logging from dataclasses import dataclass, field, replace -from typing import List, Set, Tuple, ClassVar, Any, Optional +from typing import ClassVar, Any from PyQt6 import QtWidgets, QtGui, QtCore from PyQt6.QtCore import pyqtSignal, Qt @@ -67,8 +67,8 @@ class ChartDimensions: @dataclass class ChartDragBox: - pos: Tuple[int] = (-1, -1) - pos_start: Tuple[int] = (0, 0) + pos: tuple[int] = (-1, -1) + pos_start: tuple[int] = (0, 0) state: bool = False move_x: int = -1 move_y: int = -1 @@ -128,11 +128,11 @@ class Chart(QtWidgets.QWidget): self.draggedMarker = None - self.data: List[Datapoint] = [] - self.reference: List[Datapoint] = [] + self.data: list[Datapoint] = [] + self.reference: list[Datapoint] = [] - self.markers: List[Marker] = [] - self.swrMarkers: Set[float] = set() + self.markers: list[Marker] = [] + self.swrMarkers: set[float] = set() self.action_popout = QAction("Popout chart") self.action_popout.triggered.connect( @@ -192,7 +192,7 @@ class Chart(QtWidgets.QWidget): None, ) - def getNearestMarker(self, x, y) -> Optional[Marker]: + def getNearestMarker(self, x, y) -> Marker | None: if not self.data: return None shortest = 10**6 @@ -205,7 +205,7 @@ class Chart(QtWidgets.QWidget): nearest = m return nearest - def getPosition(self, d: Datapoint) -> Tuple[int, int]: + def getPosition(self, d: Datapoint) -> tuple[int, int]: return self.getXPosition(d), self.getYPosition(d) def setDrawLines(self, draw_lines): diff --git a/src/NanoVNASaver/Charts/Frequency.py b/src/NanoVNASaver/Charts/Frequency.py index a5e467d..1599b3d 100644 --- a/src/NanoVNASaver/Charts/Frequency.py +++ b/src/NanoVNASaver/Charts/Frequency.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import math import logging -from typing import List, Tuple import numpy as np from PyQt6 import QtWidgets, QtGui, QtCore @@ -405,7 +404,7 @@ class FrequencyChart(Chart): step = span / self.dim.width return round(self.fstart + absx * step) - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: """ Returns the chart-specific value(s) at the specified Y-position :param y: The Y position to calculate for. @@ -493,7 +492,7 @@ class FrequencyChart(Chart): self.drawDragbog(qp) qp.end() - def _data_oob(self, data: List[Datapoint]) -> bool: + def _data_oob(self, data: list[Datapoint]) -> bool: return data[0].freq > self.fstop or self.data[-1].freq < self.fstart def _check_frequency_boundaries(self, qp: QtGui.QPainter): @@ -605,7 +604,7 @@ class FrequencyChart(Chart): self.drawData(qp, self.reference, Chart.color.reference) self.drawMarkers(qp) - def _find_scaling(self) -> Tuple[float, float]: + def _find_scaling(self) -> tuple[float, float]: min_value = self.minDisplayValue / 10e11 max_value = self.maxDisplayValue / 10e11 if self.fixedValues: @@ -686,7 +685,7 @@ class FrequencyChart(Chart): def drawData( self, qp: QtGui.QPainter, - data: List[Datapoint], + data: list[Datapoint], color: QtGui.QColor, y_function=None, ): diff --git a/src/NanoVNASaver/Charts/GroupDelay.py b/src/NanoVNASaver/Charts/GroupDelay.py index dc30390..ed76908 100644 --- a/src/NanoVNASaver/Charts/GroupDelay.py +++ b/src/NanoVNASaver/Charts/GroupDelay.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import math import logging -from typing import List import numpy as np @@ -74,7 +73,7 @@ class GroupDelayChart(FrequencyChart): self.groupDelayReference = self.calc_data(self.reference) self.update() - def calc_data(self, data: List[Datapoint]): + def calc_data(self, data: list[Datapoint]): data_len = len(data) if data_len <= 1: return [] @@ -172,8 +171,8 @@ class GroupDelayChart(FrequencyChart): self, qp: QtGui.QPainter, color: QtGui.QColor, - data: List[Datapoint], - delay: List[Datapoint], + data: list[Datapoint], + delay: list[Datapoint], ): pen = QtGui.QPen(color) pen.setWidth(self.dim.point) @@ -216,7 +215,7 @@ class GroupDelayChart(FrequencyChart): (self.maxDelay - delay) / self.span * self.dim.height ) - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: absy = y - self.topMargin val = -1 * ((absy / self.dim.height * self.span) - self.maxDelay) return [val] diff --git a/src/NanoVNASaver/Charts/LogMag.py b/src/NanoVNASaver/Charts/LogMag.py index c6736ba..d929c5b 100644 --- a/src/NanoVNASaver/Charts/LogMag.py +++ b/src/NanoVNASaver/Charts/LogMag.py @@ -19,7 +19,6 @@ from dataclasses import dataclass import math import logging -from typing import List from PyQt6 import QtGui @@ -165,7 +164,7 @@ class LogMagChart(FrequencyChart): (self.maxValue - logMag) / self.span * self.dim.height ) - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: absy = y - self.topMargin val = -1 * ((absy / self.dim.height * self.span) - self.maxValue) return [val] diff --git a/src/NanoVNASaver/Charts/Magnitude.py b/src/NanoVNASaver/Charts/Magnitude.py index 0f7a912..dcff5f8 100644 --- a/src/NanoVNASaver/Charts/Magnitude.py +++ b/src/NanoVNASaver/Charts/Magnitude.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import math import logging -from typing import List from PyQt6 import QtGui @@ -127,7 +126,7 @@ class MagnitudeChart(FrequencyChart): (self.maxValue - mag) / self.span * self.dim.height ) - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: absy = y - self.topMargin val = -1 * ((absy / self.dim.height * self.span) - self.maxValue) return [val] diff --git a/src/NanoVNASaver/Charts/MagnitudeZ.py b/src/NanoVNASaver/Charts/MagnitudeZ.py index 32cd2d6..b051a3d 100644 --- a/src/NanoVNASaver/Charts/MagnitudeZ.py +++ b/src/NanoVNASaver/Charts/MagnitudeZ.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import math import logging -from typing import List from PyQt6 import QtGui @@ -129,7 +128,7 @@ class MagnitudeZChart(FrequencyChart): ) return self.topMargin - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: absy = y - self.topMargin if self.logarithmicY: span = math.log(self.maxValue) - math.log(self.minValue) diff --git a/src/NanoVNASaver/Charts/Permeability.py b/src/NanoVNASaver/Charts/Permeability.py index aadda3e..8544d0e 100644 --- a/src/NanoVNASaver/Charts/Permeability.py +++ b/src/NanoVNASaver/Charts/Permeability.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import math import logging -from typing import List from PyQt6 import QtGui @@ -325,7 +324,7 @@ class PermeabilityChart(FrequencyChart): self.topMargin + (self.max - re) / self.span * self.dim.height ) - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: absy = y - self.topMargin if self.logarithmicY: min_val = self.max - self.span diff --git a/src/NanoVNASaver/Charts/Phase.py b/src/NanoVNASaver/Charts/Phase.py index d743670..aad256b 100644 --- a/src/NanoVNASaver/Charts/Phase.py +++ b/src/NanoVNASaver/Charts/Phase.py @@ -19,7 +19,6 @@ import math import logging -from typing import List import numpy as np from PyQt6.QtGui import QAction, QPainter, QPen @@ -151,7 +150,7 @@ class PhaseChart(FrequencyChart): (self.maxAngle - angle) / self.span * self.dim.height ) - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: absy = y - self.topMargin val = -1 * ((absy / self.dim.height * self.span) - self.maxAngle) return [val] diff --git a/src/NanoVNASaver/Charts/QFactor.py b/src/NanoVNASaver/Charts/QFactor.py index 3986a96..df5aa89 100644 --- a/src/NanoVNASaver/Charts/QFactor.py +++ b/src/NanoVNASaver/Charts/QFactor.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import math import logging -from typing import List from PyQt6 import QtGui @@ -127,7 +126,7 @@ class QualityFactorChart(FrequencyChart): (self.maxQ - Q) / self.span * self.dim.height ) - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: absy = y - self.topMargin val = -1 * ((absy / self.dim.height * self.span) - self.maxQ) return [val] diff --git a/src/NanoVNASaver/Charts/RI.py b/src/NanoVNASaver/Charts/RI.py index a64fda0..2690e22 100644 --- a/src/NanoVNASaver/Charts/RI.py +++ b/src/NanoVNASaver/Charts/RI.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import math import logging -from typing import List, Optional from PyQt6 import QtWidgets, QtGui @@ -381,7 +380,7 @@ class RealImaginaryChart(FrequencyChart): else self.topMargin ) - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: absy = y - self.topMargin valRe = -1 * ((absy / self.dim.height * self.span_real) - self.max_real) valIm = -1 * ((absy / self.dim.height * self.span_imag) - self.max_imag) @@ -408,7 +407,7 @@ class RealImaginaryChart(FrequencyChart): self.update() - def getNearestMarker(self, x, y) -> Optional[Marker]: + def getNearestMarker(self, x, y) -> Marker | None: if not self.data: return None shortest = 10e6 diff --git a/src/NanoVNASaver/Charts/RIZ.py b/src/NanoVNASaver/Charts/RIZ.py index 5e97489..f1a810e 100644 --- a/src/NanoVNASaver/Charts/RIZ.py +++ b/src/NanoVNASaver/Charts/RIZ.py @@ -18,7 +18,7 @@ # along with this program. If not, see . import logging -from PyQt6 import QtWidgets, QtGui +from PyQt6 import QtGui from NanoVNASaver.Formatting import format_frequency_chart from NanoVNASaver.RFTools import Datapoint diff --git a/src/NanoVNASaver/Charts/SParam.py b/src/NanoVNASaver/Charts/SParam.py index 09f6cb9..4d1e8e8 100644 --- a/src/NanoVNASaver/Charts/SParam.py +++ b/src/NanoVNASaver/Charts/SParam.py @@ -17,7 +17,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging -from typing import List from PyQt6 import QtGui @@ -142,7 +141,7 @@ class SParameterChart(FrequencyChart): + (self.maxValue - d.im) / self.span * self.dim.height ) - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: absy = y - self.topMargin val = -1 * ((absy / self.dim.height * self.span) - self.maxValue) return [val] diff --git a/src/NanoVNASaver/Charts/Square.py b/src/NanoVNASaver/Charts/Square.py index dd5ab16..ff66db8 100644 --- a/src/NanoVNASaver/Charts/Square.py +++ b/src/NanoVNASaver/Charts/Square.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import logging import math -from typing import List from PyQt6 import QtGui, QtCore, QtWidgets @@ -58,7 +57,7 @@ class SquareChart(Chart): self, qp: QtGui.QPainter, color: QtGui.QColor, - data: List[Datapoint], + data: list[Datapoint], fstart: int = 0, fstop: int = 0, ): diff --git a/src/NanoVNASaver/Charts/VSWR.py b/src/NanoVNASaver/Charts/VSWR.py index f0efe18..73d8a28 100644 --- a/src/NanoVNASaver/Charts/VSWR.py +++ b/src/NanoVNASaver/Charts/VSWR.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import math import logging -from typing import List from PyQt6 import QtGui @@ -166,7 +165,7 @@ class VSWRChart(FrequencyChart): def getYPosition(self, d: Datapoint) -> int: return self.getYPositionFromValue(d.vswr) - def valueAtPosition(self, y) -> List[float]: + def valueAtPosition(self, y) -> list[float]: absy = y - self.topMargin if self.logarithmicY: min_val = self.maxVSWR - self.span diff --git a/src/NanoVNASaver/Defaults.py b/src/NanoVNASaver/Defaults.py index e7c32ec..0a29481 100644 --- a/src/NanoVNASaver/Defaults.py +++ b/src/NanoVNASaver/Defaults.py @@ -62,7 +62,7 @@ class Chart: marker_size: int = 8 returnloss_is_positive: bool = False show_bands: bool = False - vswr_lines: list = DC.field(default_factory=lambda: []) + vswr_lines: list = DC.field(default_factory=list) @DC.dataclass @@ -126,11 +126,11 @@ class Markers: @DC.dataclass class CFG: - gui: object = DC.field(default_factory=lambda: GUI()) - charts_selected: object = DC.field(default_factory=lambda: ChartsSelected()) - chart: object = DC.field(default_factory=lambda: Chart()) - chart_colors: object = DC.field(default_factory=lambda: ChartColors()) - markers: object = DC.field(default_factory=lambda: Markers()) + gui: object = DC.field(default_factory=GUI) + charts_selected: object = DC.field(default_factory=ChartsSelected) + chart: object = DC.field(default_factory=Chart) + chart_colors: object = DC.field(default_factory=ChartColors) + markers: object = DC.field(default_factory=Markers) cfg = CFG() @@ -159,9 +159,9 @@ def store(settings: "AppSettings", data: CFG = None) -> None: def from_type(data) -> str: type_map = { - bytearray: lambda x: x.hex(), - QColor: lambda x: x.getRgb(), - QByteArray: lambda x: x.toHex(), + bytearray: bytearray.hex, + QColor: QColor.getRgb, + QByteArray: QByteArray.toHex, } return ( f"{type_map[type(data)](data)}" if type(data) in type_map else f"{data}" diff --git a/src/NanoVNASaver/Formatting.py b/src/NanoVNASaver/Formatting.py index 6a1093a..cbdab27 100644 --- a/src/NanoVNASaver/Formatting.py +++ b/src/NanoVNASaver/Formatting.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import math from numbers import Number -from typing import Union from NanoVNASaver import SITools @@ -55,7 +54,7 @@ def format_frequency(freq: Number) -> str: return str(SITools.Value(freq, "Hz", FMT_FREQ)) -def format_frequency_inputs(freq: Union[Number, str]) -> str: +def format_frequency_inputs(freq: Number | str) -> str: return str(SITools.Value(freq, "Hz", FMT_FREQ_INPUTS)) diff --git a/src/NanoVNASaver/Hardware/Hardware.py b/src/NanoVNASaver/Hardware/Hardware.py index faa352a..b63f5f3 100644 --- a/src/NanoVNASaver/Hardware/Hardware.py +++ b/src/NanoVNASaver/Hardware/Hardware.py @@ -20,7 +20,6 @@ import logging import platform from collections import namedtuple from time import sleep -from typing import List import serial from serial.tools import list_ports @@ -91,7 +90,7 @@ def usb_typename(device: ListPortInfo) -> str: # Get list of interfaces with VNAs connected -def get_interfaces() -> List[Interface]: +def get_interfaces() -> list[Interface]: interfaces = [] # serial like usb interfaces for d in list_ports.comports(): @@ -117,7 +116,7 @@ def get_interfaces() -> List[Interface]: return interfaces -def get_portinfos() -> List[str]: +def get_portinfos() -> list[str]: portinfos = [] # serial like usb interfaces for d in list_ports.comports(): diff --git a/src/NanoVNASaver/Hardware/NanoVNA.py b/src/NanoVNASaver/Hardware/NanoVNA.py index d836341..1fd2250 100644 --- a/src/NanoVNASaver/Hardware/NanoVNA.py +++ b/src/NanoVNASaver/Hardware/NanoVNA.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import logging import struct -from typing import List import serial import numpy as np @@ -123,7 +122,7 @@ class NanoVNA(VNA): self.features.add("Scan command") self.sweep_method = "scan" - def readFrequencies(self) -> List[int]: + def readFrequencies(self) -> list[int]: logger.debug("readFrequencies: %s", self.sweep_method) if self.sweep_method != "scan_mask": return super().readFrequencies() @@ -134,7 +133,7 @@ class NanoVNA(VNA): ) ] - def readValues(self, value) -> List[str]: + def readValues(self, value) -> list[str]: if self.sweep_method != "scan_mask": return super().readValues(value) logger.debug("readValue with scan mask (%s)", value) diff --git a/src/NanoVNASaver/Hardware/NanoVNA_V2.py b/src/NanoVNASaver/Hardware/NanoVNA_V2.py index d49364b..d9b8c1b 100644 --- a/src/NanoVNASaver/Hardware/NanoVNA_V2.py +++ b/src/NanoVNASaver/Hardware/NanoVNA_V2.py @@ -20,7 +20,6 @@ import logging import platform from struct import pack, unpack_from from time import sleep -from typing import List from NanoVNASaver.Hardware.Serial import Interface from NanoVNASaver.Hardware.VNA import VNA @@ -131,7 +130,7 @@ class NanoVNA_V2(VNA): logger.debug("readFirmware: %s", result) return result - def readFrequencies(self) -> List[int]: + def readFrequencies(self) -> list[int]: return [ int(self.sweepStartHz + i * self.sweepStepHz) for i in range(self.datapoints) @@ -159,7 +158,7 @@ class NanoVNA_V2(VNA): logger.debug("Freq index to: %i", freq_index) - def readValues(self, value) -> List[str]: + def readValues(self, value) -> list[str]: # Actually grab the data only when requesting channel 0. # The hardware will return all channels which we will store. if value == "data 0": diff --git a/src/NanoVNASaver/Hardware/TinySA.py b/src/NanoVNASaver/Hardware/TinySA.py index cc741d5..09a4ed9 100644 --- a/src/NanoVNASaver/Hardware/TinySA.py +++ b/src/NanoVNASaver/Hardware/TinySA.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import logging import struct -from typing import List import serial import numpy as np @@ -109,11 +108,11 @@ class TinySA(VNA): list(self.exec_command(f"sweep {start} {stop} {self.datapoints}")) list(self.exec_command("trigger auto")) - def readFrequencies(self) -> List[int]: + def readFrequencies(self) -> list[int]: logger.debug("readFrequencies") return [int(line) for line in self.exec_command("frequencies")] - def readValues(self, value) -> List[str]: + def readValues(self, value) -> list[str]: def conv2float(data: str) -> float: try: return 10 ** (float(data.strip()) / 20) diff --git a/src/NanoVNASaver/Hardware/VNA.py b/src/NanoVNASaver/Hardware/VNA.py index a429ebd..361efca 100644 --- a/src/NanoVNASaver/Hardware/VNA.py +++ b/src/NanoVNASaver/Hardware/VNA.py @@ -18,7 +18,7 @@ # along with this program. If not, see . import logging from time import sleep -from typing import List, Iterator, Set +from typing import Iterator from PyQt6 import QtGui @@ -131,7 +131,7 @@ class VNA: if len(self.valid_datapoints) > 1: self.features.add("Customizable data points") - def get_bandwidths(self) -> List[int]: + def get_bandwidths(self) -> list[int]: logger.debug("get bandwidths") if self.bw_method == "dislord": return list(DISLORD_BW.keys()) @@ -153,7 +153,7 @@ class VNA: raise IOError(f"set_bandwith({bandwidth}: {result}") self.bandwidth = bandwidth - def readFrequencies(self) -> List[int]: + def readFrequencies(self) -> list[int]: return [int(f) for f in self.readValues("frequencies")] def resetSweep(self, start: int, stop: int): @@ -170,7 +170,7 @@ class VNA: def connected(self) -> bool: return self.serial.is_open - def getFeatures(self) -> Set[str]: + def getFeatures(self) -> set[str]: return self.features def getCalibration(self) -> str: @@ -194,7 +194,7 @@ class VNA: logger.debug("result:\n%s", result) return result - def readValues(self, value) -> List[str]: + def readValues(self, value) -> list[str]: logger.debug("VNA reading %s", value) result = list(self.exec_command(value)) logger.debug("VNA done reading %s (%d values)", value, len(result)) diff --git a/src/NanoVNASaver/Marker/Values.py b/src/NanoVNASaver/Marker/Values.py index 97b0a81..be9d33a 100644 --- a/src/NanoVNASaver/Marker/Values.py +++ b/src/NanoVNASaver/Marker/Values.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from typing import List, NamedTuple +from typing import NamedTuple from NanoVNASaver.RFTools import Datapoint @@ -71,16 +71,13 @@ class Value: """Contains the data area to calculate marker values from""" def __init__( - self, - freq: int = 0, - s11: List[Datapoint] = None, - s21: List[Datapoint] = None, + self, ): - self.freq = freq - self.s11 = [] if s11 is None else s11[:] - self.s21 = [] if s21 is None else s21[:] + self.freq: int = 0 + self.s11: list[Datapoint] = [] + self.s21: list[Datapoint] = [] - def store(self, index: int, s11: List[Datapoint], s21: List[Datapoint]): + def store(self, index: int, s11: list[Datapoint], s21: list[Datapoint]): # handle boundaries if index == 0: index = 1 diff --git a/src/NanoVNASaver/Marker/Widget.py b/src/NanoVNASaver/Marker/Widget.py index 44a0696..df41495 100644 --- a/src/NanoVNASaver/Marker/Widget.py +++ b/src/NanoVNASaver/Marker/Widget.py @@ -17,7 +17,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import math -from typing import List from PyQt6 import QtGui, QtWidgets, QtCore from PyQt6.QtCore import pyqtSignal @@ -253,7 +252,7 @@ class Marker(QtCore.QObject, Value): def getRow(self): return QtWidgets.QLabel(self.name), self.layout - def findLocation(self, data: List[RFTools.Datapoint]): + def findLocation(self, data: list[RFTools.Datapoint]): self.location = -1 self.frequencyInput.nextFrequency = -1 self.frequencyInput.previousFrequency = -1 @@ -298,7 +297,7 @@ class Marker(QtCore.QObject, Value): v.setText("") def updateLabels( - self, s11: List[RFTools.Datapoint], s21: List[RFTools.Datapoint] + self, s11: list[RFTools.Datapoint], s21: list[RFTools.Datapoint] ): if not s11: return diff --git a/src/NanoVNASaver/RFTools.py b/src/NanoVNASaver/RFTools.py index 7948384..3a25387 100644 --- a/src/NanoVNASaver/RFTools.py +++ b/src/NanoVNASaver/RFTools.py @@ -18,7 +18,7 @@ # along with this program. If not, see . import math import cmath -from typing import List, NamedTuple +from typing import NamedTuple from NanoVNASaver.SITools import Format, clamp_value @@ -92,7 +92,7 @@ def gamma_to_impedance(gamma: complex, ref_impedance: float = 50) -> complex: return math.inf -def groupDelay(data: List[Datapoint], index: int) -> float: +def groupDelay(data: list[Datapoint], index: int) -> float: idx0 = clamp_value(index - 1, 0, len(data) - 1) idx1 = clamp_value(index + 1, 0, len(data) - 1) delta_angle = data[idx1].phase - data[idx0].phase @@ -147,7 +147,7 @@ def serial_to_parallel(z: complex) -> complex: return complex(z_sq_sum / z.real, z_sq_sum / z.imag) -def corr_att_data(data: List[Datapoint], att: float) -> List[Datapoint]: +def corr_att_data(data: list[Datapoint], att: float) -> list[Datapoint]: """Correct the ratio for a given attenuation on s21 input""" if att <= 0: return data diff --git a/src/NanoVNASaver/Settings/Sweep.py b/src/NanoVNASaver/Settings/Sweep.py index 57509a2..d5aef9e 100644 --- a/src/NanoVNASaver/Settings/Sweep.py +++ b/src/NanoVNASaver/Settings/Sweep.py @@ -17,10 +17,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging +from dataclasses import dataclass, replace from enum import Enum from math import log from threading import Lock -from typing import Iterator, Tuple +from typing import Iterator, NamedTuple logger = logging.getLogger(__name__) @@ -31,63 +32,28 @@ class SweepMode(Enum): AVERAGE = 2 -class Properties: - def __init__( - self, - name: str = "", - mode: "SweepMode" = SweepMode.SINGLE, - averages: Tuple[int, int] = (3, 0), - logarithmic: bool = False, - ): - self.name = name - self.mode = mode - self.averages = averages - self.logarithmic = logarithmic - - def __repr__(self): - return ( - f"Properties('{self.name}', {self.mode}, {self.averages}," - f" {self.logarithmic})" - ) +class Properties(NamedTuple): + name: str = "" + mode: "SweepMode" = SweepMode.SINGLE + averages: tuple[int, int] = (3, 0) + logarithmic: bool = False +@dataclass class Sweep: - def __init__( - self, - start: int = 3600000, - end: int = 30000000, - points: int = 101, - segments: int = 1, - properties: "Properties" = Properties(), - ): - self.start = start - self.end = end - self.points = points - self.segments = segments - self.properties = properties + start: int = 3600000 + end: int = 30000000 + points: int = 101 + segments: int = 1 + properties: "Properties" = Properties() + + def __post_init__(self): self.lock = Lock() self.check() logger.debug("%s", self) - def __repr__(self) -> str: - return ( - f"Sweep({self.start}, {self.end}, {self.points}, {self.segments}," - f" {self.properties})" - ) - - def __eq__(self, other) -> bool: - return ( - self.start == other.start - and self.end == other.end - and self.points == other.points - and self.segments == other.segments - and self.properties == other.properties - ) - def copy(self) -> "Sweep": - return Sweep( - self.start, self.end, self.points, self.segments, self.properties - ) + return replace(self) @property def span(self) -> int: @@ -110,7 +76,7 @@ class Sweep: def _exp_factor(self, index: int) -> float: return 1 - log(self.segments + 1 - index) / log(self.segments + 1) - def get_index_range(self, index: int) -> Tuple[int, int]: + def get_index_range(self, index: int) -> tuple[int, int]: if not self.properties.logarithmic: start = self.start + index * self.points * self.stepsize end = start + (self.points - 1) * self.stepsize diff --git a/src/NanoVNASaver/SweepWorker.py b/src/NanoVNASaver/SweepWorker.py index f384682..3cae9bc 100644 --- a/src/NanoVNASaver/SweepWorker.py +++ b/src/NanoVNASaver/SweepWorker.py @@ -18,7 +18,6 @@ # along with this program. If not, see . import logging from time import sleep -from typing import List, Tuple import numpy as np from PyQt6 import QtCore, QtWidgets @@ -31,7 +30,7 @@ from NanoVNASaver.Settings.Sweep import Sweep, SweepMode logger = logging.getLogger(__name__) -def truncate(values: List[List[Tuple]], count: int) -> List[List[Tuple]]: +def truncate(values: list[list[tuple]], count: int) -> list[list[tuple]]: """truncate drops extrema from data list if averaging is active""" keep = len(values) - count logger.debug("Truncating from %d values to %d", len(values), keep) @@ -62,10 +61,10 @@ class SweepWorker(QtCore.QRunnable): self.sweep = Sweep() self.setAutoDelete(False) self.percentage = 0 - self.data11: List[Datapoint] = [] - self.data21: List[Datapoint] = [] - self.rawData11: List[Datapoint] = [] - self.rawData21: List[Datapoint] = [] + self.data11: list[Datapoint] = [] + self.data21: list[Datapoint] = [] + self.rawData11: list[Datapoint] = [] + self.rawData21: list[Datapoint] = [] self.init_data() self.stopped = False self.running = False @@ -187,10 +186,10 @@ class SweepWorker(QtCore.QRunnable): self.signals.updated.emit() def applyCalibration( - self, raw_data11: List[Datapoint], raw_data21: List[Datapoint] - ) -> Tuple[List[Datapoint], List[Datapoint]]: - data11: List[Datapoint] = [] - data21: List[Datapoint] = [] + self, raw_data11: list[Datapoint], raw_data21: list[Datapoint] + ) -> tuple[list[Datapoint], list[Datapoint]]: + data11: list[Datapoint] = [] + data21: list[Datapoint] = [] if not self.app.calibration.isCalculated: data11 = raw_data11.copy() diff --git a/src/NanoVNASaver/Touchstone.py b/src/NanoVNASaver/Touchstone.py index 2a9a7f9..4e09814 100644 --- a/src/NanoVNASaver/Touchstone.py +++ b/src/NanoVNASaver/Touchstone.py @@ -22,8 +22,6 @@ import cmath import io from operator import attrgetter -from typing import List - from scipy.interpolate import interp1d from NanoVNASaver.RFTools import Datapoint @@ -108,42 +106,42 @@ class Touchstone: self._interp = {} @property - def s11(self) -> List[Datapoint]: + def s11(self) -> list[Datapoint]: return self.s("11") @s11.setter - def s11(self, value: List[Datapoint]): + def s11(self, value: list[Datapoint]): self.sdata[0] = value @property - def s12(self) -> List[Datapoint]: + def s12(self) -> list[Datapoint]: return self.s("12") @s12.setter - def s12(self, value: List[Datapoint]): + def s12(self, value: list[Datapoint]): self.sdata[2] = value @property - def s21(self) -> List[Datapoint]: + def s21(self) -> list[Datapoint]: return self.s("21") @s21.setter - def s21(self, value: List[Datapoint]): + def s21(self, value: list[Datapoint]): self.sdata[1] = value @property - def s22(self) -> List[Datapoint]: + def s22(self) -> list[Datapoint]: return self.s("22") @s22.setter - def s22(self, value: List[Datapoint]): + def s22(self, value: list[Datapoint]): self.sdata[3] = value @property def r(self) -> int: return self.opts.resistance - def s(self, name: str) -> List[Datapoint]: + def s(self, name: str) -> list[Datapoint]: return self.sdata[Touchstone.FIELD_ORDER.index(name)] def s_freq(self, name: str, freq: int) -> Datapoint: diff --git a/src/NanoVNASaver/Version.py b/src/NanoVNASaver/Version.py index f6bf3e2..f103d56 100644 --- a/src/NanoVNASaver/Version.py +++ b/src/NanoVNASaver/Version.py @@ -17,12 +17,12 @@ # along with this program. If not, see . import logging import re +import typing logger = logging.getLogger(__name__) -class Version: - RXP = re.compile( +_RXP = re.compile( r"""^ \D* (?P\d+)\. @@ -33,61 +33,26 @@ class Version: re.VERBOSE, ) - def __init__(self, vstring: str = "0.0.0"): - self.data = { - "major": 0, - "minor": 0, - "revision": 0, - "note": "", - } - try: - self.data = Version.RXP.search(vstring).groupdict() - for name in ("major", "minor", "revision"): - self.data[name] = int(self.data[name]) - except TypeError: - self.data["revision"] = 0 - except AttributeError: - logger.error("Unable to parse version: %s", vstring) - def __gt__(self, other: "Version") -> bool: - left, right = self.data, other.data - for name in ("major", "minor", "revision"): - if left[name] > right[name]: - return True - if left[name] < right[name]: - return False - return False - - def __lt__(self, other: "Version") -> bool: - return other.__gt__(self) - - def __ge__(self, other: "Version") -> bool: - return self.__gt__(other) or self.__eq__(other) - - def __le__(self, other: "Version") -> bool: - return other.__gt__(self) or self.__eq__(other) - - def __eq__(self, other: "Version") -> bool: - return self.data == other.data +class _Version(typing.NamedTuple): + major: int + minor: int + revision: int + note: str def __str__(self) -> str: return ( - f'{self.data["major"]}.{self.data["minor"]}' - f'.{self.data["revision"]}{self.data["note"]}' + f'{self.major}.{self.minor}' + f'.{self.revision}{self.note}' ) - @property - def major(self) -> int: - return self.data["major"] - @property - def minor(self) -> int: - return self.data["minor"] +def Version(vstring: str = "0.0.0") -> '_Version': + if (match := _RXP.search(vstring)) is None: + logger.error("Unable to parse version: %s", vstring) + return _Version(0, 0, 0, '') - @property - def revision(self) -> int: - return self.data["revision"] - - @property - def note(self) -> str: - return self.data["note"] + return _Version(int(match.group('major')), + int(match.group('minor')), + int(match.group('revision') or '0'), + match.group('note')) diff --git a/src/NanoVNASaver/Windows/DisplaySettings.py b/src/NanoVNASaver/Windows/DisplaySettings.py index 51f4f52..908d430 100644 --- a/src/NanoVNASaver/Windows/DisplaySettings.py +++ b/src/NanoVNASaver/Windows/DisplaySettings.py @@ -17,7 +17,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging -from typing import List from PyQt6 import QtWidgets, QtCore from PyQt6.QtGui import QColor, QColorConstants, QPalette, QShortcut @@ -210,7 +209,7 @@ class DisplaySettingsWindow(QtWidgets.QWidget): vswr_marker_box = QtWidgets.QGroupBox("VSWR Markers") vswr_marker_layout = QtWidgets.QFormLayout(vswr_marker_box) - self.vswrMarkers: List[float] = self.app.settings.value( + self.vswrMarkers: list[float] = self.app.settings.value( "VSWRMarkers", [], float ) diff --git a/src/NanoVNASaver/__init__.py b/src/NanoVNASaver/__init__.py index 8c289c0..e8935d1 100644 --- a/src/NanoVNASaver/__init__.py +++ b/src/NanoVNASaver/__init__.py @@ -1,13 +1,7 @@ -from importlib.metadata import ( - PackageNotFoundError, - version, -) +import importlib.metadata try: # Change here if project is renamed and does not equal the package name - dist_name = "nanovna-saver" - __version__ = version(dist_name) -except PackageNotFoundError: # pragma: no cover + __version__ = importlib.metadata.version(distribution_name="nanovna-saver") +except importlib.metadata.PackageNotFoundError: # pragma: no cover __version__ = "unknown" -finally: - del version, PackageNotFoundError diff --git a/tests/test_sweep.py b/tests/test_sweep.py index e4733bb..b6a484c 100644 --- a/tests/test_sweep.py +++ b/tests/test_sweep.py @@ -27,8 +27,10 @@ class TestCases(unittest.TestCase): def test_sweep(self): sweep = Sweep() self.assertEqual(str(sweep), - "Sweep(3600000, 30000000, 101, 1, Properties(''," - " SweepMode.SINGLE, (3, 0), False))") + "Sweep(start=3600000, end=30000000, points=101," + " segments=1, properties=Properties(name=''," + " mode=, averages=(3, 0)," + " logarithmic=False))") self.assertTrue(Sweep(3600000) == sweep) self.assertFalse(Sweep(3600001) == sweep) self.assertRaises(ValueError, Sweep, -1)