Skip to content

Commit c9589a0

Browse files
committed
add fiscal year versioning
1 parent b140a6c commit c9589a0

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

dcpy/test/utils/test_versions.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ def test_parsing_valid_versions(self):
2424
format=versions.DateVersionFormat.quarter,
2525
),
2626
],
27+
[
28+
"FY2020",
29+
versions.Date(
30+
date=date(2020, 1, 1),
31+
format=versions.DateVersionFormat.fiscal_year,
32+
),
33+
],
2734
[
2835
"26prelim",
2936
versions.CapitalBudget(
@@ -62,6 +69,8 @@ def test_parsing_invalid_version(self):
6269
versions.parse("23v")
6370
with self.assertRaises(Exception):
6471
versions.parse("2v12")
72+
with self.assertRaises(Exception):
73+
versions.parse("FY26")
6574
with self.assertRaises(Exception):
6675
versions.parse("20231212")
6776
with self.assertRaises(Exception):
@@ -158,6 +167,7 @@ def test_sort_invalid_versions(self):
158167
def test_is_newer_valid_versions(self):
159168
for version_1, version_2, bool_expected in [
160169
["23v2", "22v3.4", True],
170+
["FY2019", "FY2020", False],
161171
["23Q1", "23Q2", False],
162172
["23v2.0.1", "23v2", True],
163173
["23Q1.1", "23Q1", True],
@@ -182,6 +192,7 @@ def test_bumping_versions(self):
182192
["major", None, "23v2.1", "23v3"],
183193
["minor", None, "23v2", "23v2.1"],
184194
["minor", None, "23v2.1", "23v2.2"],
195+
[None, 1, "FY2020", "FY2021"],
185196
[None, 1, "23Q1", "23Q2"],
186197
[None, 2, "23Q4", "24Q2"],
187198
[None, 7, "23Q2", "25Q1"],
@@ -206,6 +217,27 @@ def test_bumping_versions(self):
206217
]:
207218
self.assertEqual(v_expected, versions.bump(v, bumped_part, bump_by).label)
208219

220+
def test_bumping_versions_errors(self):
221+
with self.assertRaises(NotImplementedError):
222+
versions.bump("2023-01-01")
223+
224+
with self.assertRaises(ValueError):
225+
versions.bump(versions.Date(date(2023, 1, 1), format="unsupported"))
226+
227+
with self.assertRaises(ValueError):
228+
versions.bump(
229+
versions.Date(
230+
date(2023, 1, 1), format=versions.DateVersionFormat.fiscal_year
231+
),
232+
bump_type=versions.VersionSubType.major,
233+
)
234+
235+
class UnsupportedVersion:
236+
pass
237+
238+
with self.assertRaises(ValueError):
239+
versions.bump(UnsupportedVersion())
240+
209241
def test_group_versions_by_base(self):
210242
for version, versions_list, expected_output in [
211243
[

dcpy/utils/versions.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111

1212
class DateVersionFormat(StrEnum):
13+
fiscal_year = "Fiscal Year"
1314
quarter = "Quarter"
1415
month = "Month"
1516
date = "Date"
@@ -159,6 +160,11 @@ class Date(Version):
159160
@property
160161
def label(self) -> str:
161162
match self.format:
163+
case DateVersionFormat.fiscal_year:
164+
if self.patch == 0:
165+
return f"FY{self.date.strftime('%Y')}"
166+
else:
167+
return f"FY{self.date.strftime('%Y')}.{self.patch}"
162168
case DateVersionFormat.quarter:
163169
if self.patch == 0:
164170
return (
@@ -176,6 +182,8 @@ def label(self) -> str:
176182
return self.date.strftime("%Y-%m-%d")
177183
else:
178184
return f"{self.date.strftime('%Y-%m-%d')}.{self.patch}"
185+
case _:
186+
raise ValueError(f"Unsupported DateVersionFormat '{self.format}'")
179187

180188
def __lt__(self, other) -> bool:
181189
match other:
@@ -253,6 +261,11 @@ def parse(v: str) -> Version:
253261
return MajorMinor(
254262
year=int(m[1]), major=int(m[2]), minor=int(m[3]), patch=int(m[4])
255263
)
264+
case r"^FY(\d{4})$" as m:
265+
return Date(
266+
date(int(m[1]), 1, 1),
267+
format=DateVersionFormat.fiscal_year,
268+
)
256269
case r"^(\d{2})Q(\d)$" as m:
257270
return Date(
258271
date(2000 + int(m[1]), int(m[2]) * 3 - 2, 1),
@@ -403,6 +416,11 @@ def bump(
403416
minor=previous_version.minor,
404417
patch=previous_version.patch + bump_by,
405418
)
419+
case Date(format=DateVersionFormat.fiscal_year), None:
420+
return Date(
421+
date=previous_version.date + relativedelta(years=bump_by),
422+
format=previous_version.format,
423+
)
406424
case Date(format=DateVersionFormat.quarter), None:
407425
return Date(
408426
date=previous_version.date + relativedelta(months=bump_by * 3),
@@ -436,7 +454,7 @@ def bump(
436454
case Date(), None:
437455
raise ValueError(f"Unsupported date format {previous_version.format}")
438456
case Date(), _:
439-
raise Exception(
457+
raise ValueError(
440458
f"Version subtype {bump_type} not applicable for Date versions"
441459
)
442460
case CapitalBudget(), None:

0 commit comments

Comments
 (0)