Browse Source

ref(metrics-extraction) Improve typing of the build_safe_config (#75341)

Improves typing of the `build_safe_config` function, and removes `# type
ignore` comments.
Vjeran Grozdanić 7 months ago
parent
commit
3860f22d87

+ 8 - 10
src/sentry/relay/config/experimental.py

@@ -1,7 +1,7 @@
 import logging
 from collections.abc import Callable, MutableMapping
 from datetime import datetime, timedelta, timezone
-from typing import Any, Protocol, TypeVar
+from typing import Any, Concatenate, ParamSpec, Protocol, TypeVar
 
 import sentry_sdk
 
@@ -66,20 +66,18 @@ def add_experimental_config(
 
 
 R = TypeVar("R")
-R_default = TypeVar("R_default")
+P = ParamSpec("P")
 
 
 def build_safe_config(
     key: str,
-    function: Callable[..., R],
-    *args: Any,
-    default_return: R_default | None = None,
-    **kwargs: Any,
-) -> R | R_default | None:
+    function: Callable[Concatenate[TimeChecker, P], R],
+    *args: P.args,
+    **kwargs: P.kwargs,
+) -> R | None:
     """
     Runs a config builder function with a timeout.
-    If the function call raises an exception, we log it to sentry and return value passed as
-    `default_return` parameter (by default this is `None`).
+    If the function call raises an exception, we log it to sentry and return None
     """
     timeout = TimeChecker(_FEATURE_BUILD_TIMEOUT)
 
@@ -95,4 +93,4 @@ def build_safe_config(
         except Exception:
             logger.exception("Exception while building Relay project config field")
 
-    return default_return
+    return None

+ 5 - 5
src/sentry/relay/config/metric_extraction.py

@@ -112,14 +112,14 @@ def get_metric_extraction_config(project: Project) -> MetricExtractionConfig | N
 
     with sentry_sdk.start_span(op="get_on_demand_metric_specs"):
         alert_specs, widget_specs = build_safe_config(
-            "on_demand_metric_specs", get_on_demand_metric_specs, project, default_return=([], [])
-        )  # type: ignore[misc]
+            "on_demand_metric_specs", get_on_demand_metric_specs, project
+        ) or ([], [])
     with sentry_sdk.start_span(op="generate_span_attribute_specs"):
-        span_attr_specs = build_safe_config(
-            "span_attribute_specs", _generate_span_attribute_specs, project, default_return=[]
+        span_attr_specs = (
+            build_safe_config("span_attribute_specs", _generate_span_attribute_specs, project) or []
         )
     with sentry_sdk.start_span(op="merge_metric_specs"):
-        metric_specs = _merge_metric_specs(alert_specs, widget_specs, span_attr_specs)  # type: ignore[arg-type]
+        metric_specs = _merge_metric_specs(alert_specs, widget_specs, span_attr_specs)
     with sentry_sdk.start_span(op="get_extrapolation_config"):
         extrapolation_config = get_extrapolation_config(project)
 

+ 6 - 6
tests/sentry/relay/config/test_experimental.py

@@ -82,20 +82,20 @@ def test_build_safe_config_returns_results_from_function_in_args():
 
 @patch("sentry.relay.config.experimental._FEATURE_BUILD_TIMEOUT", timedelta(seconds=1))
 @patch("sentry.relay.config.experimental.logger.exception")
-def test_build_safe_config_returns_default_value_on_timeout_exception(mock_logger):
+def test_build_safe_config_returns_none_on_timeout_exception(mock_logger):
     def dummy(timeout: TimeChecker, *args, **kwargs):
         sleep(1)
         timeout.check()
 
-    result = build_safe_config("key", dummy, default_return="bar")
+    result = build_safe_config("key", dummy)
 
-    assert result == "bar"
+    assert result is None
 
 
-def test_build_safe_config_returns_value_passed_as_arg_on_exception():
+def test_build_safe_config_returns_none_on_non_timeout_exception():
     def dummy(*args, **kwargs):
         raise ValueError("foo")
 
-    result = build_safe_config("key", dummy, default_return="bar")
+    result = build_safe_config("key", dummy)
 
-    assert result == "bar"
+    assert result is None