Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/pendulum/duration.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@


if TYPE_CHECKING:
from typing import SupportsIndex

from typing_extensions import Self


Expand Down Expand Up @@ -470,6 +472,9 @@ def __deepcopy__(self, _: dict[int, Self]) -> Self:
weeks=self.weeks,
)

def __reduce_ex__(self, protocol: SupportsIndex) -> tuple[object, ...]:
return (*super().__reduce_ex__(protocol), self.__dict__)


Duration.min = Duration(days=-999999999)
Duration.max = Duration(
Expand Down
32 changes: 32 additions & 0 deletions tests/duration/test_behavior.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pickle

from copy import copy
from copy import deepcopy
from datetime import timedelta

Expand All @@ -20,6 +21,37 @@ def test_pickle() -> None:
assert it == it2


@pytest.mark.parametrize("protocol", range(pickle.HIGHEST_PROTOCOL + 1))
@pytest.mark.parametrize("years, months", [(2, 3), (-2, -3), (1, -2)])
def test_pickle_preserves_calendar_components(
protocol: int, years: int, months: int
) -> None:
original = pendulum.duration(
years=years, months=months, weeks=1, days=2, seconds=37, microseconds=123
)
restored = pickle.loads(pickle.dumps(original, protocol=protocol))

assert restored == original
assert restored.years == original.years
assert restored.months == original.months
assert restored.weeks == original.weeks
assert restored.remaining_days == original.remaining_days
assert restored.seconds == original.seconds
assert restored.microseconds == original.microseconds
assert str(restored) == str(original)


def test_shallow_copy_preserves_calendar_components() -> None:
original = pendulum.duration(years=1, months=2, days=9)
copied = copy(original)

assert copied is not original
assert copied == original
assert copied.years == original.years
assert copied.months == original.months
assert str(copied) == str(original)


def test_comparison_to_timedelta() -> None:
duration = pendulum.duration(days=3)

Expand Down