@@ -234,35 +234,31 @@ def __init__(self, datafile: str | bytes, logger: Logger, error_handler: Any):
234234
235235 # Feature Rollout support: inject the "everyone else" variation
236236 # into any experiment with type == "feature_rollout"
237- rollout_for_flag = self .get_rollout_from_id (feature .rolloutId ) if feature .rolloutId else None
238- if rollout_for_flag and rollout_for_flag .experiments :
239- everyone_else_rule = rollout_for_flag .experiments [- 1 ]
240- everyone_else_variations = everyone_else_rule .get ('variations' , [])
241- if everyone_else_variations :
242- everyone_else_variation = everyone_else_variations [0 ]
243- for experiment in rules :
244- if getattr (experiment , 'type' , None ) == 'feature_rollout' :
245- experiment .variations .append (everyone_else_variation )
246- experiment .trafficAllocation .append ({
247- 'entityId' : everyone_else_variation ['id' ],
248- 'endOfRange' : 10000 ,
249- })
250- var_entity = entities .Variation (
251- id = everyone_else_variation ['id' ],
252- key = everyone_else_variation ['key' ],
253- featureEnabled = bool (everyone_else_variation .get ('featureEnabled' , False )),
254- variables = cast (
255- Optional [list [entities .Variable ]],
256- everyone_else_variation .get ('variables' ),
257- ),
258- )
259- self .variation_key_map [experiment .key ][var_entity .key ] = var_entity
260- self .variation_id_map [experiment .key ][var_entity .id ] = var_entity
261- self .variation_id_map_by_experiment_id [experiment .id ][var_entity .id ] = var_entity
262- self .variation_key_map_by_experiment_id [experiment .id ][var_entity .key ] = var_entity
263- self .variation_variable_usage_map [var_entity .id ] = self ._generate_key_map (
264- var_entity .variables , 'id' , entities .Variation .VariableUsage
265- )
237+ everyone_else_variation = self ._get_everyone_else_variation (feature )
238+ if everyone_else_variation is not None :
239+ for experiment in rules :
240+ if getattr (experiment , 'type' , None ) == 'feature_rollout' :
241+ experiment .variations .append (everyone_else_variation )
242+ experiment .trafficAllocation .append ({
243+ 'entityId' : everyone_else_variation ['id' ],
244+ 'endOfRange' : 10000 ,
245+ })
246+ var_entity = entities .Variation (
247+ id = everyone_else_variation ['id' ],
248+ key = everyone_else_variation ['key' ],
249+ featureEnabled = bool (everyone_else_variation .get ('featureEnabled' , False )),
250+ variables = cast (
251+ Optional [list [entities .Variable ]],
252+ everyone_else_variation .get ('variables' ),
253+ ),
254+ )
255+ self .variation_key_map [experiment .key ][var_entity .key ] = var_entity
256+ self .variation_id_map [experiment .key ][var_entity .id ] = var_entity
257+ self .variation_id_map_by_experiment_id [experiment .id ][var_entity .id ] = var_entity
258+ self .variation_key_map_by_experiment_id [experiment .id ][var_entity .key ] = var_entity
259+ self .variation_variable_usage_map [var_entity .id ] = self ._generate_key_map (
260+ var_entity .variables , 'id' , entities .Variation .VariableUsage
261+ )
266262
267263 flag_id = feature .id
268264 applicable_holdouts : list [entities .Holdout ] = []
@@ -699,6 +695,32 @@ def get_rollout_from_id(self, rollout_id: str) -> Optional[entities.Layer]:
699695 self .logger .error (f'Rollout with ID "{ rollout_id } " is not in datafile.' )
700696 return None
701697
698+ def _get_everyone_else_variation (self , flag : entities .FeatureFlag ) -> Optional [types .VariationDict ]:
699+ """ Get the "everyone else" variation for a feature flag.
700+
701+ The "everyone else" rule is the last experiment in the flag's rollout,
702+ and its first variation is the "everyone else" variation.
703+
704+ Args:
705+ flag: The feature flag to get the everyone else variation for.
706+
707+ Returns:
708+ The "everyone else" variation dict, or None if not available.
709+ """
710+ if not flag .rolloutId :
711+ return None
712+
713+ rollout = self .get_rollout_from_id (flag .rolloutId )
714+ if not rollout or not rollout .experiments :
715+ return None
716+
717+ everyone_else_rule = rollout .experiments [- 1 ]
718+ variations = everyone_else_rule .get ('variations' , [])
719+ if not variations :
720+ return None
721+
722+ return variations [0 ]
723+
702724 def get_variable_value_for_variation (
703725 self , variable : Optional [entities .Variable ], variation : Optional [Union [entities .Variation , VariationDict ]]
704726 ) -> Optional [str ]:
0 commit comments