@@ -90,18 +90,15 @@ def get_token_replacement(token: str, person_data: list[dict], present_attribute
9090 if TokenProcessor .should_replace_with_empty (parsed_token , present_attributes ):
9191 return ""
9292
93- # Check if this is a derived value (has a function like ADD_DAYS)
9493 if parsed_token .function_name :
9594 return TokenProcessor .get_derived_value (parsed_token , person_data , present_attributes , token )
9695
97- # For non-derived tokens, validate that target attributes are allowed
9896 TokenProcessor .validate_target_attribute (parsed_token , token )
9997
10098 found_attribute , key_to_replace = TokenProcessor .find_matching_attribute (parsed_token , person_data )
10199
102100 if not found_attribute or not key_to_replace :
103101 TokenProcessor .handle_token_not_found (parsed_token , token )
104- # handle_token_not_found always raises, but the type checker needs help
105102 msg = "Unreachable"
106103 raise RuntimeError (msg ) # pragma: no cover
107104
@@ -116,6 +113,11 @@ def get_derived_value(
116113 ) -> str :
117114 """Calculate a derived value using the registered handler.
118115
116+ For TARGET level tokens, validates that the condition is allowed before processing.
117+ If the vaccine type is not in person data, returns an empty string.
118+ For derived values, any target attribute name is allowed (e.g., NEXT_BOOKING_AVAILABLE)
119+ since it's just a placeholder that may be surfaced in the future.
120+
119121 Args:
120122 parsed_token: The parsed token containing function information
121123 person_data: List of person attribute dictionaries
@@ -139,17 +141,12 @@ def get_derived_value(
139141 message = f"Unknown function '{ function_name } ' in token '{ token } '."
140142 raise ValueError (message )
141143
142- # For TARGET level tokens, validate the condition is allowed
143144 if parsed_token .attribute_level == TARGET_ATTRIBUTE_LEVEL :
144145 is_allowed_condition = parsed_token .attribute_name in ALLOWED_CONDITIONS .__args__
145146
146- # If condition is not allowed, raise error
147147 if not is_allowed_condition :
148148 TokenProcessor .handle_token_not_found (parsed_token , token )
149149
150- # If vaccine type is not in person data, return empty string
151- # For derived values, any target attribute name is allowed (e.g., NEXT_BOOKING_AVAILABLE)
152- # since it's just a placeholder that may be surfaced in the future
153150 if parsed_token .attribute_name not in present_attributes :
154151 return ""
155152
@@ -175,7 +172,6 @@ def get_derived_value(
175172 context = context ,
176173 )
177174 except ValueError as e :
178- # Re-raise with more context
179175 message = f"Error calculating derived value for token '{ token } ': { e } "
180176 raise ValueError (message ) from e
181177
0 commit comments