Skip to content

fix: remove python-dateutil runtime dependency#540

Merged
marandaneto merged 5 commits intomainfrom
fix/drop-python-dateutil-runtime-dependency
Apr 28, 2026
Merged

fix: remove python-dateutil runtime dependency#540
marandaneto merged 5 commits intomainfrom
fix/drop-python-dateutil-runtime-dependency

Conversation

@marandaneto
Copy link
Copy Markdown
Member

@marandaneto marandaneto commented Apr 28, 2026

💡 Motivation and Context

Fixes #109.

python-dateutil was a runtime dependency of the SDK, and older supported dependency resolutions can emit Python 3.12+ deprecation warnings on import. The SDK only used a small subset of dateutil behavior, so this removes it from runtime dependencies while keeping compatibility covered in tests.

💚 How did you test it?

  • uv run ruff check posthog sdk_compliance_adapter
  • uv run pytest -q
  • uv run mypy --no-site-packages --config-file mypy.ini . | uv run mypy-baseline filter
  • uv run python -W error::DeprecationWarning -c 'import posthog'

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran sampo add to generate a changeset file
  • Added the release label to the PR

@marandaneto marandaneto requested a review from a team as a code owner April 28, 2026 13:43
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 28, 2026

Prompt To Fix All With AI
This is a comment left during a code review.
Path: posthog/feature_flags.py
Line: 777-787

Comment:
**`fromisoformat` rejects space-separated timezone offsets on Python 3.10**

`datetime.fromisoformat` on Python 3.10 does not accept a space between the time and the UTC-offset (e.g. `"2022-04-05 12:34:12 +01:00"`), raising a `ValueError`. Python 3.11 expanded `fromisoformat` to accept most ISO 8601 forms, but since `requires-python = ">=3.10"`, any property value string in that format will fail on 3.10 where `dateutil.parser.parse` previously succeeded. The test `test_parse_datetime_matches_dateutil_for_supported_formats` itself includes this exact case, so it will only pass on 3.11+. A simple normalisation before calling `fromisoformat` would cover it:

```python
def parse_datetime(value: str) -> datetime.datetime:
    text = value.strip()
    if text.endswith("Z"):
        text = text[:-1] + "+00:00"
    elif text.upper().endswith(" UTC"):
        text = text[:-4] + "+00:00"
    elif re.fullmatch(r"\d{4}", text):
        now = datetime.datetime.now()
        return datetime.datetime(int(text), now.month, now.day)
    # Normalise "... +HH:MM" (space before offset) accepted by dateutil but not
    # by fromisoformat on Python < 3.11.
    text = re.sub(r" ([+-]\d{2}:\d{2})$", r"\1", text)
    return datetime.datetime.fromisoformat(text)
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: posthog/test/test_feature_flags.py
Line: 4582-4589

Comment:
**Prefer parameterised test**

Per the project's simplicity rules, parameterised tests are preferred. The loop over a tuple of strings is equivalent to a parameterised test but hides failures behind a single test name and stops on the first failure, making it harder to diagnose which format broke.

```python
@parameterized.expand([
    ("iso_date", "2022-05-01"),
    ("iso_datetime_Z", "2022-04-05T12:34:12Z"),
    ("iso_datetime_utc", "2022-04-05 12:34:12 UTC"),
    ("iso_datetime_offset", "2022-04-05 12:34:12 +01:00"),
])
def test_parse_datetime_matches_dateutil_for_supported_formats(self, _name, value):
    assert parse_datetime(value) == parser.parse(value)
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix: remove python-dateutil runtime depe..." | Re-trigger Greptile

Comment thread posthog/feature_flags.py
Comment thread posthog/test/test_feature_flags.py Outdated
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 28, 2026

posthog-python Compliance Report

Date: 2026-04-28 14:46:23 UTC
Duration: 159947ms

✅ All Tests Passed!

30/30 tests passed


Capture Tests

29/29 tests passed

View Details
Test Status Duration
Format Validation.Event Has Required Fields 515ms
Format Validation.Event Has Uuid 1505ms
Format Validation.Event Has Lib Properties 1505ms
Format Validation.Distinct Id Is String 1505ms
Format Validation.Token Is Present 1505ms
Format Validation.Custom Properties Preserved 1505ms
Format Validation.Event Has Timestamp 1505ms
Retry Behavior.Retries On 503 9511ms
Retry Behavior.Does Not Retry On 400 3508ms
Retry Behavior.Does Not Retry On 401 3506ms
Retry Behavior.Respects Retry After Header 9512ms
Retry Behavior.Implements Backoff 23520ms
Retry Behavior.Retries On 500 7506ms
Retry Behavior.Retries On 502 7509ms
Retry Behavior.Retries On 504 7505ms
Retry Behavior.Max Retries Respected 23529ms
Deduplication.Generates Unique Uuids 1494ms
Deduplication.Preserves Uuid On Retry 7513ms
Deduplication.Preserves Uuid And Timestamp On Retry 14517ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry 7506ms
Deduplication.No Duplicate Events In Batch 1501ms
Deduplication.Different Events Have Different Uuids 1505ms
Compression.Sends Gzip When Enabled 1506ms
Batch Format.Uses Proper Batch Structure 1504ms
Batch Format.Flush With No Events Sends Nothing 1004ms
Batch Format.Multiple Events Batched Together 1503ms
Error Handling.Does Not Retry On 403 3508ms
Error Handling.Does Not Retry On 413 3505ms
Error Handling.Retries On 408 7511ms

Feature_Flags Tests

1/1 tests passed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id 512ms

Copy link
Copy Markdown
Contributor

@dustinbyrne dustinbyrne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor comment + greptile review looks legit

Comment thread posthog/feature_flags.py
@marandaneto marandaneto merged commit dea848f into main Apr 28, 2026
26 checks passed
@marandaneto marandaneto deleted the fix/drop-python-dateutil-runtime-dependency branch April 28, 2026 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Drop "python-dateutil" dependency (Python 3.12 compatibility)

2 participants