From b23f102d9a4a6f1fbbe1d6faacca7ae8d4cdec00 Mon Sep 17 00:00:00 2001 From: Dustin Byrne Date: Mon, 6 Apr 2026 11:49:41 -0400 Subject: [PATCH 1/4] fix: propagate missing params in module-level wrappers Propagate distinct_id for group_identify and flag_keys_to_evaluate for get_all_flags/get_all_flags_and_payloads through the module-level wrapper functions in posthog/__init__.py. These parameters were accepted by Client methods but not forwarded by the convenience wrappers, making them inaccessible when using the posthog.group_identify() etc. module-level API. --- posthog/__init__.py | 7 +++++ posthog/test/test_module.py | 63 +++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/posthog/__init__.py b/posthog/__init__.py index 18995d7d..f20adf01 100644 --- a/posthog/__init__.py +++ b/posthog/__init__.py @@ -391,6 +391,7 @@ def group_identify( timestamp=None, # type: Optional[datetime.datetime] uuid=None, # type: Optional[str] disable_geoip=None, # type: Optional[bool] + distinct_id=None, # type: Optional[str] ): # type: (...) -> Optional[str] """ @@ -403,6 +404,7 @@ def group_identify( timestamp: Optional timestamp for the event uuid: Optional UUID for the event disable_geoip: Whether to disable GeoIP lookup + distinct_id: Optional distinct ID of the user performing the action Examples: ```python @@ -425,6 +427,7 @@ def group_identify( timestamp=timestamp, uuid=uuid, disable_geoip=disable_geoip, + distinct_id=distinct_id, ) @@ -611,6 +614,7 @@ def get_all_flags( only_evaluate_locally=False, # type: bool disable_geoip=None, # type: Optional[bool] device_id=None, # type: Optional[str] + flag_keys_to_evaluate=None, # type: Optional[list[str]] ) -> Optional[dict[str, FeatureFlag]]: """ Get all flags for a given user. @@ -644,6 +648,7 @@ def get_all_flags( only_evaluate_locally=only_evaluate_locally, disable_geoip=disable_geoip, device_id=device_id, + flag_keys_to_evaluate=flag_keys_to_evaluate, ) @@ -747,6 +752,7 @@ def get_all_flags_and_payloads( only_evaluate_locally=False, disable_geoip=None, # type: Optional[bool] device_id=None, # type: Optional[str] + flag_keys_to_evaluate=None, # type: Optional[list[str]] ) -> FlagsAndPayloads: return _proxy( "get_all_flags_and_payloads", @@ -757,6 +763,7 @@ def get_all_flags_and_payloads( only_evaluate_locally=only_evaluate_locally, disable_geoip=disable_geoip, device_id=device_id, + flag_keys_to_evaluate=flag_keys_to_evaluate, ) diff --git a/posthog/test/test_module.py b/posthog/test/test_module.py index 79ed66c9..ffbd6d33 100644 --- a/posthog/test/test_module.py +++ b/posthog/test/test_module.py @@ -1,5 +1,7 @@ import unittest +from unittest import mock +import posthog from posthog import Posthog @@ -30,3 +32,64 @@ def test_alias(self): def test_flush(self): self.posthog.flush() + + +class TestModuleLevelWrappers(unittest.TestCase): + """Test that module-level wrapper functions in posthog/__init__.py + correctly propagate all parameters to the Client methods.""" + + def setUp(self): + self.mock_client = mock.MagicMock() + self._original_client = posthog.default_client + posthog.default_client = self.mock_client + + def tearDown(self): + posthog.default_client = self._original_client + + def test_group_identify_propagates_distinct_id(self): + posthog.group_identify( + "company", + "company_123", + {"name": "Awesome Inc."}, + distinct_id="user_456", + ) + self.mock_client.group_identify.assert_called_once_with( + group_type="company", + group_key="company_123", + properties={"name": "Awesome Inc."}, + timestamp=None, + uuid=None, + disable_geoip=None, + distinct_id="user_456", + ) + + def test_group_identify_distinct_id_defaults_to_none(self): + posthog.group_identify("company", "company_123") + call_kwargs = self.mock_client.group_identify.call_args[1] + self.assertIsNone(call_kwargs["distinct_id"]) + + def test_get_all_flags_propagates_flag_keys_to_evaluate(self): + posthog.get_all_flags( + "user_123", + flag_keys_to_evaluate=["flag-1", "flag-2"], + ) + call_kwargs = self.mock_client.get_all_flags.call_args[1] + self.assertEqual(call_kwargs["flag_keys_to_evaluate"], ["flag-1", "flag-2"]) + + def test_get_all_flags_flag_keys_defaults_to_none(self): + posthog.get_all_flags("user_123") + call_kwargs = self.mock_client.get_all_flags.call_args[1] + self.assertIsNone(call_kwargs["flag_keys_to_evaluate"]) + + def test_get_all_flags_and_payloads_propagates_flag_keys_to_evaluate(self): + posthog.get_all_flags_and_payloads( + "user_123", + flag_keys_to_evaluate=["flag-1", "flag-2"], + ) + call_kwargs = self.mock_client.get_all_flags_and_payloads.call_args[1] + self.assertEqual(call_kwargs["flag_keys_to_evaluate"], ["flag-1", "flag-2"]) + + def test_get_all_flags_and_payloads_flag_keys_defaults_to_none(self): + posthog.get_all_flags_and_payloads("user_123") + call_kwargs = self.mock_client.get_all_flags_and_payloads.call_args[1] + self.assertIsNone(call_kwargs["flag_keys_to_evaluate"]) From b590aa8c7251b8c7952a5860e51e79d977cd728d Mon Sep 17 00:00:00 2001 From: Dustin Byrne Date: Mon, 6 Apr 2026 11:52:27 -0400 Subject: [PATCH 2/4] docs: add flag_keys_to_evaluate to get_all_flags docstring --- posthog/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/posthog/__init__.py b/posthog/__init__.py index f20adf01..b8489185 100644 --- a/posthog/__init__.py +++ b/posthog/__init__.py @@ -626,6 +626,7 @@ def get_all_flags( group_properties: Group properties only_evaluate_locally: Whether to evaluate only locally disable_geoip: Whether to disable GeoIP lookup + flag_keys_to_evaluate: Optional list of flag keys to evaluate (evaluates all if None) Details: Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False. From 232dad5edd66c12abc6663be5dbe1cf6ec750de7 Mon Sep 17 00:00:00 2001 From: Dustin Byrne Date: Tue, 7 Apr 2026 10:20:09 -0400 Subject: [PATCH 3/4] test: parameterize flag_keys_to_evaluate tests in test_module --- posthog/test/test_module.py | 44 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/posthog/test/test_module.py b/posthog/test/test_module.py index ffbd6d33..03bce00b 100644 --- a/posthog/test/test_module.py +++ b/posthog/test/test_module.py @@ -1,6 +1,8 @@ import unittest from unittest import mock +from parameterized import parameterized + import posthog from posthog import Posthog @@ -68,28 +70,26 @@ def test_group_identify_distinct_id_defaults_to_none(self): call_kwargs = self.mock_client.group_identify.call_args[1] self.assertIsNone(call_kwargs["distinct_id"]) - def test_get_all_flags_propagates_flag_keys_to_evaluate(self): - posthog.get_all_flags( - "user_123", - flag_keys_to_evaluate=["flag-1", "flag-2"], - ) - call_kwargs = self.mock_client.get_all_flags.call_args[1] - self.assertEqual(call_kwargs["flag_keys_to_evaluate"], ["flag-1", "flag-2"]) - - def test_get_all_flags_flag_keys_defaults_to_none(self): - posthog.get_all_flags("user_123") - call_kwargs = self.mock_client.get_all_flags.call_args[1] - self.assertIsNone(call_kwargs["flag_keys_to_evaluate"]) - - def test_get_all_flags_and_payloads_propagates_flag_keys_to_evaluate(self): - posthog.get_all_flags_and_payloads( - "user_123", - flag_keys_to_evaluate=["flag-1", "flag-2"], - ) - call_kwargs = self.mock_client.get_all_flags_and_payloads.call_args[1] + @parameterized.expand( + [ + ("get_all_flags", "get_all_flags"), + ("get_all_flags_and_payloads", "get_all_flags_and_payloads"), + ] + ) + def test_flag_keys_to_evaluate_propagated(self, _name, method_name): + fn = getattr(posthog, method_name) + fn("user_123", flag_keys_to_evaluate=["flag-1", "flag-2"]) + call_kwargs = getattr(self.mock_client, method_name).call_args[1] self.assertEqual(call_kwargs["flag_keys_to_evaluate"], ["flag-1", "flag-2"]) - def test_get_all_flags_and_payloads_flag_keys_defaults_to_none(self): - posthog.get_all_flags_and_payloads("user_123") - call_kwargs = self.mock_client.get_all_flags_and_payloads.call_args[1] + @parameterized.expand( + [ + ("get_all_flags", "get_all_flags"), + ("get_all_flags_and_payloads", "get_all_flags_and_payloads"), + ] + ) + def test_flag_keys_to_evaluate_defaults_to_none(self, _name, method_name): + fn = getattr(posthog, method_name) + fn("user_123") + call_kwargs = getattr(self.mock_client, method_name).call_args[1] self.assertIsNone(call_kwargs["flag_keys_to_evaluate"]) From 2da0ddad13b644969c5853f4dcea1c8231dd8a20 Mon Sep 17 00:00:00 2001 From: Dustin Byrne Date: Tue, 7 Apr 2026 12:48:21 -0400 Subject: [PATCH 4/4] chore: add changeset --- .../changesets/propagate-missing-params-module-wrappers.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .sampo/changesets/propagate-missing-params-module-wrappers.md diff --git a/.sampo/changesets/propagate-missing-params-module-wrappers.md b/.sampo/changesets/propagate-missing-params-module-wrappers.md new file mode 100644 index 00000000..1112c6a9 --- /dev/null +++ b/.sampo/changesets/propagate-missing-params-module-wrappers.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +fix: propagate missing params in module-level wrapper functions (`distinct_id` for `group_identify`, `flag_keys_to_evaluate` for `get_all_flags`/`get_all_flags_and_payloads`)