Skip to content

REF: stronger typing in libconversion #46742

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 2 commits into from
Apr 16, 2022
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
3 changes: 2 additions & 1 deletion pandas/_libs/algos_common_helper.pxi.in
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ def ensure_{{name}}(object arr, copy=True):
if (<ndarray>arr).descr.type_num == NPY_{{c_type}}:
return arr
else:
return arr.astype(np.{{dtype}}, copy=copy)
# equiv: arr.astype(np.{{dtype}}, copy=copy)
return cnp.PyArray_Cast(<ndarray>arr, cnp.NPY_{{c_type}})
else:
return np.array(arr, dtype=np.{{dtype}})

Expand Down
6 changes: 5 additions & 1 deletion pandas/_libs/tslib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ cpdef array_to_datetime(
"""
cdef:
Py_ssize_t i, n = len(values)
object val, py_dt, tz, tz_out = None
object val, tz
ndarray[int64_t] iresult
ndarray[object] oresult
npy_datetimestruct dts
Expand All @@ -443,6 +443,8 @@ cpdef array_to_datetime(
float offset_seconds, tz_offset
set out_tzoffset_vals = set()
bint string_to_dts_failed
datetime py_dt
tzinfo tz_out = None

# specify error conditions
assert is_raise or is_ignore or is_coerce
Expand Down Expand Up @@ -647,6 +649,8 @@ cpdef array_to_datetime(
return result, tz_out


@cython.wraparound(False)
@cython.boundscheck(False)
cdef ndarray[object] ignore_errors_out_of_bounds_fallback(ndarray[object] values):
"""
Fallback for array_to_datetime if an OutOfBoundsDatetime is raised
Expand Down
59 changes: 31 additions & 28 deletions pandas/_libs/tslibs/conversion.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -581,55 +581,62 @@ cdef _TSObject _convert_str_to_tsobject(object ts, tzinfo tz, str unit,
"""
cdef:
npy_datetimestruct dts
int out_local = 0, out_tzoffset = 0
bint do_parse_datetime_string = False
int out_local = 0, out_tzoffset = 0, string_to_dts_failed
datetime dt
int64_t ival

if len(ts) == 0 or ts in nat_strings:
ts = NaT
obj = _TSObject()
obj.value = NPY_NAT
obj.tzinfo = tz
return obj
elif ts == 'now':
# Issue 9000, we short-circuit rather than going
# into np_datetime_strings which returns utc
ts = datetime.now(tz)
dt = datetime.now(tz)
elif ts == 'today':
# Issue 9000, we short-circuit rather than going
# into np_datetime_strings which returns a normalized datetime
ts = datetime.now(tz)
dt = datetime.now(tz)
# equiv: datetime.today().replace(tzinfo=tz)
else:
string_to_dts_failed = _string_to_dts(
ts, &dts, &out_local,
&out_tzoffset, False
)
try:
if not string_to_dts_failed:
if not string_to_dts_failed:
try:
check_dts_bounds(&dts)
if out_local == 1:
return _create_tsobject_tz_using_offset(dts,
out_tzoffset, tz)
else:
ts = dtstruct_to_dt64(&dts)
ival = dtstruct_to_dt64(&dts)
if tz is not None:
# shift for _localize_tso
ts = tz_localize_to_utc_single(ts, tz,
ambiguous="raise")
ival = tz_localize_to_utc_single(ival, tz,
ambiguous="raise")

except OutOfBoundsDatetime:
# GH#19382 for just-barely-OutOfBounds falling back to dateutil
# parser will return incorrect result because it will ignore
# nanoseconds
raise
return convert_to_tsobject(ival, tz, None, False, False)

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

if string_to_dts_failed or do_parse_datetime_string:
try:
ts = parse_datetime_string(ts, dayfirst=dayfirst,
yearfirst=yearfirst)
except (ValueError, OverflowError):
raise ValueError("could not convert string to Timestamp")
except ValueError:
# Fall through to parse_datetime_string
pass

try:
dt = parse_datetime_string(ts, dayfirst=dayfirst,
yearfirst=yearfirst)
except (ValueError, OverflowError):
raise ValueError("could not convert string to Timestamp")

return convert_to_tsobject(ts, tz, unit, dayfirst, yearfirst)
return convert_datetime_to_tsobject(dt, tz)


cdef inline check_overflows(_TSObject obj):
Expand Down Expand Up @@ -688,12 +695,8 @@ cdef inline void _localize_tso(_TSObject obj, tzinfo tz):
Sets obj.tzinfo inplace, alters obj.dts inplace.
"""
cdef:
ndarray[int64_t] trans
int64_t[::1] deltas
int64_t local_val
int64_t* tdata
Py_ssize_t pos, ntrans, outpos = -1
str typ
Py_ssize_t outpos = -1

assert obj.tzinfo is None

Expand Down
1 change: 1 addition & 0 deletions pandas/_libs/tslibs/timestamps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ cdef class _Timestamp(ABCTimestamp):
elif is_datetime64_object(other):
return type(self)(other) - self
return NotImplemented

# -----------------------------------------------------------------

cdef int64_t _maybe_convert_value_to_local(self):
Expand Down
1 change: 1 addition & 0 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,7 @@ def _local_timestamps(self) -> np.ndarray:
were timezone-naive.
"""
if self.tz is None or timezones.is_utc(self.tz):
# Avoid the copy that would be made in tzconversion
return self.asi8
return tzconversion.tz_convert_from_utc(self.asi8, self.tz)

Expand Down