parent
c82816b8be
commit
e3b44f491f
@ -62,9 +62,13 @@ help = "Run tests"
|
|||||||
cmd = "mypy src --ignore-missing-imports"
|
cmd = "mypy src --ignore-missing-imports"
|
||||||
help = "Check types with mypy"
|
help = "Check types with mypy"
|
||||||
|
|
||||||
|
[tool.poe.tasks]
|
||||||
|
_black = "black . --exclude tests/output_ --target-version py310"
|
||||||
|
_isort = "isort . --extend-skip-glob 'tests/output_*/**/*'"
|
||||||
|
|
||||||
[tool.poe.tasks.format]
|
[tool.poe.tasks.format]
|
||||||
cmd = "black . --exclude tests/output_ --target-version py310"
|
sequence = ["_black", "_isort"]
|
||||||
help = "Apply black formatting to source code"
|
help = "Apply black and isort formatting to source code"
|
||||||
|
|
||||||
[tool.poe.tasks.docs]
|
[tool.poe.tasks.docs]
|
||||||
cmd = "sphinx-build docs docs/build"
|
cmd = "sphinx-build docs docs/build"
|
||||||
|
@ -1868,13 +1868,15 @@ class _Duration(Duration):
|
|||||||
class _Timestamp(Timestamp):
|
class _Timestamp(Timestamp):
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_datetime(cls, dt: datetime) -> "_Timestamp":
|
def from_datetime(cls, dt: datetime) -> "_Timestamp":
|
||||||
seconds = int(dt.timestamp())
|
# apparently 0 isn't a year in [0, 9999]??
|
||||||
|
seconds = int((dt - DATETIME_ZERO).total_seconds())
|
||||||
nanos = int(dt.microsecond * 1e3)
|
nanos = int(dt.microsecond * 1e3)
|
||||||
return cls(seconds, nanos)
|
return cls(seconds, nanos)
|
||||||
|
|
||||||
def to_datetime(self) -> datetime:
|
def to_datetime(self) -> datetime:
|
||||||
ts = self.seconds + (self.nanos / 1e9)
|
ts = self.seconds + (self.nanos / 1e9)
|
||||||
return datetime.fromtimestamp(ts, tz=timezone.utc)
|
# if datetime.fromtimestamp ever supports -62135596800 use that instead see #407
|
||||||
|
return DATETIME_ZERO + timedelta(seconds=ts)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def timestamp_to_json(dt: datetime) -> str:
|
def timestamp_to_json(dt: datetime) -> str:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
package google_impl_behavior_equivalence;
|
package google_impl_behavior_equivalence;
|
||||||
|
|
||||||
message Foo { int64 bar = 1; }
|
message Foo { int64 bar = 1; }
|
||||||
@ -12,6 +13,10 @@ message Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Spam {
|
||||||
|
google.protobuf.Timestamp ts = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message Request { Empty foo = 1; }
|
message Request { Empty foo = 1; }
|
||||||
|
|
||||||
message Empty {}
|
message Empty {}
|
||||||
|
@ -1,17 +1,25 @@
|
|||||||
|
from datetime import (
|
||||||
|
datetime,
|
||||||
|
timezone,
|
||||||
|
)
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from google.protobuf import json_format
|
from google.protobuf import json_format
|
||||||
|
from google.protobuf.timestamp_pb2 import Timestamp
|
||||||
|
|
||||||
import betterproto
|
import betterproto
|
||||||
from tests.output_betterproto.google_impl_behavior_equivalence import (
|
from tests.output_betterproto.google_impl_behavior_equivalence import (
|
||||||
Empty,
|
Empty,
|
||||||
Foo,
|
Foo,
|
||||||
Request,
|
Request,
|
||||||
|
Spam,
|
||||||
Test,
|
Test,
|
||||||
)
|
)
|
||||||
from tests.output_reference.google_impl_behavior_equivalence.google_impl_behavior_equivalence_pb2 import (
|
from tests.output_reference.google_impl_behavior_equivalence.google_impl_behavior_equivalence_pb2 import (
|
||||||
Empty as ReferenceEmpty,
|
Empty as ReferenceEmpty,
|
||||||
Foo as ReferenceFoo,
|
Foo as ReferenceFoo,
|
||||||
Request as ReferenceRequest,
|
Request as ReferenceRequest,
|
||||||
|
Spam as ReferenceSpam,
|
||||||
Test as ReferenceTest,
|
Test as ReferenceTest,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -59,6 +67,19 @@ def test_bytes_are_the_same_for_oneof():
|
|||||||
assert isinstance(message_reference2.foo, ReferenceFoo)
|
assert isinstance(message_reference2.foo, ReferenceFoo)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("dt", (datetime.min.replace(tzinfo=timezone.utc),))
|
||||||
|
def test_datetime_clamping(dt): # see #407
|
||||||
|
ts = Timestamp()
|
||||||
|
ts.FromDatetime(dt)
|
||||||
|
assert bytes(Spam(dt)) == ReferenceSpam(ts=ts).SerializeToString()
|
||||||
|
message_bytes = bytes(Spam(dt))
|
||||||
|
|
||||||
|
assert (
|
||||||
|
Spam().parse(message_bytes).ts.timestamp()
|
||||||
|
== ReferenceSpam.FromString(message_bytes).ts.seconds
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_empty_message_field():
|
def test_empty_message_field():
|
||||||
message = Request()
|
message = Request()
|
||||||
reference_message = ReferenceRequest()
|
reference_message = ReferenceRequest()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user