Просмотр исходного кода

fix(typing) Improve types for env() (#57575)

This wrapper only accepts our homebrew type coercion instances. If one
were to use `bool` the parsed value will be wrong.
Mark Story 1 год назад
Родитель
Сommit
4e11e74161
2 измененных файлов с 45 добавлено и 9 удалено
  1. 10 8
      src/sentry/conf/server.py
  2. 35 1
      src/sentry/utils/types.py

+ 10 - 8
src/sentry/conf/server.py

@@ -11,7 +11,7 @@ import socket
 import sys
 import tempfile
 from datetime import datetime, timedelta
-from typing import Any, Callable, Dict, Final, Mapping, MutableSequence, Optional, TypeVar, overload
+from typing import Any, Callable, Dict, Final, Mapping, MutableSequence, Optional, Union, overload
 from urllib.parse import urlparse
 
 import sentry
@@ -21,9 +21,7 @@ from sentry.conf.types.sdk_config import ServerSdkConfig
 from sentry.conf.types.topic_definition import TopicDefinition
 from sentry.utils import json  # NOQA (used in getsentry config)
 from sentry.utils.celery import crontab_with_minute_jitter
-from sentry.utils.types import type_from_value
-
-T = TypeVar("T")
+from sentry.utils.types import Type, type_from_value
 
 
 def gettext_noop(s: str) -> str:
@@ -33,27 +31,31 @@ def gettext_noop(s: str) -> str:
 socket.setdefaulttimeout(5)
 
 
+_EnvTypes = Union[str, float, int, list, dict]
+
+
 @overload
 def env(key: str) -> str:
     ...
 
 
 @overload
-def env(key: str, default: T, type: Callable[[Any], T] | None = None) -> T:
+def env(key: str, default: _EnvTypes, type: Optional[Type] = None) -> _EnvTypes:
     ...
 
 
 def env(
     key: str,
-    default: str | T = "",
-    type: Optional[Callable[[Any], T]] = None,
-) -> T:
+    default: str | _EnvTypes = "",
+    type: Optional[Type] = None,
+) -> _EnvTypes:
     """
     Extract an environment variable for use in configuration
 
     :param key: The environment variable to be extracted.
     :param default: The value to be returned if `key` is not found.
     :param type: The type of the returned object (defaults to the type of `default`).
+       Type parsers must come from sentry.utils.types and not python stdlib.
     :return: The environment variable if it exists, else `default`.
     """
 

+ 35 - 1
src/sentry/utils/types.py

@@ -181,7 +181,41 @@ _type_mapping: dict[type[object], Type] = {
 }
 
 
-def type_from_value(value: typing.Any) -> typing.Callable[[typing.Any], typing.Any]:
+# @typing.overload
+# def type_from_value(value: bool) -> BoolType:
+
+
+@typing.overload
+def type_from_value(value: int) -> IntType:
+    ...
+
+
+@typing.overload
+def type_from_value(value: float) -> FloatType:
+    ...
+
+
+@typing.overload
+def type_from_value(value: bytes) -> StringType:
+    ...
+
+
+@typing.overload
+def type_from_value(value: str) -> StringType:
+    ...
+
+
+@typing.overload
+def type_from_value(value: dict) -> DictType:
+    ...
+
+
+@typing.overload
+def type_from_value(value: list) -> SequenceType:
+    ...
+
+
+def type_from_value(value):
     """Fetch Type based on a primitive value"""
     return _type_mapping[type(value)]