Merge branch 'master_gh'

This commit is contained in:
Georg K 2023-05-05 03:27:56 +03:00
commit 37e53fce85
5 changed files with 99 additions and 2 deletions

View File

@ -374,10 +374,10 @@ when calling the protobuf compiler:
``` ```
protoc -I . --custom_opt=pydantic_dataclasses --python_betterproto_out=lib example.proto protoc -I . --python_betterproto_opt=pydantic_dataclasses --python_betterproto_out=lib example.proto
``` ```
With the important change being `--custom_opt=pydantic_dataclasses`. This will With the important change being `--python_betterproto_opt=pydantic_dataclasses`. This will
swap the dataclass implementation from the builtin python dataclass to the swap the dataclass implementation from the builtin python dataclass to the
pydantic dataclass. You must have pydantic as a dependency in your project for pydantic dataclass. You must have pydantic as a dependency in your project for
this to work. this to work.

View File

@ -1587,6 +1587,9 @@ class _Timestamp(Timestamp):
@staticmethod @staticmethod
def timestamp_to_json(dt: datetime) -> str: def timestamp_to_json(dt: datetime) -> str:
nanos = dt.microsecond * 1e3 nanos = dt.microsecond * 1e3
if dt.tzinfo is not None:
# change timezone aware datetime objects to utc
dt = dt.astimezone(timezone.utc)
copy = dt.replace(microsecond=0, tzinfo=None) copy = dt.replace(microsecond=0, tzinfo=None)
result = copy.isoformat() result = copy.isoformat()
if (nanos % 1e9) == 0: if (nanos % 1e9) == 0:

View File

@ -0,0 +1,82 @@
from datetime import (
datetime,
timedelta,
timezone,
)
import pytest
from tests.output_betterproto.timestamp_dict_encode import Test
# Current World Timezone range (UTC-12 to UTC+14)
MIN_UTC_OFFSET_MIN = -12 * 60
MAX_UTC_OFFSET_MIN = 14 * 60
# Generate all timezones in range in 15 min increments
timezones = [
timezone(timedelta(minutes=x))
for x in range(MIN_UTC_OFFSET_MIN, MAX_UTC_OFFSET_MIN + 1, 15)
]
@pytest.mark.parametrize("tz", timezones)
def test_timezone_aware_datetime_dict_encode(tz: timezone):
original_time = datetime.now(tz=tz)
original_message = Test()
original_message.ts = original_time
encoded = original_message.to_dict()
decoded_message = Test()
decoded_message.from_dict(encoded)
# check that the timestamps are equal after decoding from dict
assert original_message.ts.tzinfo is not None
assert decoded_message.ts.tzinfo is not None
assert original_message.ts == decoded_message.ts
def test_naive_datetime_dict_encode():
# make suer naive datetime objects are still treated as utc
original_time = datetime.now()
assert original_time.tzinfo is None
original_message = Test()
original_message.ts = original_time
original_time_utc = original_time.replace(tzinfo=timezone.utc)
encoded = original_message.to_dict()
decoded_message = Test()
decoded_message.from_dict(encoded)
# check that the timestamps are equal after decoding from dict
assert decoded_message.ts.tzinfo is not None
assert original_time_utc == decoded_message.ts
@pytest.mark.parametrize("tz", timezones)
def test_timezone_aware_json_serialize(tz: timezone):
original_time = datetime.now(tz=tz)
original_message = Test()
original_message.ts = original_time
json_serialized = original_message.to_json()
decoded_message = Test()
decoded_message.from_json(json_serialized)
# check that the timestamps are equal after decoding from dict
assert original_message.ts.tzinfo is not None
assert decoded_message.ts.tzinfo is not None
assert original_message.ts == decoded_message.ts
def test_naive_datetime_json_serialize():
# make suer naive datetime objects are still treated as utc
original_time = datetime.now()
assert original_time.tzinfo is None
original_message = Test()
original_message.ts = original_time
original_time_utc = original_time.replace(tzinfo=timezone.utc)
json_serialized = original_message.to_json()
decoded_message = Test()
decoded_message.from_json(json_serialized)
# check that the timestamps are equal after decoding from dict
assert decoded_message.ts.tzinfo is not None
assert original_time_utc == decoded_message.ts

View File

@ -0,0 +1,3 @@
{
"ts" : "2023-03-15T22:35:51.253277Z"
}

View File

@ -0,0 +1,9 @@
syntax = "proto3";
package timestamp_dict_encode;
import "google/protobuf/timestamp.proto";
message Test {
google.protobuf.Timestamp ts = 1;
}