From 479dee483f67d7fb35f9fdc63e0fda7dca165105 Mon Sep 17 00:00:00 2001 From: Gareth Thackeray Date: Fri, 3 Jan 2025 17:25:50 +0000 Subject: [PATCH 1/2] Preserve months when using the Pendulum Duration type --- pydantic_extra_types/pendulum_dt.py | 82 +++++++++--- tests/test_pendulum_dt.py | 196 +++++++++++++++++----------- 2 files changed, 183 insertions(+), 95 deletions(-) diff --git a/pydantic_extra_types/pendulum_dt.py b/pydantic_extra_types/pendulum_dt.py index 797bb8e..b469e6b 100644 --- a/pydantic_extra_types/pendulum_dt.py +++ b/pydantic_extra_types/pendulum_dt.py @@ -22,12 +22,12 @@ class DateTimeSettings(type): def __new__(cls, name, bases, dct, **kwargs): # type: ignore[no-untyped-def] - dct['strict'] = kwargs.pop('strict', True) + dct["strict"] = kwargs.pop("strict", True) return super().__new__(cls, name, bases, dct) def __init__(cls, name, bases, dct, **kwargs): # type: ignore[no-untyped-def] super().__init__(name, bases, dct) - cls.strict = kwargs.get('strict', True) + cls.strict = kwargs.get("strict", True) class DateTime(_DateTime, metaclass=DateTimeSettings): @@ -52,7 +52,9 @@ class test_model(BaseModel): __slots__: list[str] = [] @classmethod - def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: + def __get_pydantic_core_schema__( + cls, source: type[Any], handler: GetCoreSchemaHandler + ) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the Datetime validation Args: @@ -62,10 +64,14 @@ def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaH Returns: A Pydantic CoreSchema with the Datetime validation. """ - return core_schema.no_info_wrap_validator_function(cls._validate, core_schema.datetime_schema()) + return core_schema.no_info_wrap_validator_function( + cls._validate, core_schema.datetime_schema() + ) @classmethod - def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> DateTime: + def _validate( + cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler + ) -> DateTime: """Validate the datetime object and return it. Args: @@ -88,11 +94,13 @@ def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler value = parse(value, strict=cls.strict) if isinstance(value, _DateTime): return DateTime.instance(value) - raise ValueError(f'value is not a valid datetime it is a {type(value)}') + raise ValueError(f"value is not a valid datetime it is a {type(value)}") except ValueError: raise except Exception as exc: - raise PydanticCustomError('value_error', 'value is not a valid datetime') from exc + raise PydanticCustomError( + "value_error", "value is not a valid datetime" + ) from exc class Date(_Date): @@ -117,7 +125,9 @@ class test_model(BaseModel): __slots__: list[str] = [] @classmethod - def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: + def __get_pydantic_core_schema__( + cls, source: type[Any], handler: GetCoreSchemaHandler + ) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the Date validation Args: @@ -127,10 +137,14 @@ def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaH Returns: A Pydantic CoreSchema with the Date validation. """ - return core_schema.no_info_wrap_validator_function(cls._validate, core_schema.date_schema()) + return core_schema.no_info_wrap_validator_function( + cls._validate, core_schema.date_schema() + ) @classmethod - def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> Date: + def _validate( + cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler + ) -> Date: """Validate the date object and return it. Args: @@ -149,9 +163,11 @@ def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler parsed = parse(value) if isinstance(parsed, (_DateTime, _Date)): return Date(parsed.year, parsed.month, parsed.day) - raise ValueError('value is not a valid date it is a {type(parsed)}') + raise ValueError("value is not a valid date it is a {type(parsed)}") except Exception as exc: - raise PydanticCustomError('value_error', 'value is not a valid date') from exc + raise PydanticCustomError( + "value_error", "value is not a valid date" + ) from exc class Duration(_Duration): @@ -176,7 +192,9 @@ class test_model(BaseModel): __slots__: list[str] = [] @classmethod - def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: + def __get_pydantic_core_schema__( + cls, source: type[Any], handler: GetCoreSchemaHandler + ) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the Duration validation Args: @@ -186,10 +204,14 @@ def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaH Returns: A Pydantic CoreSchema with the Duration validation. """ - return core_schema.no_info_wrap_validator_function(cls._validate, core_schema.timedelta_schema()) + return core_schema.no_info_wrap_validator_function( + cls._validate, core_schema.timedelta_schema() + ) @classmethod - def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> Duration: + def _validate( + cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler + ) -> Duration: """Validate the Duration object and return it. Args: @@ -199,14 +221,34 @@ def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler Returns: The validated value or raises a PydanticCustomError. """ - # if we are passed an existing instance, pass it straight through. - if isinstance(value, (_Duration, timedelta)): - return Duration(seconds=value.total_seconds()) + + if isinstance(value, _Duration): + return Duration( + years=value.years, + months=value.months, + weeks=value.weeks, + days=value.remaining_days, + hours=value.hours, + minutes=value.minutes, + seconds=value.remaining_seconds, + microseconds=value.microseconds, + ) + + if isinstance(value, timedelta): + return Duration( + days=value.days, + seconds=value.seconds, + microseconds=value.microseconds, + ) try: parsed = parse(value, exact=True) if not isinstance(parsed, timedelta): - raise ValueError(f'value is not a valid duration it is a {type(parsed)}') + raise ValueError( + f"value is not a valid duration it is a {type(parsed)}" + ) return Duration(seconds=parsed.total_seconds()) except Exception as exc: - raise PydanticCustomError('value_error', 'value is not a valid duration') from exc + raise PydanticCustomError( + "value_error", "value is not a valid duration" + ) from exc diff --git a/tests/test_pendulum_dt.py b/tests/test_pendulum_dt.py index 868648b..7e24cab 100644 --- a/tests/test_pendulum_dt.py +++ b/tests/test_pendulum_dt.py @@ -33,7 +33,7 @@ class DurationModel(BaseModel): @pytest.mark.parametrize( - 'instance', + "instance", [ pendulum.now(), datetime.now(), @@ -66,7 +66,7 @@ def test_existing_instance(instance): @pytest.mark.parametrize( - 'instance', + "instance", [ pendulum.today(), date.today(), @@ -88,12 +88,34 @@ def test_pendulum_date_existing_instance(instance): @pytest.mark.parametrize( - 'instance', + "instance", [ pendulum.duration(days=42, hours=13, minutes=37), pendulum.duration(days=-42, hours=13, minutes=37), + pendulum.duration(weeks=97), + pendulum.duration(days=463), + pendulum.duration(milliseconds=90122), + pendulum.duration(microseconds=90122), + pendulum.duration( + years=2, + months=3, + weeks=19, + days=1, + hours=25, + seconds=732, + milliseconds=123, + microseconds=1324, + ), timedelta(days=42, hours=13, minutes=37), timedelta(days=-42, hours=13, minutes=37), + timedelta( + weeks=19, + days=1, + hours=25, + seconds=732, + milliseconds=123, + microseconds=1324, + ), ], ) def test_duration_timedelta__existing_instance(instance): @@ -106,7 +128,7 @@ def test_duration_timedelta__existing_instance(instance): @pytest.mark.parametrize( - 'dt', + "dt", [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), @@ -122,7 +144,7 @@ def test_pendulum_dt_from_serialized(dt): @pytest.mark.parametrize( - 'dt', + "dt", [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), @@ -143,16 +165,20 @@ def test_pendulum_dt_from_serialized_preserves_timezones(dt): assert model.dt.tz is not None assert model.dt.tz.utcoffset(model.dt) == dt_actual.tz.utcoffset(dt_actual) assert model.dt.timezone is not None - assert model.dt.timezone.utcoffset(model.dt) == dt_actual.timezone.utcoffset(dt_actual) + assert model.dt.timezone.utcoffset(model.dt) == dt_actual.timezone.utcoffset( + dt_actual + ) @pytest.mark.parametrize( - 'dt', + "dt", [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), - 'Sat Oct 11 17:13:46 UTC 2003', # date util parsing - pendulum.now().to_iso8601_string()[:5], # actualy valid or pendulum.parse(dt, strict=False) would fail here + "Sat Oct 11 17:13:46 UTC 2003", # date util parsing + pendulum.now().to_iso8601_string()[ + :5 + ], # actualy valid or pendulum.parse(dt, strict=False) would fail here ], ) def test_pendulum_dt_not_strict_from_serialized(dt): @@ -165,7 +191,7 @@ def test_pendulum_dt_not_strict_from_serialized(dt): @pytest.mark.parametrize( - 'dt', + "dt", [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), @@ -173,17 +199,17 @@ def test_pendulum_dt_not_strict_from_serialized(dt): 1718096578.5, -5, -5.5, - float('-0'), - '1718096578', - '1718096578.5', - '-5', - '-5.5', - '-0', - '-0.0', - '+0.0', - '+1718096578.5', - float('-2e10') - 1.0, - float('2e10') + 1.0, + float("-0"), + "1718096578", + "1718096578.5", + "-5", + "-5.5", + "-0", + "-0.0", + "+0.0", + "+1718096578.5", + float("-2e10") - 1.0, + float("2e10") + 1.0, -2e10 - 1, 2e10 + 1, ], @@ -198,23 +224,23 @@ def test_pendulum_dt_from_str_unix_timestamp(dt): @pytest.mark.parametrize( - 'dt', + "dt", [ 1718096578, 1718096578.5, -5, -5.5, - float('-0'), - '1718096578', - '1718096578.5', - '-5', - '-5.5', - '-0', - '-0.0', - '+0.0', - '+1718096578.5', - float('-2e10') - 1.0, - float('2e10') + 1.0, + float("-0"), + "1718096578", + "1718096578.5", + "-5", + "-5.5", + "-0", + "-0.0", + "+0.0", + "+1718096578.5", + float("-2e10") - 1.0, + float("2e10") + 1.0, -2e10 - 1, 2e10 + 1, ], @@ -222,12 +248,16 @@ def test_pendulum_dt_from_str_unix_timestamp(dt): def test_pendulum_dt_from_str_unix_timestamp_is_utc(dt): """Verifies that without timezone information, it is coerced to UTC. As in pendulum""" model = DtModel(dt=dt) - assert model.dt.tzinfo.tzname(model.dt) == 'UTC' + assert model.dt.tzinfo.tzname(model.dt) == "UTC" @pytest.mark.parametrize( - 'd', - [pendulum.now().date().isoformat(), pendulum.now().to_w3c_string(), pendulum.now().to_iso8601_string()], + "d", + [ + pendulum.now().date().isoformat(), + pendulum.now().to_w3c_string(), + pendulum.now().to_iso8601_string(), + ], ) def test_pendulum_date_from_serialized(d): """Verifies that building an instance from serialized, well-formed strings decode properly.""" @@ -239,13 +269,13 @@ def test_pendulum_date_from_serialized(d): @pytest.mark.parametrize( - 'delta_t_str', + "delta_t_str", [ - 'P3.14D', - 'PT404H', - 'P1DT25H', - 'P2W', - 'P10Y10M10D', + "P3.14D", + "PT404H", + "P1DT25H", + "P2W", + "P10Y10M10D", ], ) def test_pendulum_duration_from_serialized(delta_t_str): @@ -260,30 +290,30 @@ def test_pendulum_duration_from_serialized(delta_t_str): def get_invalid_dt_common(): return [ None, - 'malformed', - 'P10Y10M10D', - float('inf'), - float('-inf'), - 'inf', - '-inf', - 'INF', - '-INF', - '+inf', - 'Infinity', - '+Infinity', - '-Infinity', - 'INFINITY', - '+INFINITY', - '-INFINITY', - 'infinity', - '+infinity', - '-infinity', - float('nan'), - 'nan', - 'NaN', - 'NAN', - '+nan', - '-nan', + "malformed", + "P10Y10M10D", + float("inf"), + float("-inf"), + "inf", + "-inf", + "INF", + "-INF", + "+inf", + "Infinity", + "+Infinity", + "-Infinity", + "INFINITY", + "+INFINITY", + "-INFINITY", + "infinity", + "+infinity", + "-infinity", + float("nan"), + "nan", + "NaN", + "NAN", + "+nan", + "-nan", ] @@ -292,7 +322,7 @@ def get_invalid_dt_common(): @pytest.mark.parametrize( - 'dt', + "dt", dt_strict, ) def test_pendulum_dt_malformed(dt): @@ -301,14 +331,17 @@ def test_pendulum_dt_malformed(dt): DtModel(dt=dt) -@pytest.mark.parametrize('dt', get_invalid_dt_common()) +@pytest.mark.parametrize("dt", get_invalid_dt_common()) def test_pendulum_dt_non_strict_malformed(dt): """Verifies that the instance fails to validate if malformed dt are passed.""" with pytest.raises(ValidationError): DtModelNotStrict(dt=dt) -@pytest.mark.parametrize('invalid_value', [None, 'malformed', pendulum.today().to_iso8601_string()[:5], 'P10Y10M10D']) +@pytest.mark.parametrize( + "invalid_value", + [None, "malformed", pendulum.today().to_iso8601_string()[:5], "P10Y10M10D"], +) def test_pendulum_date_malformed(invalid_value): """Verifies that the instance fails to validate if malformed date are passed.""" with pytest.raises(ValidationError): @@ -316,8 +349,15 @@ def test_pendulum_date_malformed(invalid_value): @pytest.mark.parametrize( - 'delta_t', - [None, 'malformed', pendulum.today().to_iso8601_string()[:5], 42, '12m', '2021-01-01T12:00:00'], + "delta_t", + [ + None, + "malformed", + pendulum.today().to_iso8601_string()[:5], + 42, + "12m", + "2021-01-01T12:00:00", + ], ) def test_pendulum_duration_malformed(delta_t): """Verifies that the instance fails to validate if malformed durations are passed.""" @@ -326,15 +366,15 @@ def test_pendulum_duration_malformed(delta_t): @pytest.mark.parametrize( - 'input_type, value, is_instance', + "input_type, value, is_instance", [ - (Date, '2021-01-01', pendulum.Date), + (Date, "2021-01-01", pendulum.Date), (Date, date(2021, 1, 1), pendulum.Date), (Date, pendulum.date(2021, 1, 1), pendulum.Date), - (DateTime, '2021-01-01T12:00:00', pendulum.DateTime), + (DateTime, "2021-01-01T12:00:00", pendulum.DateTime), (DateTime, datetime(2021, 1, 1, 12, 0, 0), pendulum.DateTime), (DateTime, pendulum.datetime(2021, 1, 1, 12, 0, 0), pendulum.DateTime), - (Duration, 'P1DT25H', pendulum.Duration), + (Duration, "P1DT25H", pendulum.Duration), (Duration, timedelta(days=1, hours=25), pendulum.Duration), (Duration, pendulum.duration(days=1, hours=25), pendulum.Duration), ], @@ -344,3 +384,9 @@ def test_date_type_adapter(input_type: type, value, is_instance: type): assert type(validated) is input_type assert isinstance(validated, input_type) assert isinstance(validated, is_instance) + + +def test_pendulum_duration_months_are_preserved(): + m = DurationModel(delta_t=pendulum.Duration(months=1)) + + assert m.delta_t.months == 1 From dd3fe84e25d4777b77b77e5d2e7442fb12e5c427 Mon Sep 17 00:00:00 2001 From: Gareth Thackeray Date: Fri, 3 Jan 2025 17:42:39 +0000 Subject: [PATCH 2/2] format --- pydantic_extra_types/pendulum_dt.py | 60 +++-------- tests/test_pendulum_dt.py | 158 ++++++++++++++-------------- 2 files changed, 94 insertions(+), 124 deletions(-) diff --git a/pydantic_extra_types/pendulum_dt.py b/pydantic_extra_types/pendulum_dt.py index b469e6b..f306529 100644 --- a/pydantic_extra_types/pendulum_dt.py +++ b/pydantic_extra_types/pendulum_dt.py @@ -22,12 +22,12 @@ class DateTimeSettings(type): def __new__(cls, name, bases, dct, **kwargs): # type: ignore[no-untyped-def] - dct["strict"] = kwargs.pop("strict", True) + dct['strict'] = kwargs.pop('strict', True) return super().__new__(cls, name, bases, dct) def __init__(cls, name, bases, dct, **kwargs): # type: ignore[no-untyped-def] super().__init__(name, bases, dct) - cls.strict = kwargs.get("strict", True) + cls.strict = kwargs.get('strict', True) class DateTime(_DateTime, metaclass=DateTimeSettings): @@ -52,9 +52,7 @@ class test_model(BaseModel): __slots__: list[str] = [] @classmethod - def __get_pydantic_core_schema__( - cls, source: type[Any], handler: GetCoreSchemaHandler - ) -> core_schema.CoreSchema: + def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the Datetime validation Args: @@ -64,14 +62,10 @@ def __get_pydantic_core_schema__( Returns: A Pydantic CoreSchema with the Datetime validation. """ - return core_schema.no_info_wrap_validator_function( - cls._validate, core_schema.datetime_schema() - ) + return core_schema.no_info_wrap_validator_function(cls._validate, core_schema.datetime_schema()) @classmethod - def _validate( - cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler - ) -> DateTime: + def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> DateTime: """Validate the datetime object and return it. Args: @@ -94,13 +88,11 @@ def _validate( value = parse(value, strict=cls.strict) if isinstance(value, _DateTime): return DateTime.instance(value) - raise ValueError(f"value is not a valid datetime it is a {type(value)}") + raise ValueError(f'value is not a valid datetime it is a {type(value)}') except ValueError: raise except Exception as exc: - raise PydanticCustomError( - "value_error", "value is not a valid datetime" - ) from exc + raise PydanticCustomError('value_error', 'value is not a valid datetime') from exc class Date(_Date): @@ -125,9 +117,7 @@ class test_model(BaseModel): __slots__: list[str] = [] @classmethod - def __get_pydantic_core_schema__( - cls, source: type[Any], handler: GetCoreSchemaHandler - ) -> core_schema.CoreSchema: + def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the Date validation Args: @@ -137,14 +127,10 @@ def __get_pydantic_core_schema__( Returns: A Pydantic CoreSchema with the Date validation. """ - return core_schema.no_info_wrap_validator_function( - cls._validate, core_schema.date_schema() - ) + return core_schema.no_info_wrap_validator_function(cls._validate, core_schema.date_schema()) @classmethod - def _validate( - cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler - ) -> Date: + def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> Date: """Validate the date object and return it. Args: @@ -163,11 +149,9 @@ def _validate( parsed = parse(value) if isinstance(parsed, (_DateTime, _Date)): return Date(parsed.year, parsed.month, parsed.day) - raise ValueError("value is not a valid date it is a {type(parsed)}") + raise ValueError('value is not a valid date it is a {type(parsed)}') except Exception as exc: - raise PydanticCustomError( - "value_error", "value is not a valid date" - ) from exc + raise PydanticCustomError('value_error', 'value is not a valid date') from exc class Duration(_Duration): @@ -192,9 +176,7 @@ class test_model(BaseModel): __slots__: list[str] = [] @classmethod - def __get_pydantic_core_schema__( - cls, source: type[Any], handler: GetCoreSchemaHandler - ) -> core_schema.CoreSchema: + def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the Duration validation Args: @@ -204,14 +186,10 @@ def __get_pydantic_core_schema__( Returns: A Pydantic CoreSchema with the Duration validation. """ - return core_schema.no_info_wrap_validator_function( - cls._validate, core_schema.timedelta_schema() - ) + return core_schema.no_info_wrap_validator_function(cls._validate, core_schema.timedelta_schema()) @classmethod - def _validate( - cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler - ) -> Duration: + def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> Duration: """Validate the Duration object and return it. Args: @@ -244,11 +222,7 @@ def _validate( try: parsed = parse(value, exact=True) if not isinstance(parsed, timedelta): - raise ValueError( - f"value is not a valid duration it is a {type(parsed)}" - ) + raise ValueError(f'value is not a valid duration it is a {type(parsed)}') return Duration(seconds=parsed.total_seconds()) except Exception as exc: - raise PydanticCustomError( - "value_error", "value is not a valid duration" - ) from exc + raise PydanticCustomError('value_error', 'value is not a valid duration') from exc diff --git a/tests/test_pendulum_dt.py b/tests/test_pendulum_dt.py index 7e24cab..7635b5d 100644 --- a/tests/test_pendulum_dt.py +++ b/tests/test_pendulum_dt.py @@ -33,7 +33,7 @@ class DurationModel(BaseModel): @pytest.mark.parametrize( - "instance", + 'instance', [ pendulum.now(), datetime.now(), @@ -66,7 +66,7 @@ def test_existing_instance(instance): @pytest.mark.parametrize( - "instance", + 'instance', [ pendulum.today(), date.today(), @@ -88,7 +88,7 @@ def test_pendulum_date_existing_instance(instance): @pytest.mark.parametrize( - "instance", + 'instance', [ pendulum.duration(days=42, hours=13, minutes=37), pendulum.duration(days=-42, hours=13, minutes=37), @@ -128,7 +128,7 @@ def test_duration_timedelta__existing_instance(instance): @pytest.mark.parametrize( - "dt", + 'dt', [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), @@ -144,7 +144,7 @@ def test_pendulum_dt_from_serialized(dt): @pytest.mark.parametrize( - "dt", + 'dt', [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), @@ -165,20 +165,16 @@ def test_pendulum_dt_from_serialized_preserves_timezones(dt): assert model.dt.tz is not None assert model.dt.tz.utcoffset(model.dt) == dt_actual.tz.utcoffset(dt_actual) assert model.dt.timezone is not None - assert model.dt.timezone.utcoffset(model.dt) == dt_actual.timezone.utcoffset( - dt_actual - ) + assert model.dt.timezone.utcoffset(model.dt) == dt_actual.timezone.utcoffset(dt_actual) @pytest.mark.parametrize( - "dt", + 'dt', [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), - "Sat Oct 11 17:13:46 UTC 2003", # date util parsing - pendulum.now().to_iso8601_string()[ - :5 - ], # actualy valid or pendulum.parse(dt, strict=False) would fail here + 'Sat Oct 11 17:13:46 UTC 2003', # date util parsing + pendulum.now().to_iso8601_string()[:5], # actualy valid or pendulum.parse(dt, strict=False) would fail here ], ) def test_pendulum_dt_not_strict_from_serialized(dt): @@ -191,7 +187,7 @@ def test_pendulum_dt_not_strict_from_serialized(dt): @pytest.mark.parametrize( - "dt", + 'dt', [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), @@ -199,17 +195,17 @@ def test_pendulum_dt_not_strict_from_serialized(dt): 1718096578.5, -5, -5.5, - float("-0"), - "1718096578", - "1718096578.5", - "-5", - "-5.5", - "-0", - "-0.0", - "+0.0", - "+1718096578.5", - float("-2e10") - 1.0, - float("2e10") + 1.0, + float('-0'), + '1718096578', + '1718096578.5', + '-5', + '-5.5', + '-0', + '-0.0', + '+0.0', + '+1718096578.5', + float('-2e10') - 1.0, + float('2e10') + 1.0, -2e10 - 1, 2e10 + 1, ], @@ -224,23 +220,23 @@ def test_pendulum_dt_from_str_unix_timestamp(dt): @pytest.mark.parametrize( - "dt", + 'dt', [ 1718096578, 1718096578.5, -5, -5.5, - float("-0"), - "1718096578", - "1718096578.5", - "-5", - "-5.5", - "-0", - "-0.0", - "+0.0", - "+1718096578.5", - float("-2e10") - 1.0, - float("2e10") + 1.0, + float('-0'), + '1718096578', + '1718096578.5', + '-5', + '-5.5', + '-0', + '-0.0', + '+0.0', + '+1718096578.5', + float('-2e10') - 1.0, + float('2e10') + 1.0, -2e10 - 1, 2e10 + 1, ], @@ -248,11 +244,11 @@ def test_pendulum_dt_from_str_unix_timestamp(dt): def test_pendulum_dt_from_str_unix_timestamp_is_utc(dt): """Verifies that without timezone information, it is coerced to UTC. As in pendulum""" model = DtModel(dt=dt) - assert model.dt.tzinfo.tzname(model.dt) == "UTC" + assert model.dt.tzinfo.tzname(model.dt) == 'UTC' @pytest.mark.parametrize( - "d", + 'd', [ pendulum.now().date().isoformat(), pendulum.now().to_w3c_string(), @@ -269,13 +265,13 @@ def test_pendulum_date_from_serialized(d): @pytest.mark.parametrize( - "delta_t_str", + 'delta_t_str', [ - "P3.14D", - "PT404H", - "P1DT25H", - "P2W", - "P10Y10M10D", + 'P3.14D', + 'PT404H', + 'P1DT25H', + 'P2W', + 'P10Y10M10D', ], ) def test_pendulum_duration_from_serialized(delta_t_str): @@ -290,30 +286,30 @@ def test_pendulum_duration_from_serialized(delta_t_str): def get_invalid_dt_common(): return [ None, - "malformed", - "P10Y10M10D", - float("inf"), - float("-inf"), - "inf", - "-inf", - "INF", - "-INF", - "+inf", - "Infinity", - "+Infinity", - "-Infinity", - "INFINITY", - "+INFINITY", - "-INFINITY", - "infinity", - "+infinity", - "-infinity", - float("nan"), - "nan", - "NaN", - "NAN", - "+nan", - "-nan", + 'malformed', + 'P10Y10M10D', + float('inf'), + float('-inf'), + 'inf', + '-inf', + 'INF', + '-INF', + '+inf', + 'Infinity', + '+Infinity', + '-Infinity', + 'INFINITY', + '+INFINITY', + '-INFINITY', + 'infinity', + '+infinity', + '-infinity', + float('nan'), + 'nan', + 'NaN', + 'NAN', + '+nan', + '-nan', ] @@ -322,7 +318,7 @@ def get_invalid_dt_common(): @pytest.mark.parametrize( - "dt", + 'dt', dt_strict, ) def test_pendulum_dt_malformed(dt): @@ -331,7 +327,7 @@ def test_pendulum_dt_malformed(dt): DtModel(dt=dt) -@pytest.mark.parametrize("dt", get_invalid_dt_common()) +@pytest.mark.parametrize('dt', get_invalid_dt_common()) def test_pendulum_dt_non_strict_malformed(dt): """Verifies that the instance fails to validate if malformed dt are passed.""" with pytest.raises(ValidationError): @@ -339,8 +335,8 @@ def test_pendulum_dt_non_strict_malformed(dt): @pytest.mark.parametrize( - "invalid_value", - [None, "malformed", pendulum.today().to_iso8601_string()[:5], "P10Y10M10D"], + 'invalid_value', + [None, 'malformed', pendulum.today().to_iso8601_string()[:5], 'P10Y10M10D'], ) def test_pendulum_date_malformed(invalid_value): """Verifies that the instance fails to validate if malformed date are passed.""" @@ -349,14 +345,14 @@ def test_pendulum_date_malformed(invalid_value): @pytest.mark.parametrize( - "delta_t", + 'delta_t', [ None, - "malformed", + 'malformed', pendulum.today().to_iso8601_string()[:5], 42, - "12m", - "2021-01-01T12:00:00", + '12m', + '2021-01-01T12:00:00', ], ) def test_pendulum_duration_malformed(delta_t): @@ -366,15 +362,15 @@ def test_pendulum_duration_malformed(delta_t): @pytest.mark.parametrize( - "input_type, value, is_instance", + 'input_type, value, is_instance', [ - (Date, "2021-01-01", pendulum.Date), + (Date, '2021-01-01', pendulum.Date), (Date, date(2021, 1, 1), pendulum.Date), (Date, pendulum.date(2021, 1, 1), pendulum.Date), - (DateTime, "2021-01-01T12:00:00", pendulum.DateTime), + (DateTime, '2021-01-01T12:00:00', pendulum.DateTime), (DateTime, datetime(2021, 1, 1, 12, 0, 0), pendulum.DateTime), (DateTime, pendulum.datetime(2021, 1, 1, 12, 0, 0), pendulum.DateTime), - (Duration, "P1DT25H", pendulum.Duration), + (Duration, 'P1DT25H', pendulum.Duration), (Duration, timedelta(days=1, hours=25), pendulum.Duration), (Duration, pendulum.duration(days=1, hours=25), pendulum.Duration), ],