Skip to content

Commit e5518f6

Browse files
committed
tslibs cleanup, typing, memoryviews
1 parent aed5689 commit e5518f6

File tree

11 files changed

+98
-113
lines changed

11 files changed

+98
-113
lines changed

pandas/_libs/missing.pxd

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# -*- coding: utf-8 -*-
22

3-
from tslibs.nattype cimport is_null_datetimelike
4-
53
cpdef bint checknull(object val)
64
cpdef bint checknull_old(object val)
75

pandas/_libs/tslibs/ccalendar.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ weekday_to_int = {int_to_weekday[key]: key for key in int_to_weekday}
5454

5555
@cython.wraparound(False)
5656
@cython.boundscheck(False)
57-
cpdef inline int32_t get_days_in_month(int year, Py_ssize_t month) nogil:
57+
cpdef int32_t get_days_in_month(int year, Py_ssize_t month) nogil:
5858
"""Return the number of days in the given month of the given year.
5959
6060
Parameters

pandas/_libs/tslibs/conversion.pyx

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ TD_DTYPE = np.dtype('m8[ns]')
4949

5050
UTC = pytz.UTC
5151

52+
5253
# ----------------------------------------------------------------------
5354
# Misc Helpers
5455

55-
# TODO: How to declare np.datetime64 as the input type?
5656
cdef inline int64_t get_datetime64_nanos(object val) except? -1:
5757
"""
5858
Extract the value and unit from a np.datetime64 object, then convert the
@@ -74,7 +74,7 @@ cdef inline int64_t get_datetime64_nanos(object val) except? -1:
7474
return ival
7575

7676

77-
def ensure_datetime64ns(ndarray arr, copy=True):
77+
def ensure_datetime64ns(arr: ndarray, copy: bint = True):
7878
"""
7979
Ensure a np.datetime64 array has dtype specifically 'datetime64[ns]'
8080
@@ -121,7 +121,7 @@ def ensure_datetime64ns(ndarray arr, copy=True):
121121
return result
122122

123123

124-
def ensure_timedelta64ns(ndarray arr, copy=True):
124+
def ensure_timedelta64ns(arr: ndarray, copy: bint = True):
125125
"""
126126
Ensure a np.timedelta64 array has dtype specifically 'timedelta64[ns]'
127127
@@ -133,23 +133,23 @@ def ensure_timedelta64ns(ndarray arr, copy=True):
133133
Returns
134134
-------
135135
result : ndarray with dtype timedelta64[ns]
136-
137136
"""
138137
return arr.astype(TD_DTYPE, copy=copy)
138+
# TODO: check for overflows when going from a lower-resolution to nanos
139139

140140

141-
def datetime_to_datetime64(object[:] values):
141+
def datetime_to_datetime64(values: object[:]):
142142
"""
143143
Convert ndarray of datetime-like objects to int64 array representing
144144
nanosecond timestamps.
145145
146146
Parameters
147147
----------
148-
values : ndarray
148+
values : ndarray[object]
149149
150150
Returns
151151
-------
152-
result : ndarray with dtype int64
152+
result : ndarray[int64_t]
153153
inferred_tz : tzinfo or None
154154
"""
155155
cdef:
@@ -225,6 +225,7 @@ cdef class _TSObject:
225225

226226
@property
227227
def value(self):
228+
# This is needed in order for `value` to be accessible in lib.pyx
228229
return self.value
229230

230231

@@ -849,10 +850,11 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
849850
ndarray[int64_t] trans
850851
int64_t[:] deltas, idx_shifted
851852
ndarray ambiguous_array
852-
Py_ssize_t i, idx, pos, ntrans, n = len(vals)
853+
Py_ssize_t i, idx, pos, pos_left, pos_right, ntrans, n = len(vals)
853854
int64_t *tdata
854-
int64_t v, left, right, val, v_left, v_right
855-
ndarray[int64_t] result, result_a, result_b, dst_hours
855+
int64_t v, left, right, val, v_left, v_right, delta_idx
856+
int64_t[:] result, dst_hours, idx_shifted_left, idx_shifted_right
857+
ndarray[int64_t] result_a, result_b
856858
npy_datetimestruct dts
857859
bint infer_dst = False, is_dst = False, fill = False
858860
bint shift = False, fill_nonexist = False
@@ -867,7 +869,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
867869
for i in range(n):
868870
v = vals[i]
869871
result[i] = _tz_convert_tzlocal_utc(v, tz, to_utc=True)
870-
return result
872+
return result.base # `.base` to access underlying np.array
871873

872874
if is_string_object(ambiguous):
873875
if ambiguous == 'infer':
@@ -929,7 +931,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
929931

930932
if infer_dst:
931933
dst_hours = np.empty(n, dtype=np.int64)
932-
dst_hours.fill(NPY_NAT)
934+
dst_hours[:] = NPY_NAT
933935

934936
# Get the ambiguous hours (given the above, these are the hours
935937
# where result_a != result_b and neither of them are NAT)
@@ -970,7 +972,13 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
970972
# Pull the only index and adjust
971973
a_idx = grp[:switch_idx]
972974
b_idx = grp[switch_idx:]
973-
dst_hours[grp] = np.hstack((result_a[a_idx], result_b[b_idx]))
975+
976+
# __setitem__ on dst_hours.base because indexing with
977+
# an ndarray (grp) directly on a memoryview is not supported
978+
# TODO: is `grp` necessarily contiguous? i.e. could we
979+
# equivalently write dst_hours[grp[0]:grp[-1]] = ... ?
980+
dst_hours.base[grp] = np.hstack((result_a[a_idx],
981+
result_b[b_idx]))
974982

975983
for i in range(n):
976984
val = vals[i]
@@ -1015,7 +1023,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
10151023
stamp = _render_tstamp(val)
10161024
raise pytz.NonExistentTimeError(stamp)
10171025

1018-
return result
1026+
return result.base # `.base` to access underlying np.array
10191027

10201028

10211029
cdef inline bisect_right_i8(int64_t *data, int64_t val, Py_ssize_t n):
@@ -1051,7 +1059,7 @@ cdef inline str _render_tstamp(int64_t val):
10511059
# Normalization
10521060

10531061

1054-
def normalize_date(object dt):
1062+
def normalize_date(dt: object) -> datetime:
10551063
"""
10561064
Normalize datetime.datetime value to midnight. Returns datetime.date as a
10571065
datetime.datetime at midnight
@@ -1085,7 +1093,7 @@ def normalize_date(object dt):
10851093

10861094
@cython.wraparound(False)
10871095
@cython.boundscheck(False)
1088-
def normalize_i8_timestamps(int64_t[:] stamps, tz=None):
1096+
def normalize_i8_timestamps(int64_t[:] stamps, object tz=None):
10891097
"""
10901098
Normalize each of the (nanosecond) timestamps in the given array by
10911099
rounding down to the beginning of the day (i.e. midnight). If `tz`
@@ -1122,7 +1130,7 @@ def normalize_i8_timestamps(int64_t[:] stamps, tz=None):
11221130

11231131
@cython.wraparound(False)
11241132
@cython.boundscheck(False)
1125-
cdef int64_t[:] _normalize_local(int64_t[:] stamps, object tz):
1133+
cdef int64_t[:] _normalize_local(int64_t[:] stamps, tzinfo tz):
11261134
"""
11271135
Normalize each of the (nanosecond) timestamps in the given array by
11281136
rounding down to the beginning of the day (i.e. midnight) for the
@@ -1131,7 +1139,7 @@ cdef int64_t[:] _normalize_local(int64_t[:] stamps, object tz):
11311139
Parameters
11321140
----------
11331141
stamps : int64 ndarray
1134-
tz : tzinfo or None
1142+
tz : tzinfo
11351143
11361144
Returns
11371145
-------
@@ -1207,7 +1215,7 @@ cdef inline int64_t _normalized_stamp(npy_datetimestruct *dts) nogil:
12071215
return dtstruct_to_dt64(dts)
12081216

12091217

1210-
def is_date_array_normalized(int64_t[:] stamps, tz=None):
1218+
def is_date_array_normalized(int64_t[:] stamps, object tz=None):
12111219
"""
12121220
Check if all of the given (nanosecond) timestamps are normalized to
12131221
midnight, i.e. hour == minute == second == 0. If the optional timezone

0 commit comments

Comments
 (0)