fix(tools): send a date window that ends before it starts back to the model (#1595)

- as_of_window refuses a start after the end, as it does an unreadable start, instead of passing it to the vendor
This commit is contained in:
Yijia-Xiao
2026-10-27 07:59:39 +00:00
parent 21bc5d8fe7
commit ee06dcb961
2 changed files with 13 additions and 1 deletions
+9
View File
@@ -159,6 +159,15 @@ def test_a_start_date_that_is_not_a_date_is_sent_back_to_the_model(tool):
assert "YYYY-MM-DD" in out and "start_date" in out
@pytest.mark.unit
def test_a_window_that_ends_before_it_starts_is_sent_back_to_the_model():
# A reversed window reached the vendor, which then reported no data for it.
with mock.patch.object(tools, "route_to_vendor", return_value="ok") as routed:
out = tools.get_stock_data.func("NVDA", "2026-08-12", "2026-08-01", trade_date=TRADE_DATE)
assert not routed.called
assert "start_date" in out and "end_date" in out
@pytest.mark.unit
def test_a_window_whose_start_is_not_a_date_is_refused():
with pytest.raises(ValueError, match="start_date"):
+4 -1
View File
@@ -95,11 +95,14 @@ def as_of_window(start_date: str, end_date: str, trade_date: str) -> tuple[str,
A window wholly after the run date keeps its length and moves back to end there.
An unreadable end reads as the run date, but no window can be guessed from an
unreadable start, so it raises ValueError for the caller to send back (#1476).
unreadable start or from a start after the end, so those raise ValueError for
the caller to send back (#1476).
"""
start, old_end = _parse(start_date), _parse(end_date)
if start is None:
raise ValueError(f"start_date {start_date!r} is not a date; give it as YYYY-MM-DD")
if old_end is not None and start > old_end:
raise ValueError(f"start_date {start_date} is after end_date {end_date}; give the earlier date first")
end = as_of(end_date, trade_date)
end_dt = _parse(end)
if end_dt is None or end_dt == old_end or start <= end_dt: