Skip to content

feat: replace python-dateutil with stdlib datetime.fromisoformat#1429

Open
splch wants to merge 1 commit intoopenapi-generators:mainfrom
splch:drop-python-dateutil
Open

feat: replace python-dateutil with stdlib datetime.fromisoformat#1429
splch wants to merge 1 commit intoopenapi-generators:mainfrom
splch:drop-python-dateutil

Conversation

@splch
Copy link
Copy Markdown

@splch splch commented Apr 24, 2026

Summary

Drop the python-dateutil dependency from both the generator and all generated client packages. Date/datetime parsing now uses Python's built-in datetime.fromisoformat() instead of dateutil.parser.isoparse().

This removes one runtime dependency from every generated client, reducing install size and eliminating a dependency that is unmaintained upstream and being deprecated by Fedora 45 (no releases since March 2024).

Changes

Generator source (openapi_python_client/parser/properties/):

  • datetime.py: Validate defaults with datetime.datetime.fromisoformat() instead of isoparse(). Normalize Z to +00:00 at generation time so the emitted Python code is clean.
  • date.py: Validate defaults with datetime.date.fromisoformat() instead of isoparse().date().
  • Both: Remove "from dateutil.parser import isoparse" from the import set returned by get_imports().

Jinja templates (openapi_python_client/templates/property_templates/):

  • datetime_property.py.jinja: isoparse(x) -> datetime.datetime.fromisoformat(x.replace("Z", "+00:00"))
  • date_property.py.jinja: isoparse(x).date() -> datetime.date.fromisoformat(x)

Dependency removal (all 4 metadata formats):

  • pyproject_uv.toml.jinja, pyproject_poetry.toml.jinja, pyproject_pdm.toml.jinja, setup.py.jinja: Remove python-dateutil from generated dependencies.
  • pyproject.toml (generator): Remove python-dateutil from runtime deps and types-python-dateutil from dev deps.
  • integration-tests/pyproject.toml: Remove both as well.

Tests & golden records: All regenerated. Unit tests pass (283 passed, 4 skipped).

Python 3.10 compatibility

datetime.fromisoformat() gained full ISO 8601 support (including the Z suffix) in Python 3.11. On Python 3.10, the Z suffix raises a ValueError:

# Python 3.10
>>> datetime.datetime.fromisoformat("2024-01-15T10:30:00Z")
ValueError: Invalid isoformat string: '2024-01-15T10:30:00Z'

>>> datetime.datetime.fromisoformat("2024-01-15T10:30:00+00:00")
datetime.datetime(2024, 1, 15, 10, 30, tzinfo=datetime.timezone.utc)  # works
# Python 3.11+
>>> datetime.datetime.fromisoformat("2024-01-15T10:30:00Z")
datetime.datetime(2024, 1, 15, 10, 30, tzinfo=datetime.timezone.utc)  # works natively

The generated datetime parsing code uses .replace("Z", "+00:00") to normalize Z to an explicit UTC offset before calling fromisoformat(), which works on both 3.10 and 3.11+. This is a no-op on strings without Z. Date parsing does not need this since date strings have no timezone component.

Default values in OpenAPI specs are normalized at generation time (Z -> +00:00), so the emitted default expressions are clean datetime.datetime.fromisoformat("...") calls.

Drop the python-dateutil dependency from both the generator and all
generated client code. Date/datetime parsing now uses the stdlib:

- datetime fields: datetime.datetime.fromisoformat(v.replace("Z", "+00:00"))
- date fields: datetime.date.fromisoformat(v)

The .replace("Z", "+00:00") call is needed because Python 3.10's
fromisoformat() does not accept the Z timezone suffix (added in 3.11).
It is a no-op on strings that do not contain Z.

Default values in OpenAPI specs are normalized at generation time
(Z replaced with +00:00), so the generated default expressions are
clean datetime.datetime.fromisoformat("...") calls without the
replace.

This removes one runtime dependency from every generated client
package, reducing install size and eliminating a dependency that is
in maintenance-only mode upstream.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant