44import typing
55import warnings
66from contextlib import suppress
7- from functools import lru_cache , wraps
7+ from functools import lru_cache , partial , wraps
88
99import jsonpath_rfc9535
1010import semver
2626 SegmentMetadataT ,
2727 is_context_value ,
2828)
29- from flag_engine .segments .utils import escape_double_quotes , get_matching_function
29+ from flag_engine .segments .utils import get_matching_function
3030from flag_engine .utils .hashing import get_hashed_percentage_for_object_ids
3131from flag_engine .utils .semver import is_semver
3232from flag_engine .utils .types import SupportsStr , get_casting_function
@@ -268,9 +268,8 @@ def get_context_value(
268268 value = None
269269 if property .startswith ("$." ):
270270 value = _get_context_value_getter (property )(context )
271- elif identity_context := context .get ("identity" ):
272- if traits := identity_context .get ("traits" ):
273- value = traits .get (property )
271+ else :
272+ value = _get_trait_value (context , property )
274273 return map_any_value_to_context_value (value )
275274
276275
@@ -357,6 +356,16 @@ def inner(
357356}
358357
359358
359+ def _get_trait_value (
360+ context : EvaluationContext [SegmentMetadataT ],
361+ trait_key : str ,
362+ ) -> ContextValue :
363+ if identity_context := context .get ("identity" ):
364+ if traits := identity_context .get ("traits" ):
365+ return traits .get (trait_key )
366+ return None
367+
368+
360369@lru_cache
361370def _get_context_value_getter (
362371 property : str ,
@@ -373,11 +382,12 @@ def _get_context_value_getter(
373382 except jsonpath_rfc9535 .JSONPathSyntaxError :
374383 # This covers a rare case when a trait starting with "$.",
375384 # but not a valid JSONPath, is used.
376- compiled_query = jsonpath_rfc9535 .compile (
377- f'$.identity.traits["{ escape_double_quotes (property )} "]' ,
378- )
385+ return partial (_get_trait_value , trait_key = property )
379386
380387 def getter (context : EvaluationContext [SegmentMetadataT ]) -> ContextValue :
388+ value : object
389+ if (value := _get_trait_value (context , property )) is not None :
390+ return value
381391 if typing .TYPE_CHECKING : # pragma: no cover
382392 # Ugly hack to satisfy mypy :(
383393 data = dict (context )
0 commit comments