diff --git a/swh/model/model.py b/swh/model/model.py --- a/swh/model/model.py +++ b/swh/model/model.py @@ -165,7 +165,7 @@ """Represents a TZ-aware timestamp from a VCS.""" timestamp = attrib_typecheck(type=Timestamp) offset = attrib_typecheck(type=int) - negative_utc = attrib_typecheck(type=bool) + negative_utc = attrib_typecheck(type=bool, default=False) @offset.validator def check_offset(self, attribute, value): @@ -176,6 +176,11 @@ # you'll find in the wild... raise ValueError('offset too large: %d minutes' % value) + @negative_utc.validator + def check_sign(self, attribute, value): + if self.offset and value: + raise ValueError("negative_utc can only be True is offset=0") + @classmethod def from_dict(cls, obj: Union[Dict, datetime.datetime, int]): """Builds a TimestampWithTimezone from any of the formats diff --git a/swh/model/tests/test_model.py b/swh/model/tests/test_model.py --- a/swh/model/tests/test_model.py +++ b/swh/model/tests/test_model.py @@ -90,6 +90,63 @@ Timestamp(seconds=0, microseconds=-1) +def test_timestampwithtimezone(): + ts = Timestamp(seconds=0, microseconds=0) + tstz = TimestampWithTimezone( + timestamp=ts, + offset=0) + attr.validate(tstz) + assert tstz.negative_utc is False + + attr.validate(TimestampWithTimezone( + timestamp=ts, + offset=10)) + + attr.validate(TimestampWithTimezone( + timestamp=ts, + offset=-10)) + + tstz = TimestampWithTimezone( + timestamp=ts, + offset=0, + negative_utc=True) + attr.validate(tstz) + assert tstz.negative_utc is True + + with pytest.raises(AttributeTypeError): + TimestampWithTimezone( + timestamp=datetime.datetime.now(), + offset=0) + + with pytest.raises(AttributeTypeError): + TimestampWithTimezone( + timestamp=ts, + offset='0') + + with pytest.raises(AttributeTypeError): + TimestampWithTimezone( + timestamp=ts, + offset=1.0) + + with pytest.raises(AttributeTypeError): + TimestampWithTimezone( + timestamp=ts, + offset=1, + negative_utc=0) + + with pytest.raises(ValueError): + TimestampWithTimezone( + timestamp=ts, + offset=1, + negative_utc=True) + + with pytest.raises(ValueError): + TimestampWithTimezone( + timestamp=ts, + offset=-1, + negative_utc=True) + + def test_timestampwithtimezone_from_datetime(): tz = datetime.timezone(datetime.timedelta(minutes=+60)) date = datetime.datetime(