From b1200b3657f21a69bfa4737851e316e25524635f Mon Sep 17 00:00:00 2001 From: Laurent Vaylet Date: Wed, 11 Dec 2024 14:55:36 +0100 Subject: [PATCH] ci: fix deprecated type hints reported by `ruff check` (#535) * ci: fix deprecated type hints reported by `ruff check` * ci: update python matrix to remove end-of-life versions and add currently supported one * ci: remove Python 3.13 from version matrix --- .github/workflows/ci.yml | 4 ++-- .../backends/cloud_monitoring_mql.py | 22 +++++++++---------- .../backends/cloud_service_monitoring.py | 3 ++- slo_generator/backends/prometheus.py | 8 +++---- slo_generator/constants.py | 9 ++++---- slo_generator/report.py | 3 +-- 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0fc43e6..26111d45 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: matrix: os: [ubuntu-latest] architecture: ['x64'] - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -31,7 +31,7 @@ jobs: matrix: os: [ubuntu-latest] architecture: ['x64'] - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 diff --git a/slo_generator/backends/cloud_monitoring_mql.py b/slo_generator/backends/cloud_monitoring_mql.py index 40351416..4e244b32 100644 --- a/slo_generator/backends/cloud_monitoring_mql.py +++ b/slo_generator/backends/cloud_monitoring_mql.py @@ -22,7 +22,7 @@ import warnings from collections import OrderedDict from datetime import datetime, timezone -from typing import List, Optional, Tuple +from typing import Optional from google.api.distribution_pb2 import Distribution from google.cloud.monitoring_v3 import QueryTimeSeriesRequest @@ -60,7 +60,7 @@ def good_bad_ratio( timestamp: int, window: int, slo_config: dict, - ) -> Tuple[int, int]: + ) -> tuple[int, int]: """Query two timeseries, one containing 'good' events, one containing 'bad' events. @@ -78,16 +78,16 @@ def good_bad_ratio( filter_valid: Optional[str] = measurement.get("filter_valid") # Query 'good events' timeseries - good_ts: List[TimeSeries] = self.query(timestamp, window, filter_good) + good_ts: list[TimeSeries] = self.query(timestamp, window, filter_good) good_event_count: int = CM.count(good_ts) # Query 'bad events' timeseries bad_event_count: int if filter_bad: - bad_ts: List[TimeSeries] = self.query(timestamp, window, filter_bad) + bad_ts: list[TimeSeries] = self.query(timestamp, window, filter_bad) bad_event_count = CM.count(bad_ts) elif filter_valid: - valid_ts: List[TimeSeries] = self.query(timestamp, window, filter_valid) + valid_ts: list[TimeSeries] = self.query(timestamp, window, filter_valid) bad_event_count = CM.count(valid_ts) - good_event_count else: raise ValueError("One of `filter_bad` or `filter_valid` is required.") @@ -103,7 +103,7 @@ def distribution_cut( timestamp: int, window: int, slo_config: dict, - ) -> Tuple[int, int]: + ) -> tuple[int, int]: """Query one timeseries of type 'exponential'. Args: @@ -162,7 +162,7 @@ def distribution_cut( return good_event_count, bad_event_count - def exponential_distribution_cut(self, *args, **kwargs) -> Tuple[int, int]: + def exponential_distribution_cut(self, *args, **kwargs) -> tuple[int, int]: """Alias for `distribution_cut` method to allow for backwards compatibility. """ @@ -192,12 +192,12 @@ def query_sli( """ measurement: dict = slo_config["spec"]["service_level_indicator"] query: str = measurement["query"] - series: List[TimeSeries] = self.query(timestamp, window, query) + series: list[TimeSeries] = self.query(timestamp, window, query) sli_value: float = series[0].point_data[0].values[0].double_value LOGGER.debug(f"SLI value: {sli_value}") return sli_value - def query(self, timestamp: float, window: int, query: str) -> List[TimeSeries]: + def query(self, timestamp: float, window: int, query: str) -> list[TimeSeries]: """Query timeseries from Cloud Monitoring using MQL. Args: @@ -219,7 +219,7 @@ def query(self, timestamp: float, window: int, query: str) -> List[TimeSeries]: self.client.query_time_series(request) # type: ignore[union-attr] ) # fmt: on - timeseries: List[TimeSeries] = list(timeseries_pager) + timeseries: list[TimeSeries] = list(timeseries_pager) LOGGER.debug(pprint.pformat(timeseries)) return timeseries @@ -251,7 +251,7 @@ def enrich_query_with_time_horizon_and_period( return query_with_time_horizon_and_period @staticmethod - def count(timeseries: List[TimeSeries]) -> int: + def count(timeseries: list[TimeSeries]) -> int: """Count events in time series assuming it was aligned with ALIGN_SUM and reduced with REDUCE_SUM (default). diff --git a/slo_generator/backends/cloud_service_monitoring.py b/slo_generator/backends/cloud_service_monitoring.py index 3a332f41..1fe3e3fb 100644 --- a/slo_generator/backends/cloud_service_monitoring.py +++ b/slo_generator/backends/cloud_service_monitoring.py @@ -21,7 +21,8 @@ import logging import os import warnings -from typing import Optional, Sequence, Union +from collections.abc import Sequence +from typing import Optional, Union import google.api_core.exceptions from google.cloud.monitoring_v3 import ServiceMonitoringServiceClient diff --git a/slo_generator/backends/prometheus.py b/slo_generator/backends/prometheus.py index d08df896..9b3bfda9 100644 --- a/slo_generator/backends/prometheus.py +++ b/slo_generator/backends/prometheus.py @@ -20,7 +20,7 @@ import logging import os import pprint -from typing import Dict, List, Optional, Tuple, Union +from typing import Optional, Union from prometheus_http_client import Prometheus @@ -99,7 +99,7 @@ def good_bad_ratio(self, timestamp, window, slo_config): def distribution_cut( self, timestamp: int, window: int, slo_config: dict - ) -> Tuple[float, float]: + ) -> tuple[float, float]: """Query events for distributions (histograms). Args: @@ -189,8 +189,8 @@ def count(response: dict) -> float: def _fmt_query( query: str, window: int, - operators: Union[List[str], None] = None, - labels: Union[Dict[str, str], None] = None, + operators: Union[list[str], None] = None, + labels: Union[dict[str, str], None] = None, ) -> str: """Format Prometheus query: diff --git a/slo_generator/constants.py b/slo_generator/constants.py index cd47f62a..9f4d759f 100644 --- a/slo_generator/constants.py +++ b/slo_generator/constants.py @@ -17,7 +17,6 @@ """ import os -from typing import Dict, List, Tuple # Compute NO_DATA: int = -1 @@ -30,7 +29,7 @@ DEBUG: int = int(os.environ.get("DEBUG", "0")) # Exporters supporting v2 SLO report format -V2_EXPORTERS: Tuple[str, ...] = ("Pubsub", "Cloudevent") +V2_EXPORTERS: tuple[str, ...] = ("Pubsub", "Cloudevent") # Config skeletons CONFIG_SCHEMA: dict = { @@ -53,7 +52,7 @@ # Providers that have changed with v2 YAML config format. This mapping helps # migrate them to their updated names. -PROVIDERS_COMPAT: Dict[str, str] = { +PROVIDERS_COMPAT: dict[str, str] = { "Stackdriver": "CloudMonitoring", "StackdriverServiceMonitoring": "CloudServiceMonitoring", } @@ -61,7 +60,7 @@ # Fields that have changed name with v2 YAML config format. This mapping helps # migrate them back to their former name, so that exporters are backward- # compatible with v1. -METRIC_LABELS_COMPAT: Dict[str, str] = { +METRIC_LABELS_COMPAT: dict[str, str] = { "goal": "slo_target", "description": "slo_description", "error_budget_burn_rate_threshold": "alerting_burn_rate_threshold", @@ -70,7 +69,7 @@ # Fields that used to be specified in top-level of YAML config are now specified # in metadata fields. This mapping helps migrate them back to the top level when # exporting reports, so that exporters are backward-compatible with v1. -METRIC_METADATA_LABELS_TOP_COMPAT: List[str] = [ +METRIC_METADATA_LABELS_TOP_COMPAT: list[str] = [ "service_name", "feature_name", "slo_name", diff --git a/slo_generator/report.py b/slo_generator/report.py index 0a754393..45dea439 100644 --- a/slo_generator/report.py +++ b/slo_generator/report.py @@ -18,7 +18,6 @@ import logging from dataclasses import asdict, dataclass, field, fields -from typing import List from slo_generator import utils from slo_generator.constants import COLORED_OUTPUT, MIN_VALID_EVENTS, NO_DATA, Colors @@ -85,7 +84,7 @@ class SLOReport: metadata: dict = field(default_factory=dict) # Data validation - errors: List[str] = field(default_factory=list) + errors: list[str] = field(default_factory=list) def __init__(self, config, backend, step, timestamp, client=None, delete=False): # noqa: PLR0913 # Init dataclass fields from SLO config and Error Budget Policy