diff --git a/openfeature/api.py b/openfeature/api.py index d2b22e9d..7e06c886 100644 --- a/openfeature/api.py +++ b/openfeature/api.py @@ -1,5 +1,3 @@ -import typing - from openfeature import _event_support from openfeature.client import OpenFeatureClient from openfeature.evaluation_context import ( @@ -40,14 +38,12 @@ def get_client( - domain: typing.Optional[str] = None, version: typing.Optional[str] = None + domain: str | None = None, version: str | None = None ) -> OpenFeatureClient: return OpenFeatureClient(domain=domain, version=version) -def set_provider( - provider: FeatureProvider, domain: typing.Optional[str] = None -) -> None: +def set_provider(provider: FeatureProvider, domain: str | None = None) -> None: if domain is None: provider_registry.set_default_provider(provider) else: @@ -59,7 +55,7 @@ def clear_providers() -> None: _event_support.clear() -def get_provider_metadata(domain: typing.Optional[str] = None) -> Metadata: +def get_provider_metadata(domain: str | None = None) -> Metadata: return provider_registry.get_provider(domain).get_metadata() diff --git a/openfeature/client.py b/openfeature/client.py index 42690f9e..a02693c1 100644 --- a/openfeature/client.py +++ b/openfeature/client.py @@ -43,16 +43,10 @@ TypeMap = dict[ FlagType, - typing.Union[ - type[bool], - type[int], - type[float], - type[str], - tuple[type[dict], type[list]], - ], + type[bool] | type[int] | type[float] | type[str] | tuple[type[dict], type[list]], ] -T = typing.TypeVar("T", bool, int, float, str, typing.Union[dict, list]) +T = typing.TypeVar("T", bool, int, float, str, dict | list) class ResolveDetailsCallable(typing.Protocol[T]): @@ -60,7 +54,7 @@ def __call__( self, flag_key: str, default_value: T, - evaluation_context: typing.Optional[EvaluationContext], + evaluation_context: EvaluationContext | None, ) -> FlagResolutionDetails[T]: ... @@ -69,23 +63,23 @@ def __call__( self, flag_key: str, default_value: T, - evaluation_context: typing.Optional[EvaluationContext], + evaluation_context: EvaluationContext | None, ) -> Awaitable[FlagResolutionDetails[T]]: ... @dataclass class ClientMetadata: - name: typing.Optional[str] = None - domain: typing.Optional[str] = None + name: str | None = None + domain: str | None = None class OpenFeatureClient: def __init__( self, - domain: typing.Optional[str], - version: typing.Optional[str], - context: typing.Optional[EvaluationContext] = None, - hooks: typing.Optional[list[Hook]] = None, + domain: str | None, + version: str | None, + context: EvaluationContext | None = None, + hooks: list[Hook] | None = None, ) -> None: self.domain = domain self.version = version @@ -109,8 +103,8 @@ def get_boolean_value( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> bool: return self.get_boolean_details( flag_key, @@ -123,8 +117,8 @@ async def get_boolean_value_async( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> bool: details = await self.get_boolean_details_async( flag_key, @@ -138,8 +132,8 @@ def get_boolean_details( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[bool]: return self.evaluate_flag_details( FlagType.BOOLEAN, @@ -153,8 +147,8 @@ async def get_boolean_details_async( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[bool]: return await self.evaluate_flag_details_async( FlagType.BOOLEAN, @@ -168,8 +162,8 @@ def get_string_value( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> str: return self.get_string_details( flag_key, @@ -182,8 +176,8 @@ async def get_string_value_async( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> str: details = await self.get_string_details_async( flag_key, @@ -197,8 +191,8 @@ def get_string_details( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[str]: return self.evaluate_flag_details( FlagType.STRING, @@ -212,8 +206,8 @@ async def get_string_details_async( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[str]: return await self.evaluate_flag_details_async( FlagType.STRING, @@ -227,8 +221,8 @@ def get_integer_value( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> int: return self.get_integer_details( flag_key, @@ -241,8 +235,8 @@ async def get_integer_value_async( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> int: details = await self.get_integer_details_async( flag_key, @@ -256,8 +250,8 @@ def get_integer_details( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[int]: return self.evaluate_flag_details( FlagType.INTEGER, @@ -271,8 +265,8 @@ async def get_integer_details_async( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[int]: return await self.evaluate_flag_details_async( FlagType.INTEGER, @@ -286,8 +280,8 @@ def get_float_value( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> float: return self.get_float_details( flag_key, @@ -300,8 +294,8 @@ async def get_float_value_async( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> float: details = await self.get_float_details_async( flag_key, @@ -315,8 +309,8 @@ def get_float_details( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[float]: return self.evaluate_flag_details( FlagType.FLOAT, @@ -330,8 +324,8 @@ async def get_float_details_async( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[float]: return await self.evaluate_flag_details_async( FlagType.FLOAT, @@ -344,12 +338,10 @@ async def get_float_details_async( def get_object_value( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, - ) -> typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]]: + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, + ) -> Sequence[FlagValueType] | Mapping[str, FlagValueType]: return self.get_object_details( flag_key, default_value, @@ -360,12 +352,10 @@ def get_object_value( async def get_object_value_async( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, - ) -> typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]]: + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, + ) -> Sequence[FlagValueType] | Mapping[str, FlagValueType]: details = await self.get_object_details_async( flag_key, default_value, @@ -377,14 +367,10 @@ async def get_object_value_async( def get_object_details( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, - ) -> FlagEvaluationDetails[ - typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]] - ]: + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, + ) -> FlagEvaluationDetails[Sequence[FlagValueType] | Mapping[str, FlagValueType]]: return self.evaluate_flag_details( FlagType.OBJECT, flag_key, @@ -396,14 +382,10 @@ def get_object_details( async def get_object_details_async( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, - ) -> FlagEvaluationDetails[ - typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]] - ]: + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, + ) -> FlagEvaluationDetails[Sequence[FlagValueType] | Mapping[str, FlagValueType]]: return await self.evaluate_flag_details_async( FlagType.OBJECT, flag_key, @@ -417,8 +399,8 @@ def _establish_hooks_and_provider( flag_type: FlagType, flag_key: str, default_value: FlagValueType, - evaluation_context: typing.Optional[EvaluationContext], - flag_evaluation_options: typing.Optional[FlagEvaluationOptions], + evaluation_context: EvaluationContext | None, + flag_evaluation_options: FlagEvaluationOptions | None, ) -> tuple[ FeatureProvider, HookHints, @@ -485,7 +467,7 @@ def _establish_hooks_and_provider( def _assert_provider_status( self, - ) -> typing.Optional[OpenFeatureError]: + ) -> OpenFeatureError | None: status = self.get_provider_status() if status == ProviderStatus.NOT_READY: return ProviderNotReadyError() @@ -518,8 +500,8 @@ async def evaluate_flag_details_async( flag_type: FlagType, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[bool]: ... @typing.overload @@ -528,8 +510,8 @@ async def evaluate_flag_details_async( flag_type: FlagType, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[int]: ... @typing.overload @@ -538,8 +520,8 @@ async def evaluate_flag_details_async( flag_type: FlagType, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[float]: ... @typing.overload @@ -548,8 +530,8 @@ async def evaluate_flag_details_async( flag_type: FlagType, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[str]: ... @typing.overload @@ -558,8 +540,8 @@ async def evaluate_flag_details_async( flag_type: FlagType, flag_key: str, default_value: Sequence["FlagValueType"], - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[Sequence["FlagValueType"]]: ... @typing.overload @@ -568,8 +550,8 @@ async def evaluate_flag_details_async( flag_type: FlagType, flag_key: str, default_value: Mapping[str, "FlagValueType"], - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[Mapping[str, "FlagValueType"]]: ... async def evaluate_flag_details_async( @@ -577,8 +559,8 @@ async def evaluate_flag_details_async( flag_type: FlagType, flag_key: str, default_value: FlagValueType, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[FlagValueType]: """ Evaluate the flag requested by the user from the clients provider. @@ -694,8 +676,8 @@ def evaluate_flag_details( flag_type: FlagType, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[bool]: ... @typing.overload @@ -704,8 +686,8 @@ def evaluate_flag_details( flag_type: FlagType, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[int]: ... @typing.overload @@ -714,8 +696,8 @@ def evaluate_flag_details( flag_type: FlagType, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[float]: ... @typing.overload @@ -724,8 +706,8 @@ def evaluate_flag_details( flag_type: FlagType, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[str]: ... @typing.overload @@ -734,8 +716,8 @@ def evaluate_flag_details( flag_type: FlagType, flag_key: str, default_value: Sequence["FlagValueType"], - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[Sequence["FlagValueType"]]: ... @typing.overload @@ -744,8 +726,8 @@ def evaluate_flag_details( flag_type: FlagType, flag_key: str, default_value: Mapping[str, "FlagValueType"], - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[Mapping[str, "FlagValueType"]]: ... def evaluate_flag_details( @@ -753,8 +735,8 @@ def evaluate_flag_details( flag_type: FlagType, flag_key: str, default_value: FlagValueType, - evaluation_context: typing.Optional[EvaluationContext] = None, - flag_evaluation_options: typing.Optional[FlagEvaluationOptions] = None, + evaluation_context: EvaluationContext | None = None, + flag_evaluation_options: FlagEvaluationOptions | None = None, ) -> FlagEvaluationDetails[FlagValueType]: """ Evaluate the flag requested by the user from the clients provider. @@ -872,7 +854,7 @@ async def _create_provider_evaluation_async( flag_type: FlagType, flag_key: str, default_value: FlagValueType, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagEvaluationDetails[FlagValueType]: get_details_callables_async: Mapping[FlagType, ResolveDetailsCallableAsync] = { FlagType.BOOLEAN: provider.resolve_boolean_details_async, @@ -917,7 +899,7 @@ def _create_provider_evaluation( flag_type: FlagType, flag_key: str, default_value: FlagValueType, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagEvaluationDetails[FlagValueType]: """ Encapsulated method to create a FlagEvaluationDetail from a specific provider. @@ -976,7 +958,7 @@ def remove_handler(self, event: ProviderEvent, handler: EventHandler) -> None: def _typecheck_flag_value( value: typing.Any, flag_type: FlagType -) -> typing.Optional[OpenFeatureError]: +) -> OpenFeatureError | None: type_map: TypeMap = { FlagType.BOOLEAN: bool, FlagType.STRING: str, diff --git a/openfeature/evaluation_context/__init__.py b/openfeature/evaluation_context/__init__.py index 948a4baf..4c046418 100644 --- a/openfeature/evaluation_context/__init__.py +++ b/openfeature/evaluation_context/__init__.py @@ -10,20 +10,20 @@ __all__ = ["EvaluationContext", "get_evaluation_context", "set_evaluation_context"] # https://openfeature.dev/specification/sections/evaluation-context#requirement-312 -EvaluationContextAttribute = typing.Union[ - bool, - int, - float, - str, - datetime, - Sequence["EvaluationContextAttribute"], - Mapping[str, "EvaluationContextAttribute"], -] +EvaluationContextAttribute: typing.TypeAlias = ( + bool + | int + | float + | str + | datetime + | Sequence["EvaluationContextAttribute"] + | Mapping[str, "EvaluationContextAttribute"] +) @dataclass class EvaluationContext: - targeting_key: typing.Optional[str] = None + targeting_key: str | None = None attributes: Mapping[str, EvaluationContextAttribute] = field(default_factory=dict) def merge(self, ctx2: EvaluationContext) -> EvaluationContext: diff --git a/openfeature/event.py b/openfeature/event.py index f40ad74a..53dc3834 100644 --- a/openfeature/event.py +++ b/openfeature/event.py @@ -1,6 +1,5 @@ from __future__ import annotations -import typing from collections.abc import Callable from dataclasses import dataclass, field from enum import Enum @@ -19,23 +18,19 @@ class ProviderEvent(Enum): @dataclass class ProviderEventDetails: - flags_changed: typing.Optional[list[str]] = None - message: typing.Optional[str] = None - error_code: typing.Optional[ErrorCode] = None - metadata: dict[str, typing.Union[bool, str, int, float]] = field( - default_factory=dict - ) + flags_changed: list[str] | None = None + message: str | None = None + error_code: ErrorCode | None = None + metadata: dict[str, bool | str | int | float] = field(default_factory=dict) @dataclass class EventDetails(ProviderEventDetails): provider_name: str = "" - flags_changed: typing.Optional[list[str]] = None - message: typing.Optional[str] = None - error_code: typing.Optional[ErrorCode] = None - metadata: dict[str, typing.Union[bool, str, int, float]] = field( - default_factory=dict - ) + flags_changed: list[str] | None = None + message: str | None = None + error_code: ErrorCode | None = None + metadata: dict[str, bool | str | int | float] = field(default_factory=dict) @classmethod def from_provider_event_details( diff --git a/openfeature/exception.py b/openfeature/exception.py index d4fc388f..fbd13897 100644 --- a/openfeature/exception.py +++ b/openfeature/exception.py @@ -1,6 +1,5 @@ from __future__ import annotations -import typing from collections.abc import Callable, Mapping from openfeature._backports.strenum import StrEnum @@ -25,9 +24,7 @@ class OpenFeatureError(Exception): the more specific exceptions extending this one should be used. """ - def __init__( - self, error_code: ErrorCode, error_message: typing.Optional[str] = None - ): + def __init__(self, error_code: ErrorCode, error_message: str | None = None): """ Constructor for the generic OpenFeatureError. @param error_message: an optional string message representing why the @@ -43,7 +40,7 @@ class ProviderNotReadyError(OpenFeatureError): This exception should be raised when the provider is not ready to be used. """ - def __init__(self, error_message: typing.Optional[str] = None): + def __init__(self, error_message: str | None = None): """ Constructor for the ProviderNotReadyError. The error code for this type of exception is ErrorCode.PROVIDER_NOT_READY. @@ -58,7 +55,7 @@ class ProviderFatalError(OpenFeatureError): This exception should be raised when the provider encounters a fatal error. """ - def __init__(self, error_message: typing.Optional[str] = None): + def __init__(self, error_message: str | None = None): """ Constructor for the ProviderFatalError. The error code for this type of exception is ErrorCode.PROVIDER_FATAL. @@ -74,7 +71,7 @@ class FlagNotFoundError(OpenFeatureError): key provided by the user. """ - def __init__(self, error_message: typing.Optional[str] = None): + def __init__(self, error_message: str | None = None): """ Constructor for the FlagNotFoundError. The error code for this type of exception is ErrorCode.FLAG_NOT_FOUND. @@ -90,7 +87,7 @@ class GeneralError(OpenFeatureError): feature python sdk. """ - def __init__(self, error_message: typing.Optional[str] = None): + def __init__(self, error_message: str | None = None): """ Constructor for the GeneralError. The error code for this type of exception is ErrorCode.GENERAL. @@ -106,7 +103,7 @@ class ParseError(OpenFeatureError): be parsed into a FlagEvaluationDetails object. """ - def __init__(self, error_message: typing.Optional[str] = None): + def __init__(self, error_message: str | None = None): """ Constructor for the ParseError. The error code for this type of exception is ErrorCode.PARSE_ERROR. @@ -122,7 +119,7 @@ class TypeMismatchError(OpenFeatureError): not match the type requested by the user. """ - def __init__(self, error_message: typing.Optional[str] = None): + def __init__(self, error_message: str | None = None): """ Constructor for the TypeMismatchError. The error code for this type of exception is ErrorCode.TYPE_MISMATCH. @@ -138,7 +135,7 @@ class TargetingKeyMissingError(OpenFeatureError): but one was not provided in the evaluation context. """ - def __init__(self, error_message: typing.Optional[str] = None): + def __init__(self, error_message: str | None = None): """ Constructor for the TargetingKeyMissingError. The error code for this type of exception is ErrorCode.TARGETING_KEY_MISSING. @@ -154,7 +151,7 @@ class InvalidContextError(OpenFeatureError): requirements. """ - def __init__(self, error_message: typing.Optional[str]): + def __init__(self, error_message: str | None): """ Constructor for the InvalidContextError. The error code for this type of exception is ErrorCode.INVALID_CONTEXT. diff --git a/openfeature/flag_evaluation.py b/openfeature/flag_evaluation.py index 723f8bb5..df47e732 100644 --- a/openfeature/flag_evaluation.py +++ b/openfeature/flag_evaluation.py @@ -42,15 +42,10 @@ class Reason(StrEnum): UNKNOWN = "UNKNOWN" -FlagMetadata = Mapping[str, typing.Union[bool, int, float, str]] -FlagValueType = typing.Union[ - bool, - int, - float, - str, - Sequence["FlagValueType"], - Mapping[str, "FlagValueType"], -] +FlagMetadata = Mapping[str, bool | int | float | str] +FlagValueType: typing.TypeAlias = ( + bool | int | float | str | Sequence["FlagValueType"] | Mapping[str, "FlagValueType"] +) T_co = typing.TypeVar("T_co", covariant=True) @@ -59,13 +54,13 @@ class Reason(StrEnum): class FlagEvaluationDetails(typing.Generic[T_co]): flag_key: str value: T_co - variant: typing.Optional[str] = None + variant: str | None = None flag_metadata: FlagMetadata = field(default_factory=dict) - reason: typing.Optional[typing.Union[str, Reason]] = None - error_code: typing.Optional[ErrorCode] = None - error_message: typing.Optional[str] = None + reason: str | Reason | None = None + error_code: ErrorCode | None = None + error_message: str | None = None - def get_exception(self) -> typing.Optional[OpenFeatureError]: + def get_exception(self) -> OpenFeatureError | None: if self.error_code: return ErrorCode.to_exception(self.error_code, self.error_message or "") return None @@ -83,10 +78,10 @@ class FlagEvaluationOptions: @dataclass class FlagResolutionDetails(typing.Generic[U_co]): value: U_co - error_code: typing.Optional[ErrorCode] = None - error_message: typing.Optional[str] = None - reason: typing.Optional[typing.Union[str, Reason]] = None - variant: typing.Optional[str] = None + error_code: ErrorCode | None = None + error_message: str | None = None + reason: str | Reason | None = None + variant: str | None = None flag_metadata: FlagMetadata = field(default_factory=dict) def raise_for_error(self) -> None: diff --git a/openfeature/hook/__init__.py b/openfeature/hook/__init__.py index 2d5282c2..247d316b 100644 --- a/openfeature/hook/__init__.py +++ b/openfeature/hook/__init__.py @@ -44,9 +44,9 @@ def __init__( # noqa: PLR0913 flag_type: FlagType, default_value: FlagValueType, evaluation_context: EvaluationContext, - client_metadata: typing.Optional[ClientMetadata] = None, - provider_metadata: typing.Optional[Metadata] = None, - hook_data: typing.Optional[HookData] = None, + client_metadata: ClientMetadata | None = None, + provider_metadata: Metadata | None = None, + hook_data: HookData | None = None, ): self.flag_key = flag_key self.flag_type = flag_type @@ -69,15 +69,15 @@ def __setattr__(self, key: str, value: typing.Any) -> None: # https://openfeature.dev/specification/sections/hooks/#requirement-421 -HookHintValue = typing.Union[ - bool, - int, - float, - str, - datetime, - Sequence["HookHintValue"], - Mapping[str, "HookHintValue"], -] +HookHintValue: typing.TypeAlias = ( + bool + | int + | float + | str + | datetime + | Sequence["HookHintValue"] + | Mapping[str, "HookHintValue"] +) HookHints = Mapping[str, HookHintValue] @@ -85,7 +85,7 @@ def __setattr__(self, key: str, value: typing.Any) -> None: class Hook: def before( self, hook_context: HookContext, hints: HookHints - ) -> typing.Optional[EvaluationContext]: + ) -> EvaluationContext | None: """ Runs before flag is resolved. diff --git a/openfeature/hook/_hook_support.py b/openfeature/hook/_hook_support.py index 0a3565cd..4f292997 100644 --- a/openfeature/hook/_hook_support.py +++ b/openfeature/hook/_hook_support.py @@ -13,7 +13,7 @@ def error_hooks( flag_type: FlagType, exception: Exception, hooks_and_context: list[tuple[Hook, HookContext]], - hints: typing.Optional[HookHints] = None, + hints: HookHints | None = None, ) -> None: kwargs = {"exception": exception, "hints": hints} _execute_hooks( @@ -28,7 +28,7 @@ def after_all_hooks( flag_type: FlagType, details: FlagEvaluationDetails[typing.Any], hooks_and_context: list[tuple[Hook, HookContext]], - hints: typing.Optional[HookHints] = None, + hints: HookHints | None = None, ) -> None: kwargs = {"details": details, "hints": hints} _execute_hooks( @@ -43,7 +43,7 @@ def after_hooks( flag_type: FlagType, details: FlagEvaluationDetails[typing.Any], hooks_and_context: list[tuple[Hook, HookContext]], - hints: typing.Optional[HookHints] = None, + hints: HookHints | None = None, ) -> None: kwargs = {"details": details, "hints": hints} _execute_hooks_unchecked( @@ -57,7 +57,7 @@ def after_hooks( def before_hooks( flag_type: FlagType, hooks_and_context: list[tuple[Hook, HookContext]], - hints: typing.Optional[HookHints] = None, + hints: HookHints | None = None, ) -> EvaluationContext: kwargs = {"hints": hints} executed_hooks = _execute_hooks_unchecked( @@ -79,7 +79,7 @@ def _execute_hooks( hooks_and_context: list[tuple[Hook, HookContext]], hook_method: HookType, **kwargs: typing.Any, -) -> list[typing.Optional[EvaluationContext]]: +) -> list[EvaluationContext | None]: """ Run multiple hooks of any hook type. All of these hooks will be run through an exception check. @@ -102,7 +102,7 @@ def _execute_hooks_unchecked( hooks_and_context: list[tuple[Hook, HookContext]], hook_method: HookType, **kwargs: typing.Any, -) -> list[typing.Optional[EvaluationContext]]: +) -> list[EvaluationContext | None]: """ Execute a single hook without checking whether an exception is thrown. This is used in the before and after hooks since any exception will be caught in the @@ -123,7 +123,7 @@ def _execute_hooks_unchecked( def _execute_hook_checked( hook: Hook, hook_method: HookType, **kwargs: typing.Any -) -> typing.Optional[EvaluationContext]: +) -> EvaluationContext | None: """ Try and run a single hook and catch any exception thrown. This is used in the after all and error hooks since any error thrown at this point needs to be caught. @@ -135,7 +135,7 @@ def _execute_hook_checked( """ try: return typing.cast( - "typing.Optional[EvaluationContext]", + "EvaluationContext | None", getattr(hook, hook_method.value)(**kwargs), ) except Exception: # pragma: no cover diff --git a/openfeature/provider/__init__.py b/openfeature/provider/__init__.py index cf21c023..aea5069f 100644 --- a/openfeature/provider/__init__.py +++ b/openfeature/provider/__init__.py @@ -46,78 +46,74 @@ def resolve_boolean_details( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: ... async def resolve_boolean_details_async( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: ... def resolve_string_details( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[str]: ... async def resolve_string_details_async( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[str]: ... def resolve_integer_details( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[int]: ... async def resolve_integer_details_async( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[int]: ... def resolve_float_details( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[float]: ... async def resolve_float_details_async( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[float]: ... def resolve_object_details( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[ - typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]] + Sequence[FlagValueType] | Mapping[str, FlagValueType] ]: ... async def resolve_object_details_async( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[ - typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]] + Sequence[FlagValueType] | Mapping[str, FlagValueType] ]: ... @@ -154,7 +150,7 @@ def resolve_boolean_details( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: pass @@ -162,7 +158,7 @@ async def resolve_boolean_details_async( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: return self.resolve_boolean_details(flag_key, default_value, evaluation_context) @@ -171,7 +167,7 @@ def resolve_string_details( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[str]: pass @@ -179,7 +175,7 @@ async def resolve_string_details_async( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[str]: return self.resolve_string_details(flag_key, default_value, evaluation_context) @@ -188,7 +184,7 @@ def resolve_integer_details( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[int]: pass @@ -196,7 +192,7 @@ async def resolve_integer_details_async( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[int]: return self.resolve_integer_details(flag_key, default_value, evaluation_context) @@ -205,7 +201,7 @@ def resolve_float_details( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[float]: pass @@ -213,7 +209,7 @@ async def resolve_float_details_async( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[float]: return self.resolve_float_details(flag_key, default_value, evaluation_context) @@ -221,25 +217,17 @@ async def resolve_float_details_async( def resolve_object_details( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, - ) -> FlagResolutionDetails[ - typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]] - ]: + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, + ) -> FlagResolutionDetails[Sequence[FlagValueType] | Mapping[str, FlagValueType]]: pass async def resolve_object_details_async( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, - ) -> FlagResolutionDetails[ - typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]] - ]: + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, + ) -> FlagResolutionDetails[Sequence[FlagValueType] | Mapping[str, FlagValueType]]: return self.resolve_object_details(flag_key, default_value, evaluation_context) def emit_provider_ready(self, details: ProviderEventDetails) -> None: diff --git a/openfeature/provider/_registry.py b/openfeature/provider/_registry.py index 1b5ff041..7529d9fa 100644 --- a/openfeature/provider/_registry.py +++ b/openfeature/provider/_registry.py @@ -1,5 +1,3 @@ -import typing - from openfeature._event_support import run_handlers_for_provider from openfeature.evaluation_context import EvaluationContext, get_evaluation_context from openfeature.event import ( @@ -36,7 +34,7 @@ def set_provider(self, domain: str, provider: FeatureProvider) -> None: self._initialize_provider(provider) providers[domain] = provider - def get_provider(self, domain: typing.Optional[str]) -> FeatureProvider: + def get_provider(self, domain: str | None) -> FeatureProvider: if domain is None: return self._default_provider return self._providers.get(domain, self._default_provider) diff --git a/openfeature/provider/in_memory_provider.py b/openfeature/provider/in_memory_provider.py index 958edd71..2ef00db9 100644 --- a/openfeature/provider/in_memory_provider.py +++ b/openfeature/provider/in_memory_provider.py @@ -35,12 +35,13 @@ class State(StrEnum): variants: dict[str, T_co] flag_metadata: FlagMetadata = field(default_factory=dict) state: State = State.ENABLED - context_evaluator: typing.Optional[ + context_evaluator: ( Callable[[InMemoryFlag[T_co], EvaluationContext], FlagResolutionDetails[T_co]] - ] = None + | None + ) = None def resolve( - self, evaluation_context: typing.Optional[EvaluationContext] + self, evaluation_context: EvaluationContext | None ) -> FlagResolutionDetails[T_co]: if self.context_evaluator: return self.context_evaluator( @@ -76,7 +77,7 @@ def resolve_boolean_details( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: return self._resolve(flag_key, default_value, evaluation_context) @@ -84,7 +85,7 @@ async def resolve_boolean_details_async( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: return await self._resolve_async(flag_key, default_value, evaluation_context) @@ -92,7 +93,7 @@ def resolve_string_details( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[str]: return self._resolve(flag_key, default_value, evaluation_context) @@ -100,7 +101,7 @@ async def resolve_string_details_async( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[str]: return await self._resolve_async(flag_key, default_value, evaluation_context) @@ -108,7 +109,7 @@ def resolve_integer_details( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[int]: return self._resolve(flag_key, default_value, evaluation_context) @@ -116,7 +117,7 @@ async def resolve_integer_details_async( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[int]: return await self._resolve_async(flag_key, default_value, evaluation_context) @@ -124,7 +125,7 @@ def resolve_float_details( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[float]: return self._resolve(flag_key, default_value, evaluation_context) @@ -132,39 +133,31 @@ async def resolve_float_details_async( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[float]: return await self._resolve_async(flag_key, default_value, evaluation_context) def resolve_object_details( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, - ) -> FlagResolutionDetails[ - typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]] - ]: + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, + ) -> FlagResolutionDetails[Sequence[FlagValueType] | Mapping[str, FlagValueType]]: return self._resolve(flag_key, default_value, evaluation_context) async def resolve_object_details_async( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, - ) -> FlagResolutionDetails[ - typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]] - ]: + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, + ) -> FlagResolutionDetails[Sequence[FlagValueType] | Mapping[str, FlagValueType]]: return await self._resolve_async(flag_key, default_value, evaluation_context) def _resolve( self, flag_key: str, default_value: V, - evaluation_context: typing.Optional[EvaluationContext], + evaluation_context: EvaluationContext | None, ) -> FlagResolutionDetails[V]: flag = self._flags.get(flag_key) if flag is None: @@ -180,6 +173,6 @@ async def _resolve_async( self, flag_key: str, default_value: V, - evaluation_context: typing.Optional[EvaluationContext], + evaluation_context: EvaluationContext | None, ) -> FlagResolutionDetails[V]: return self._resolve(flag_key, default_value, evaluation_context) diff --git a/openfeature/provider/no_op_provider.py b/openfeature/provider/no_op_provider.py index 30d4c571..9bd1d169 100644 --- a/openfeature/provider/no_op_provider.py +++ b/openfeature/provider/no_op_provider.py @@ -27,7 +27,7 @@ def resolve_boolean_details( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: return FlagResolutionDetails( value=default_value, @@ -39,7 +39,7 @@ def resolve_string_details( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[str]: return FlagResolutionDetails( value=default_value, @@ -51,7 +51,7 @@ def resolve_integer_details( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[int]: return FlagResolutionDetails( value=default_value, @@ -63,7 +63,7 @@ def resolve_float_details( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[float]: return FlagResolutionDetails( value=default_value, @@ -74,13 +74,9 @@ def resolve_float_details( def resolve_object_details( self, flag_key: str, - default_value: typing.Union[ - Sequence[FlagValueType], Mapping[str, FlagValueType] - ], - evaluation_context: typing.Optional[EvaluationContext] = None, - ) -> FlagResolutionDetails[ - typing.Union[Sequence[FlagValueType], Mapping[str, FlagValueType]] - ]: + default_value: Sequence[FlagValueType] | Mapping[str, FlagValueType], + evaluation_context: EvaluationContext | None = None, + ) -> FlagResolutionDetails[Sequence[FlagValueType] | Mapping[str, FlagValueType]]: return FlagResolutionDetails( value=default_value, reason=Reason.DEFAULT, diff --git a/openfeature/telemetry/__init__.py b/openfeature/telemetry/__init__.py index ef97eff3..7342bb81 100644 --- a/openfeature/telemetry/__init__.py +++ b/openfeature/telemetry/__init__.py @@ -25,7 +25,7 @@ @dataclass class EvaluationEvent(typing.Generic[T_co]): name: str - attributes: Mapping[TelemetryAttribute, typing.Union[str, T_co]] + attributes: Mapping[TelemetryAttribute, str | T_co] body: Mapping[TelemetryBodyField, T_co] diff --git a/openfeature/transaction_context/context_var_transaction_context_propagator.py b/openfeature/transaction_context/context_var_transaction_context_propagator.py index 30869359..449c67a1 100644 --- a/openfeature/transaction_context/context_var_transaction_context_propagator.py +++ b/openfeature/transaction_context/context_var_transaction_context_propagator.py @@ -1,4 +1,3 @@ -import typing from contextvars import ContextVar from openfeature.evaluation_context import EvaluationContext @@ -8,8 +7,8 @@ class ContextVarsTransactionContextPropagator(TransactionContextPropagator): - _transaction_context_var: ContextVar[typing.Optional[EvaluationContext]] = ( - ContextVar("transaction_context", default=None) + _transaction_context_var: ContextVar[EvaluationContext | None] = ContextVar( + "transaction_context", default=None ) def get_transaction_context(self) -> EvaluationContext: diff --git a/pyproject.toml b/pyproject.toml index 79c398e2..bd2e00dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,9 +71,10 @@ exclude = [ ".git", ".venv", "__pycache__", + "spec", "venv", ] -target-version = "py39" +target-version = "py310" [tool.ruff.lint] select = [ @@ -139,4 +140,4 @@ test-cov = "scripts.scripts:test_cov" cov-report = "scripts.scripts:cov_report" cov = "scripts.scripts:cov" e2e = "scripts.scripts:e2e" -precommit = "scripts.scripts:precommit" \ No newline at end of file +precommit = "scripts.scripts:precommit" diff --git a/tests/hook/test_hook_data.py b/tests/hook/test_hook_data.py index 33d12591..a7e3e0d3 100644 --- a/tests/hook/test_hook_data.py +++ b/tests/hook/test_hook_data.py @@ -20,7 +20,7 @@ def __init__(self, data: dict[str, typing.Any]): def before( self, hook_context: HookContext, hints: HookHints - ) -> typing.Optional[EvaluationContext]: + ) -> EvaluationContext | None: hook_context.hook_data = hook_context.hook_data | self.data_before return None diff --git a/tests/provider/test_provider_compatibility.py b/tests/provider/test_provider_compatibility.py index b49c6553..80c8cf2a 100644 --- a/tests/provider/test_provider_compatibility.py +++ b/tests/provider/test_provider_compatibility.py @@ -1,5 +1,3 @@ -import typing - import pytest from openfeature.api import get_client, set_provider @@ -19,7 +17,7 @@ def resolve_boolean_details( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: return FlagResolutionDetails(value=True) @@ -27,7 +25,7 @@ def resolve_string_details( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[str]: return FlagResolutionDetails(value="string") @@ -35,7 +33,7 @@ def resolve_integer_details( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[int]: return FlagResolutionDetails(value=1) @@ -43,16 +41,16 @@ def resolve_float_details( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[float]: return FlagResolutionDetails(value=10.0) def resolve_object_details( self, flag_key: str, - default_value: typing.Union[dict, list], - evaluation_context: typing.Optional[EvaluationContext] = None, - ) -> FlagResolutionDetails[typing.Union[dict, list]]: + default_value: dict | list, + evaluation_context: EvaluationContext | None = None, + ) -> FlagResolutionDetails[dict | list]: return FlagResolutionDetails(value={"key": "value"}) @@ -92,7 +90,7 @@ async def resolve_boolean_details_async( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: return FlagResolutionDetails(value=False) @@ -116,7 +114,7 @@ async def resolve_boolean_details_async( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: return FlagResolutionDetails(value=True) @@ -144,7 +142,7 @@ async def resolve_boolean_details_async( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: return FlagResolutionDetails(value=True) @@ -152,7 +150,7 @@ def resolve_boolean_details( self, flag_key: str, default_value: bool, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[bool]: raise NotImplementedError("Use the async method") @@ -160,7 +158,7 @@ def resolve_string_details( self, flag_key: str, default_value: str, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[str]: raise NotImplementedError("Use the async method") @@ -168,7 +166,7 @@ def resolve_integer_details( self, flag_key: str, default_value: int, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[int]: raise NotImplementedError("Use the async method") @@ -176,16 +174,16 @@ def resolve_float_details( self, flag_key: str, default_value: float, - evaluation_context: typing.Optional[EvaluationContext] = None, + evaluation_context: EvaluationContext | None = None, ) -> FlagResolutionDetails[float]: raise NotImplementedError("Use the async method") def resolve_object_details( self, flag_key: str, - default_value: typing.Union[dict, list], - evaluation_context: typing.Optional[EvaluationContext] = None, - ) -> FlagResolutionDetails[typing.Union[dict, list]]: + default_value: dict | list, + evaluation_context: EvaluationContext | None = None, + ) -> FlagResolutionDetails[dict | list]: raise NotImplementedError("Use the async method") # When