Skip to content

REF: Cleanups, typing, memoryviews in tslibs #23368

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

Closed
wants to merge 9 commits into from
2 changes: 1 addition & 1 deletion pandas/_libs/tslibs/ccalendar.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ weekday_to_int = {int_to_weekday[key]: key for key in int_to_weekday}

@cython.wraparound(False)
@cython.boundscheck(False)
cpdef inline int32_t get_days_in_month(int year, Py_ssize_t month) nogil:
Copy link
Contributor

Choose a reason for hiding this comment

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

does this not do anything?

Copy link
Member Author

Choose a reason for hiding this comment

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

AFAICT the "inline" doesn't get carried across modules in this context. Since the function is never called from within ccalendar, its not accomplishing anything.

cpdef int32_t get_days_in_month(int year, Py_ssize_t month) nogil:
"""Return the number of days in the given month of the given year.

Parameters
Expand Down
40 changes: 24 additions & 16 deletions pandas/_libs/tslibs/conversion.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ cdef inline int64_t get_datetime64_nanos(object val) except? -1:

@cython.boundscheck(False)
@cython.wraparound(False)
def ensure_datetime64ns(ndarray arr, copy=True):
def ensure_datetime64ns(arr: ndarray, copy: bool=True):
"""
Ensure a np.datetime64 array has dtype specifically 'datetime64[ns]'

Expand Down Expand Up @@ -122,7 +122,7 @@ def ensure_datetime64ns(ndarray arr, copy=True):
return result


def ensure_timedelta64ns(ndarray arr, copy=True):
def ensure_timedelta64ns(arr: ndarray, copy: bint=True):
"""
Ensure a np.timedelta64 array has dtype specifically 'timedelta64[ns]'

Expand All @@ -134,14 +134,14 @@ def ensure_timedelta64ns(ndarray arr, copy=True):
Returns
-------
result : ndarray with dtype timedelta64[ns]

"""
return arr.astype(TD_DTYPE, copy=copy)
# TODO: check for overflows when going from a lower-resolution to nanos


@cython.boundscheck(False)
@cython.wraparound(False)
def datetime_to_datetime64(object[:] values):
def datetime_to_datetime64(values: object[:]):
"""
Convert ndarray of datetime-like objects to int64 array representing
nanosecond timestamps.
Expand Down Expand Up @@ -614,6 +614,8 @@ cpdef inline datetime localize_pydatetime(datetime dt, object tz):
# ----------------------------------------------------------------------
# Timezone Conversion

@cython.boundscheck(False)
@cython.wraparound(False)
cdef inline int64_t[:] _tz_convert_dst(int64_t[:] values, tzinfo tz,
bint to_utc=True):
"""
Expand Down Expand Up @@ -852,14 +854,14 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
localized : ndarray[int64_t]
"""
cdef:
ndarray[int64_t] trans
ndarray[int64_t] trans, result_a, result_b
int64_t[:] deltas, idx_shifted
ndarray ambiguous_array
Py_ssize_t i, idx, pos, ntrans, n = len(vals)
Py_ssize_t delta_idx_offset, delta_idx
int64_t *tdata
int64_t[:] result, dst_hours, idx_shifted_left, idx_shifted_right
int64_t v, left, right, val, v_left, v_right, new_local, remaining_mins
ndarray[int64_t] result, result_a, result_b, dst_hours
Py_ssize_t i, idx, pos, pos_left, pos_right, ntrans, n = len(vals)
Py_ssize_t delta_idx, delta_idx_offset
int64_t *tdata
ndarray ambiguous_array
npy_datetimestruct dts
bint infer_dst = False, is_dst = False, fill = False
bint shift = False, fill_nonexist = False
Expand All @@ -874,7 +876,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
for i in range(n):
v = vals[i]
result[i] = _tz_convert_tzlocal_utc(v, tz, to_utc=True)
return result
return np.asarray(result)

if is_string_object(ambiguous):
if ambiguous == 'infer':
Expand Down Expand Up @@ -936,7 +938,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,

if infer_dst:
dst_hours = np.empty(n, dtype=np.int64)
dst_hours.fill(NPY_NAT)
dst_hours[:] = NPY_NAT

# Get the ambiguous hours (given the above, these are the hours
# where result_a != result_b and neither of them are NAT)
Expand Down Expand Up @@ -977,7 +979,13 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
# Pull the only index and adjust
a_idx = grp[:switch_idx]
b_idx = grp[switch_idx:]
dst_hours[grp] = np.hstack((result_a[a_idx], result_b[b_idx]))

# __setitem__ on dst_hours.base because indexing with
Copy link
Contributor

Choose a reason for hiding this comment

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

i would really rather not use .base

# an ndarray (grp) directly on a memoryview is not supported
# TODO: is `grp` necessarily contiguous? i.e. could we
# equivalently write dst_hours[grp[0]:grp[-1]] = ... ?
dst_hours.base[grp] = np.hstack((result_a[a_idx],
result_b[b_idx]))

for i in range(n):
val = vals[i]
Expand Down Expand Up @@ -1026,7 +1034,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
stamp = _render_tstamp(val)
raise pytz.NonExistentTimeError(stamp)

return result
return np.asarray(result)


cdef inline bisect_right_i8(int64_t *data, int64_t val, Py_ssize_t n):
Expand Down Expand Up @@ -1128,7 +1136,7 @@ def normalize_i8_timestamps(int64_t[:] stamps, object tz=None):
dt64_to_dtstruct(stamps[i], &dts)
result[i] = _normalized_stamp(&dts)

return result.base # .base to access underlying np.ndarray
return np.asarray(result)


@cython.wraparound(False)
Expand Down Expand Up @@ -1220,7 +1228,7 @@ cdef inline int64_t _normalized_stamp(npy_datetimestruct *dts) nogil:

@cython.wraparound(False)
@cython.boundscheck(False)
def is_date_array_normalized(int64_t[:] stamps, tz=None):
def is_date_array_normalized(int64_t[:] stamps, object tz=None):
"""
Check if all of the given (nanosecond) timestamps are normalized to
midnight, i.e. hour == minute == second == 0. If the optional timezone
Expand Down
Loading