From dfe2698c2b4182fa4044d3a108a9e8ce34fba920 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Thu, 18 Jun 2026 11:03:05 +0200 Subject: [PATCH 1/5] fix: ignore version value in public API snapshot --- .github/scripts/check_public_api.py | 2 ++ references/public_api_snapshot.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/scripts/check_public_api.py b/.github/scripts/check_public_api.py index 7b276890..474b89e7 100644 --- a/.github/scripts/check_public_api.py +++ b/.github/scripts/check_public_api.py @@ -19,6 +19,7 @@ SNAPSHOT_PATH = ROOT / "references" / "public_api_snapshot.txt" PUBLIC_SPECIAL_NAMES = {"__version__"} EXCLUDED_MODULE_PREFIXES = ("posthog.test",) +ATTRIBUTE_VALUE_PLACEHOLDERS = {"posthog.version.VERSION": ""} HEADER = """# This file is generated by .github/scripts/check_public_api.py. # Run `make public_api_snapshot` after an intentional public API change. @@ -142,6 +143,7 @@ def _attribute_details(obj: object) -> str: value = getattr(obj, "value", None) if value is not None: + value = ATTRIBUTE_VALUE_PLACEHOLDERS.get(_object_path(obj), value) parts.append(f" = {value}") return "".join(parts) diff --git a/references/public_api_snapshot.txt b/references/public_api_snapshot.txt index e6645985..2ba8a253 100644 --- a/references/public_api_snapshot.txt +++ b/references/public_api_snapshot.txt @@ -685,7 +685,7 @@ attribute posthog.utils.RedisFlagCache.stale_ttl = stale_ttl attribute posthog.utils.RedisFlagCache.version_key = f'{key_prefix}version' attribute posthog.utils.SizeLimitedDict.max_size = max_size attribute posthog.utils.log = logging.getLogger('posthog') -attribute posthog.version.VERSION = '7.19.1' +attribute posthog.version.VERSION = class posthog.Posthog class posthog.ai.anthropic.anthropic.Anthropic(posthog_client: Optional[PostHogClient] = None, **kwargs) class posthog.ai.anthropic.anthropic.WrappedMessages From 82e11fa932e5a3486051baf5f6acd2f14b08b94d Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Thu, 18 Jun 2026 13:13:35 +0200 Subject: [PATCH 2/5] test: cover public API version placeholder --- posthog/test/test_public_api_snapshot.py | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 posthog/test/test_public_api_snapshot.py diff --git a/posthog/test/test_public_api_snapshot.py b/posthog/test/test_public_api_snapshot.py new file mode 100644 index 00000000..0ed8e67e --- /dev/null +++ b/posthog/test/test_public_api_snapshot.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +import importlib.util +from pathlib import Path +from types import SimpleNamespace + +import pytest + + +ROOT = Path(__file__).resolve().parents[2] +CHECK_PUBLIC_API_PATH = ROOT / ".github" / "scripts" / "check_public_api.py" + + +def load_check_public_api(): + spec = importlib.util.spec_from_file_location( + "check_public_api", CHECK_PUBLIC_API_PATH + ) + assert spec is not None + assert spec.loader is not None + + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +check_public_api = load_check_public_api() + + +@pytest.mark.parametrize( + ("path", "placeholder"), + check_public_api.ATTRIBUTE_VALUE_PLACEHOLDERS.items(), +) +def test_attribute_details_uses_placeholder_values(path, placeholder): + obj = SimpleNamespace(path=path, annotation=None, value='"7.19.1"') + + assert check_public_api._attribute_details(obj) == f"{path} = {placeholder}" From b68fc26ea30c81b0c1ad83e11eac90a8452334a7 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Thu, 18 Jun 2026 13:15:27 +0200 Subject: [PATCH 3/5] fix: avoid griffe import during test collection --- .github/scripts/check_public_api.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/scripts/check_public_api.py b/.github/scripts/check_public_api.py index 474b89e7..702abf17 100644 --- a/.github/scripts/check_public_api.py +++ b/.github/scripts/check_public_api.py @@ -9,12 +9,6 @@ from pathlib import Path from typing import Iterable -try: - import griffe -except ImportError: # pragma: no cover - exercised only when dependencies are missing. - print("griffe is required; install dev dependencies first.", file=sys.stderr) - raise - ROOT = Path(__file__).resolve().parents[2] SNAPSHOT_PATH = ROOT / "references" / "public_api_snapshot.txt" PUBLIC_SPECIAL_NAMES = {"__version__"} @@ -209,7 +203,17 @@ def _iter_module_members(module: object) -> Iterable[object]: yield from _iter_class_members(member) +def _load_griffe(): + try: + import griffe + except ImportError: # pragma: no cover + print("griffe is required; install dev dependencies first.", file=sys.stderr) + raise + return griffe + + def generate_snapshot() -> str: + griffe = _load_griffe() package = griffe.load( "posthog", allow_inspection=False, From f2aec3a2148c1bdfe697a3f97146b708275e146e Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Thu, 18 Jun 2026 13:42:41 +0200 Subject: [PATCH 4/5] test: move public API script test out of package suite --- .github/scripts/test_check_public_api.py | 39 ++++++++++++++++++++++++ .github/workflows/ci.yml | 1 + posthog/test/test_public_api_snapshot.py | 36 ---------------------- 3 files changed, 40 insertions(+), 36 deletions(-) create mode 100644 .github/scripts/test_check_public_api.py delete mode 100644 posthog/test/test_public_api_snapshot.py diff --git a/.github/scripts/test_check_public_api.py b/.github/scripts/test_check_public_api.py new file mode 100644 index 00000000..6fade7b4 --- /dev/null +++ b/.github/scripts/test_check_public_api.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +"""Tests for check_public_api.py.""" + +from __future__ import annotations + +import importlib.util +from pathlib import Path +from types import SimpleNamespace + + +SCRIPT_PATH = Path(__file__).with_name("check_public_api.py") + + +def load_check_public_api(): + spec = importlib.util.spec_from_file_location("check_public_api", SCRIPT_PATH) + assert spec is not None + assert spec.loader is not None + + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +def test_attribute_details_uses_placeholder_values() -> None: + check_public_api = load_check_public_api() + + for path, placeholder in check_public_api.ATTRIBUTE_VALUE_PLACEHOLDERS.items(): + obj = SimpleNamespace(path=path, annotation=None, value='"7.19.1"') + assert check_public_api._attribute_details(obj) == f"{path} = {placeholder}" + + +def main() -> int: + test_attribute_details_uses_placeholder_values() + print("check_public_api tests passed.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5fccec51..4b3f5e6c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,6 +74,7 @@ jobs: - name: Check public API snapshot run: | + python .github/scripts/test_check_public_api.py make public_api_check package-build: diff --git a/posthog/test/test_public_api_snapshot.py b/posthog/test/test_public_api_snapshot.py deleted file mode 100644 index 0ed8e67e..00000000 --- a/posthog/test/test_public_api_snapshot.py +++ /dev/null @@ -1,36 +0,0 @@ -from __future__ import annotations - -import importlib.util -from pathlib import Path -from types import SimpleNamespace - -import pytest - - -ROOT = Path(__file__).resolve().parents[2] -CHECK_PUBLIC_API_PATH = ROOT / ".github" / "scripts" / "check_public_api.py" - - -def load_check_public_api(): - spec = importlib.util.spec_from_file_location( - "check_public_api", CHECK_PUBLIC_API_PATH - ) - assert spec is not None - assert spec.loader is not None - - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - return module - - -check_public_api = load_check_public_api() - - -@pytest.mark.parametrize( - ("path", "placeholder"), - check_public_api.ATTRIBUTE_VALUE_PLACEHOLDERS.items(), -) -def test_attribute_details_uses_placeholder_values(path, placeholder): - obj = SimpleNamespace(path=path, annotation=None, value='"7.19.1"') - - assert check_public_api._attribute_details(obj) == f"{path} = {placeholder}" From 45b5445af9f35a5a6a17e88c60fa65d6ba497b02 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Thu, 18 Jun 2026 14:02:07 +0200 Subject: [PATCH 5/5] test: disable client atexit joins during tests --- posthog/test/conftest.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 posthog/test/conftest.py diff --git a/posthog/test/conftest.py b/posthog/test/conftest.py new file mode 100644 index 00000000..1aa9d03f --- /dev/null +++ b/posthog/test/conftest.py @@ -0,0 +1,10 @@ +from __future__ import annotations + +import pytest + +import posthog.client as client_module + + +@pytest.fixture(autouse=True) +def disable_client_atexit_join(monkeypatch): + monkeypatch.setattr(client_module.atexit, "register", lambda *args, **kwargs: None)