diff --git a/posthog/client.py b/posthog/client.py index 64db985d..1600c5af 100644 --- a/posthog/client.py +++ b/posthog/client.py @@ -1928,10 +1928,12 @@ def _capture_feature_flag_called( f"{key}_{'::null::' if response is None else str(response)}" ) - if ( - feature_flag_reported_key - not in self.distinct_ids_feature_flags_reported[distinct_id] - ): + reported_flags = self.distinct_ids_feature_flags_reported.get(distinct_id) + if reported_flags is None: + reported_flags = set() + self.distinct_ids_feature_flags_reported[distinct_id] = reported_flags + + if feature_flag_reported_key not in reported_flags: properties: dict[str, Any] = { "$feature_flag": key, "$feature_flag_response": response, @@ -1967,9 +1969,7 @@ def _capture_feature_flag_called( groups=groups, disable_geoip=disable_geoip, ) - self.distinct_ids_feature_flags_reported[distinct_id].add( - feature_flag_reported_key - ) + reported_flags.add(feature_flag_reported_key) def get_remote_config_payload(self, key: str): if self.disabled: diff --git a/posthog/test/test_feature_flags.py b/posthog/test/test_feature_flags.py index 783793f8..042ddb4b 100644 --- a/posthog/test/test_feature_flags.py +++ b/posthog/test/test_feature_flags.py @@ -2513,7 +2513,10 @@ def test_load_feature_flags_clears_etag_when_server_stops_sending( self.assertIsNone(client._flags_etag) self.assertEqual(client.feature_flags[0]["key"], "flag-v2") - def test_load_feature_flags_wrong_key(self): + @mock.patch("posthog.client.Poller") + @mock.patch("posthog.client.get") + def test_load_feature_flags_wrong_key(self, patch_get, _patch_poll): + patch_get.side_effect = APIError(401, "Unauthorized") client = Client(FAKE_TEST_API_KEY, personal_api_key=FAKE_TEST_API_KEY) with self.assertLogs("posthog", level="ERROR") as logs: @@ -4266,13 +4269,15 @@ def test_disable_geoip_get_flag_capture_call(self, patch_flags, patch_capture): disable_geoip=False, ) - @mock.patch("posthog.client.MAX_DICT_SIZE", 100) @mock.patch.object(Client, "capture") @mock.patch("posthog.client.flags") def test_capture_multiple_users_doesnt_out_of_memory( self, patch_flags, patch_capture ): client = Client(FAKE_TEST_API_KEY, personal_api_key=FAKE_TEST_API_KEY) + # Set on the instance to avoid relying on module-constant patching behavior + # across Python/runtime implementations. + client.distinct_ids_feature_flags_reported.max_size = 100 client.feature_flags = [ { "id": 1,