Skip to content

REF: avoid catching and re-raising in datetime parsing #50629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 23 additions & 31 deletions pandas/_libs/tslibs/conversion.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -520,43 +520,35 @@ cdef _TSObject _convert_str_to_tsobject(object ts, tzinfo tz, str unit,
)
if not string_to_dts_failed:
reso = get_supported_reso(out_bestunit)
try:
check_dts_bounds(&dts, reso)
if out_local == 1:
return _create_tsobject_tz_using_offset(
dts, out_tzoffset, tz, reso
check_dts_bounds(&dts, reso)
if out_local == 1:
return _create_tsobject_tz_using_offset(
dts, out_tzoffset, tz, reso
)
else:
ival = npy_datetimestruct_to_datetime(reso, &dts)
if tz is not None:
# shift for _localize_tso
ival = tz_localize_to_utc_single(
ival, tz, ambiguous="raise", nonexistent=None, creso=reso
)
else:
ival = npy_datetimestruct_to_datetime(reso, &dts)
if tz is not None:
# shift for _localize_tso
ival = tz_localize_to_utc_single(
ival, tz, ambiguous="raise", nonexistent=None, creso=reso
)
obj = _TSObject()
obj.dts = dts
obj.value = ival
obj.creso = reso
maybe_localize_tso(obj, tz, obj.creso)
return obj

except OutOfBoundsDatetime:
# GH#19382 for just-barely-OutOfBounds falling back to dateutil
# parser will return incorrect result because it will ignore
# nanoseconds
raise

except ValueError:
# Fall through to parse_datetime_string
pass
Comment on lines -549 to -551
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this was uncovered, so OK to remove

obj = _TSObject()
obj.dts = dts
obj.value = ival
obj.creso = reso
maybe_localize_tso(obj, tz, obj.creso)
return obj

try:
# TODO: use the one that returns reso
dt = parse_datetime_string(
ts, dayfirst=dayfirst, yearfirst=yearfirst
)
except (ValueError, OverflowError) as err:
raise ValueError("could not convert string to Timestamp") from err
except ValueError as err:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like there was no test which hit the OverflowError anyway, nice

if "out of range for month" in str(err):
# dateutil raised when constructing a datetime object,
# let's give a nicer exception message
raise ValueError("could not convert string to Timestamp") from err
raise

return convert_datetime_to_tsobject(dt, tz)

Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/datetimes/test_date_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ def test_misc(self):
def test_date_parse_failure(self):
badly_formed_date = "2007/100/1"

msg = "could not convert string to Timestamp"
msg = "Unknown string format: 2007/100/1"
with pytest.raises(ValueError, match=msg):
Timestamp(badly_formed_date)

Expand Down
5 changes: 4 additions & 1 deletion pandas/tests/io/pytables/test_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,10 @@ def test_query_compare_column_type(setup_path):
v = "a"
for col in ["int", "float", "real_date"]:
query = f"{col} {op} v"
msg = "could not convert string to "
if col == "real_date":
msg = 'Given date string "a" not likely a datetime'
else:
msg = "could not convert string to "
with pytest.raises(ValueError, match=msg):
store.select("test", where=query)

Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/scalar/timestamp/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ def test_constructor_nanosecond(self, result):
@pytest.mark.parametrize("z", ["Z0", "Z00"])
def test_constructor_invalid_Z0_isostring(self, z):
# GH 8910
msg = "could not convert string to Timestamp"
msg = f"Unknown string format: 2014-11-02 01:00{z}"
with pytest.raises(ValueError, match=msg):
Timestamp(f"2014-11-02 01:00{z}")

Expand Down