Skip to content

Commit 74a94a4

Browse files
author
Suhana Shaik
committed
Fix to_offset fallback and add reproduction test
1 parent 961357c commit 74a94a4

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

pandas/_libs/tslibs/offsets.pyx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6349,17 +6349,20 @@ cpdef to_offset(freq, bint is_period=False):
63496349
else:
63506350
result = result + offset
63516351
except (ValueError, TypeError) as err:
6352-
raise_invalid_freq(
6353-
freq=freq,
6354-
extra_message=f"Failed to parse with error message: {repr(err)}"
6355-
)
6352+
# --- FALLBACK---
6353+
try:
6354+
td = Timedelta(freq)
6355+
result = delta_to_tick(td)
6356+
except (ValueError, TypeError):
6357+
# If Timedelta parsing also fails, raise the original error
6358+
raise_invalid_freq(
6359+
freq=freq,
6360+
extra_message=f"Failed to parse with error message: {repr(err)}"
6361+
)
63566362

6357-
# TODO(3.0?) once deprecation of "d" is enforced, the check for it here
6358-
# can be removed
63596363
if (
63606364
isinstance(result, Hour)
63616365
and result.n % 24 == 0
6362-
and ("d" in freq or "D" in freq)
63636366
):
63646367
# Since Day is no longer a Tick, delta_to_tick returns Hour above,
63656368
# so we convert back here.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import pytest
2+
3+
from pandas import Timedelta
4+
5+
from pandas.tseries.frequencies import to_offset
6+
7+
8+
def test_to_offset_timedelta_string_fallback():
9+
# This is the case you found: str(Timedelta)
10+
# Previously, this might have failed in the regex loop
11+
freq_str = "0 days 01:30:00"
12+
result = to_offset(freq_str)
13+
14+
expected = to_offset("1h30min")
15+
assert result == expected
16+
17+
18+
@pytest.mark.parametrize(
19+
"freq",
20+
[
21+
"1 days 02:00:00",
22+
"00:00:00.001",
23+
"1h 30min", # spaces between components
24+
],
25+
)
26+
def test_to_offset_consistent_with_timedelta(freq):
27+
# Ensure our fallback produces the same result as direct Timedelta conversion
28+
result = to_offset(freq)
29+
expected_td = Timedelta(freq)
30+
31+
# Convert result to total seconds to compare magnitude
32+
assert result.nanos == expected_td.value
33+
34+
35+
def test_to_offset_invalid_still_raises():
36+
# Ensure that if BOTH fail, we still get the Invalid Frequency error
37+
with pytest.raises(ValueError, match="Invalid frequency"):
38+
to_offset("not_a_time_at_all")

0 commit comments

Comments
 (0)