From 1751aedfa4c130ac4b8a354376574bd673f66523 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Thu, 12 Nov 2026 12:08:33 +0100 Subject: [PATCH] chore: remove mutation testing setup --- .github/workflows/ci.yml | 37 +++++-------------------------------- .gitignore | 1 - posthog/utils.py | 16 +++++++--------- pyproject.toml | 7 ------- 4 files changed, 12 insertions(+), 49 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef0ff8a61..d93383859 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -205,8 +205,8 @@ jobs: run: | pytest posthog/test/mcp --verbose --timeout=30 - mutation-tests: - name: Targeted mutation tests + utils-quality: + name: Utils quality runs-on: ubuntu-latest steps: @@ -214,7 +214,7 @@ jobs: with: fetch-depth: 0 - - name: Check targeted mutation inputs changed + - name: Check utils quality inputs changed id: changes shell: bash run: | @@ -235,11 +235,11 @@ jobs: if [[ -n "$changed_files" ]]; then echo "changed=true" >> "$GITHUB_OUTPUT" - echo "Targeted mutation inputs changed:" + echo "Utils quality inputs changed:" echo "$changed_files" else echo "changed=false" >> "$GITHUB_OUTPUT" - echo "Skipping targeted mutation tests: inputs unchanged." + echo "Skipping utils quality check: inputs unchanged." fi - name: Set up Python 3.11 @@ -263,33 +263,6 @@ jobs: UV_PROJECT_ENVIRONMENT=$pythonLocation uv run --extra test --with pytest-crap --with pytest-cov pytest posthog/test/test_utils.py posthog/test/test_size_limited_dict.py --timeout=30 --cov=posthog.utils --crap --crap-threshold=10 --crap-top-n=40 -q UV_PROJECT_ENVIRONMENT=$pythonLocation uv run --extra test --with pytest-crap --with pytest-cov python .github/scripts/check_crap_threshold.py posthog/utils.py --max-crap 10 - - name: Restore mutmut cache - id: mutmut-cache - if: steps.changes.outputs.changed == 'true' - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: mutants - key: mutmut-${{ runner.os }}-py311-${{ hashFiles('posthog/utils.py', 'posthog/test/test_utils.py', 'posthog/test/test_size_limited_dict.py') }} - restore-keys: | - mutmut-${{ runner.os }}-py311- - - - name: Skip mutation tests on exact cache hit - if: steps.changes.outputs.changed == 'true' && steps.mutmut-cache.outputs.cache-hit == 'true' - run: | - echo "Skipping targeted mutation tests: exact mutmut cache hit." - - - name: Run targeted mutation tests - if: steps.changes.outputs.changed == 'true' && steps.mutmut-cache.outputs.cache-hit != 'true' - shell: bash - run: | - set -euo pipefail - UV_PROJECT_ENVIRONMENT=$pythonLocation uv run --extra test --with mutmut mutmut run --max-children 1 - results="$(UV_PROJECT_ENVIRONMENT=$pythonLocation uv run --extra test --with mutmut mutmut results)" - if [[ -n "$results" ]]; then - echo "$results" - exit 1 - fi - import-check: name: Python ${{ matrix.python-version }} import check runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index b8e7cb9ac..4e3d70dcb 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,3 @@ pyrightconfig.json .DS_Store posthog-python-references.json .claude/settings.local.json -mutants/ diff --git a/posthog/utils.py b/posthog/utils.py index 1f36416a8..cfa508565 100644 --- a/posthog/utils.py +++ b/posthog/utils.py @@ -21,7 +21,7 @@ def is_naive(dt: datetime) -> bool: """Determines if a given datetime.datetime is naive.""" - return dt.tzinfo is None or dt.tzinfo.utcoffset(dt) is None # pragma: no mutate + return dt.tzinfo is None or dt.tzinfo.utcoffset(dt) is None def total_seconds(delta: timedelta) -> float: @@ -36,14 +36,12 @@ def guess_timezone(dt: datetime) -> datetime: # attempts to guess the datetime.datetime.now() local timezone # case, and then defaults to utc delta = total_seconds(datetime.now() - dt) - if 0 <= delta < 5: # pragma: no mutate + if 0 <= delta < 5: # this was created using datetime.datetime.now(), # so use the current system local timezone # Equivalent to converting the naive value directly because this path # only handles values created in the current local timezone. - dt = dt.replace( - tzinfo=datetime.now().astimezone().tzinfo - ) # pragma: no mutate + dt = dt.replace(tzinfo=datetime.now().astimezone().tzinfo) else: # at this point, the best we can do is guess UTC dt = dt.replace(tzinfo=timezone.utc) @@ -62,7 +60,7 @@ def _normalize_timestamp(timestamp: Union[datetime, str]) -> str: try: # Python 3.10 needs the replacements; on 3.11+ fromisoformat accepts Z # and compact UTC offsets such as +0530. - normalized_timestamp = timestamp.replace("Z", "+00:00") # pragma: no mutate + normalized_timestamp = timestamp.replace("Z", "+00:00") normalized_timestamp = re.sub( r"([+-]\d{2})(\d{2})$", r"\1:\2", normalized_timestamp ) @@ -162,7 +160,7 @@ def _coerce_unicode(cmplx: Any) -> Optional[str]: item = None try: if isinstance(cmplx, bytes): - item = cmplx.decode("utf-8", "strict") # pragma: no mutate + item = cmplx.decode("utf-8", "strict") elif isinstance(cmplx, str): item = cmplx except Exception as exception: @@ -569,7 +567,7 @@ def invalidate_version(self, old_version): self._delete_keys_with_version(keys, old_version) if cursor == 0: - break # pragma: no mutate + break except Exception: # Redis error - silently fail @@ -641,7 +639,7 @@ def clear(self): if keys: self.redis.delete(*keys) if cursor == 0: - break # pragma: no mutate + break except Exception: # Redis error - silently fail pass diff --git a/pyproject.toml b/pyproject.toml index 0829a5833..b0e3b164f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -173,13 +173,6 @@ asyncio_default_fixture_loop_scope = "function" testpaths = ["posthog/test"] norecursedirs = ["integration_tests"] -[tool.mutmut] -paths_to_mutate = ["posthog/utils.py"] -do_not_mutate = ["posthog/test/*"] -tests_dir = ["posthog/test/test_utils.py", "posthog/test/test_size_limited_dict.py"] -also_copy = ["posthog"] -pytest_add_cli_args = ["--timeout=30"] - [dependency-groups] dev = [ "claude-agent-sdk>=0.1.50",