From 5054126c508a2046bf006e59919f60e954f7241a Mon Sep 17 00:00:00 2001 From: Ramon Torres Date: Thu, 7 Mar 2024 13:19:34 -0500 Subject: [PATCH] Add distance_to (#7) * Add `distance_to` * Version bump * Fix typechecker warning --- CHANGELOG.md | 6 ++++++ mp_yearmonth/yearmonth.py | 4 ++++ pyproject.toml | 2 +- tests/test_yearmonth.py | 18 ++++++++++++++++-- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56295fe..70c1c87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## v0.3.0 + +### Added + +- Added `YearMonth.distance_to()` method for calculating the distance between two `YearMonth` instances. + ## v0.2.0 ### Added diff --git a/mp_yearmonth/yearmonth.py b/mp_yearmonth/yearmonth.py index 850f160..d7b75d9 100644 --- a/mp_yearmonth/yearmonth.py +++ b/mp_yearmonth/yearmonth.py @@ -167,6 +167,10 @@ def applying_delta(self, months: int) -> "YearMonth": month = ((self.month + months - 1) % 12) + 1 return YearMonth(year, month) + def distance_to(self, other: "YearMonth") -> int: + """Return the number of months between this and another YearMonth.""" + return (other.year - self.year) * 12 + (other.month - self.month) + @classmethod def range(cls, start: "YearMonth", end: "YearMonth") -> Iterator["YearMonth"]: """Return a list of all months between start and end, inclusive.""" diff --git a/pyproject.toml b/pyproject.toml index 38146ea..2b236e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mp-yearmonth" -version = "0.2.0" +version = "0.3.0" description = "A year-month datatype for Python." keywords = ["year", "month", "date", "calendar"] authors = ["Ramon Torres "] diff --git a/tests/test_yearmonth.py b/tests/test_yearmonth.py index c372575..df6d664 100644 --- a/tests/test_yearmonth.py +++ b/tests/test_yearmonth.py @@ -21,10 +21,10 @@ def test_init_handles_out_of_range_year(): def test_init_handles_non_int_values(): with pytest.raises(TypeError, match=r"^year must be an integer$"): - YearMonth("2021", 1) + YearMonth("2021", 1) # type: ignore with pytest.raises(TypeError, match=r"^month must be an integer$"): - YearMonth(2021, "1") + YearMonth(2021, "1") # type: ignore def test_str(): @@ -137,6 +137,20 @@ def test_next(): assert YearMonth(2021, 12).next() == YearMonth(2022, 1) +@pytest.mark.parametrize( + ("month", "other_month", "expected_distance"), + [ + (YearMonth(2021, 1), YearMonth(2021, 1), 0), + (YearMonth(2021, 1), YearMonth(2021, 2), 1), + (YearMonth(2021, 1), YearMonth(2022, 1), 12), + (YearMonth(2021, 1), YearMonth(2020, 12), -1), + (YearMonth(2021, 1), YearMonth(2020, 1), -12), + ], +) +def test_distance_to(month: YearMonth, other_month: YearMonth, expected_distance: int): + assert month.distance_to(other_month) == expected_distance + + def test_range(): # Ascending r = YearMonth.range(YearMonth(2021, 1), YearMonth(2021, 3))