Skip to content

Commit 91dada8

Browse files
committed
added 'want_exc' param to '_string_to_dts'
1 parent 10636ca commit 91dada8

File tree

5 files changed

+61
-62
lines changed

5 files changed

+61
-62
lines changed

pandas/_libs/tslib.pyx

Lines changed: 48 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,7 @@ def _test_parse_iso8601(object ts):
205205
elif ts == 'today':
206206
return Timestamp.now().normalize()
207207

208-
if _string_to_dts(ts, &obj.dts, &out_local, &out_tzoffset) == -1:
209-
raise ValueError
208+
_string_to_dts(ts, &obj.dts, &out_local, &out_tzoffset, True)
210209
obj.value = dtstruct_to_dt64(&obj.dts)
211210
check_dts_bounds(&obj.dts)
212211
if out_local == 1:
@@ -583,62 +582,55 @@ cpdef array_to_datetime(ndarray[object] values, str errors='raise',
583582

584583
string_to_dts_failed = _string_to_dts(
585584
val, &dts, &out_local,
586-
&out_tzoffset
585+
&out_tzoffset, False
587586
)
588-
try:
589-
if string_to_dts_failed:
590-
# An error at this point is a _parsing_ error
591-
# specifically _not_ OutOfBoundsDatetime
592-
if _parse_today_now(val, &iresult[i]):
593-
continue
594-
elif require_iso8601:
595-
# if requiring iso8601 strings, skip trying
596-
# other formats
597-
if is_coerce:
598-
iresult[i] = NPY_NAT
599-
continue
600-
elif is_raise:
601-
raise ValueError("time data {val} doesn't "
602-
"match format specified"
603-
.format(val=val))
604-
return values, tz_out
605-
606-
try:
607-
py_dt = parse_datetime_string(
608-
val,
609-
dayfirst=dayfirst,
610-
yearfirst=yearfirst
611-
)
612-
except Exception:
613-
if is_coerce:
614-
iresult[i] = NPY_NAT
615-
continue
616-
raise TypeError("invalid string coercion to "
617-
"datetime")
618-
619-
# If the dateutil parser returned tzinfo,
620-
# capture it to check if all arguments
621-
# have the same tzinfo
622-
tz = py_dt.utcoffset()
623-
if tz is not None:
624-
seen_datetime_offset = 1
625-
# dateutil timezone objects cannot be hashed,
626-
# so store the UTC offsets in seconds instead
627-
out_tzoffset_vals.add(tz.total_seconds())
628-
else:
629-
# Add a marker for naive string,
630-
# to track if we are
631-
# parsing mixed naive and aware strings
632-
out_tzoffset_vals.add('naive')
633-
634-
_ts = convert_datetime_to_tsobject(py_dt, None)
635-
iresult[i] = _ts.value
636-
except:
637-
# TODO: What exception are we concerned with here?
638-
if is_coerce:
639-
iresult[i] = NPY_NAT
587+
if string_to_dts_failed:
588+
# An error at this point is a _parsing_ error
589+
# specifically _not_ OutOfBoundsDatetime
590+
if _parse_today_now(val, &iresult[i]):
640591
continue
641-
raise
592+
elif require_iso8601:
593+
# if requiring iso8601 strings, skip trying
594+
# other formats
595+
if is_coerce:
596+
iresult[i] = NPY_NAT
597+
continue
598+
elif is_raise:
599+
raise ValueError("time data {val} doesn't "
600+
"match format specified"
601+
.format(val=val))
602+
return values, tz_out
603+
604+
try:
605+
py_dt = parse_datetime_string(
606+
val,
607+
dayfirst=dayfirst,
608+
yearfirst=yearfirst
609+
)
610+
except Exception:
611+
if is_coerce:
612+
iresult[i] = NPY_NAT
613+
continue
614+
raise TypeError("invalid string coercion to "
615+
"datetime")
616+
617+
# If the dateutil parser returned tzinfo,
618+
# capture it to check if all arguments
619+
# have the same tzinfo
620+
tz = py_dt.utcoffset()
621+
if tz is not None:
622+
seen_datetime_offset = 1
623+
# dateutil timezone objects cannot be hashed,
624+
# so store the UTC offsets in seconds instead
625+
out_tzoffset_vals.add(tz.total_seconds())
626+
else:
627+
# Add a marker for naive string,
628+
# to track if we are
629+
# parsing mixed naive and aware strings
630+
out_tzoffset_vals.add('naive')
631+
632+
_ts = convert_datetime_to_tsobject(py_dt, None)
633+
iresult[i] = _ts.value
642634
if not string_to_dts_failed:
643635
# No error reported by string_to_dts, pick back up
644636
# where we left off

pandas/_libs/tslibs/conversion.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ cdef _TSObject convert_str_to_tsobject(object ts, object tz, object unit,
445445
else:
446446
string_to_dts_failed = _string_to_dts(
447447
ts, &obj.dts, &out_local,
448-
&out_tzoffset
448+
&out_tzoffset, False
449449
)
450450
if string_to_dts_failed:
451451
try:

pandas/_libs/tslibs/np_datetime.pxd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,5 @@ cdef npy_timedelta get_timedelta64_value(object obj) nogil
7373
cdef NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil
7474

7575
cdef int _string_to_dts(object val, npy_datetimestruct* dts,
76-
int* out_local, int* out_tzoffset)
76+
int* out_local, int* out_tzoffset,
77+
bint want_exc) except? -1

pandas/_libs/tslibs/np_datetime.pyx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,12 @@ cdef inline int64_t pydate_to_dt64(date val, npy_datetimestruct *dts):
170170

171171

172172
cdef inline int _string_to_dts(object val, npy_datetimestruct* dts,
173-
int* out_local, int* out_tzoffset):
173+
int* out_local, int* out_tzoffset,
174+
bint want_exc) except? -1:
174175
cdef:
175176
Py_ssize_t length
176177
const char* buf
177178

178179
buf = get_c_string_buf_and_size(val, &length)
179-
return parse_iso_8601_datetime(buf, length, 0,
180+
return parse_iso_8601_datetime(buf, length, want_exc,
180181
dts, out_local, out_tzoffset)

pandas/tests/tslibs/test_parse_iso8601.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,18 @@ def test_parsers_iso8601(date_str, exp):
4646
"20010101 12345Z",
4747
])
4848
def test_parsers_iso8601_invalid(date_str):
49-
with pytest.raises(ValueError):
49+
msg = "Error parsing datetime string \"{s}\"".format(s=date_str)
50+
51+
with pytest.raises(ValueError, match=msg):
5052
tslib._test_parse_iso8601(date_str)
5153

5254

5355
def test_parsers_iso8601_invalid_offset_invalid():
5456
date_str = "2001-01-01 12-34-56"
55-
with pytest.raises(ValueError):
57+
msg = ("Timezone hours offset out of range "
58+
"in datetime string \"{s}\"".format(s=date_str))
59+
60+
with pytest.raises(ValueError, match=msg):
5661
tslib._test_parse_iso8601(date_str)
5762

5863

0 commit comments

Comments
 (0)