Skip to content

Return InvalidDateTime for invalid protobuf timestamps #276

Description

@llucax

Problem

frequenz.client.common.proto.datetime_from_proto() currently calls datetime.fromtimestamp(). A protobuf Timestamp can carry a value that Python cannot represent, causing conversion to raise instead of preserving the received data in the return type.

For example:

from google.protobuf.timestamp_pb2 import Timestamp

from frequenz.client.common.proto import datetime_from_proto

datetime_from_proto(Timestamp(seconds=253402300800))
# ValueError: year 10000 is out of range

This exception also escapes higher-level converters such as metric_sample_from_proto(), contrary to the goal of representing malformed wire data explicitly.

Proposed change

  • Add a protobuf-independent InvalidDateTime wrapper that preserves the raw timestamp data needed for inspection.
  • Add a datetime_from_proto2() if datetime_from_proto() was already released that returns datetime | InvalidDateTime instead of raising for invalid or unrepresentable protobuf timestamps. Change the current function instead if it is unreleased.
  • Propagate the union through all wrappers and converters that use datetime_from_proto/2(), including metric samples, microgrids, and lifetimes.
  • Add semantic accessors and a package-specific error where callers commonly require a valid datetime, following the existing invalid-field pattern.
  • Handle the public API change according to the project's 0.x compatibility policy.

Tests

Cover at least:

  • valid timestamps, including timezone behavior;
  • the minimum and maximum values representable by both protobuf and Python;
  • values outside Python's datetime range;
  • invalid seconds/nanoseconds combinations accepted from decoded wire data;
  • higher-level converters preserving InvalidDateTime instead of raising;
  • safe accessors returning valid values and raising typed errors for invalid ones.

Downstream migration

Find downstream users of datetime_from_proto() and affected wrapper datetime fields, update their annotations and exhaustive handling, and document the migration in the release notes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:enhancementNew feature or enhancement visitble to users

    Fields

    Priority

    High

    Effort

    Medium

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions