Skip to content

Commit b98315b

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

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-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: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import pytest
2+
import pandas as pd
3+
from pandas.tseries.frequencies import to_offset
4+
from pandas import Timedelta
5+
6+
7+
def test_to_offset_timedelta_string_fallback():
8+
# This is the case you found: str(Timedelta)
9+
# Previously, this might have failed in the regex loop
10+
freq_str = "0 days 01:30:00"
11+
result = to_offset(freq_str)
12+
13+
expected = to_offset("1h30min")
14+
assert result == expected
15+
16+
17+
@pytest.mark.parametrize("freq", [
18+
"1 days 02:00:00",
19+
"00:00:00.001",
20+
"1h 30min", # spaces between components
21+
])
22+
def test_to_offset_consistent_with_timedelta(freq):
23+
# Ensure our fallback produces the same result as direct Timedelta conversion
24+
result = to_offset(freq)
25+
expected_td = Timedelta(freq)
26+
27+
# Convert result to total seconds to compare magnitude
28+
assert result.nanos == expected_td.value
29+
30+
31+
def test_to_offset_invalid_still_raises():
32+
# Ensure that if BOTH fail, we still get the Invalid Frequency error
33+
with pytest.raises(ValueError, match="Invalid frequency"):
34+
to_offset("not_a_time_at_all")

0 commit comments

Comments
 (0)