Skip to content

Python: generated parse_rfc3339 rejects timestamps with more than 6 fractional digits #297

Open

Description

@sebxt

What happens

For an OffsetDateTime field, the Python generator emits a parse_rfc3339 validator that tries two datetime.strptime formats ending in %S.%fZ and %SZ. Python's %f accepts at most 6 digits. The time crate's RFC 3339 serializer (#[serde(with = "time::serde::rfc3339")]) writes up to 9 fractional digits, so any timestamp with nanosecond precision fails validation on the Python side.

On Linux, OffsetDateTime::now_utc() has nanosecond precision, so this is the normal case for values produced by a Rust service, not an edge case.

What should happen

A value serialized by the Rust side should validate in the generated Pydantic model. Digits beyond microsecond precision can be dropped, since datetime cannot represent them.

Minimal repro

#[typeshare]
pub struct Foo {
    #[serde(with = "time::serde::rfc3339")]
    pub time: OffsetDateTime,
}

Rust serializes datetime!(2024-05-01 12:34:56.123456789 UTC) as:

{"time":"2024-05-01T12:34:56.123456789Z"}

Feeding that to the generated model (the current core/data/tests/test_serde_iso8601/output.py):

Foo.model_validate_json('{"time":"2024-05-01T12:34:56.123456789Z"}')
# pydantic_core.ValidationError: 1 validation error for Foo
# time
#   Value error, Invalid RFC 3339 date format: 2024-05-01T12:34:56.123456789Z

"2024-05-01T12:34:56.123Z" and "2024-05-01T12:34:56Z" validate fine.

Root cause

The deserialization_content for datetime in json_translation_for_type (core/src/language/python.rs) passes the raw string to strptime with %f, which only matches 1 to 6 digits.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions