@@ -72,23 +72,50 @@ cdef inline void set_array_not_contiguous(ndarray ao) nogil:
7272 (NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_F_CONTIGUOUS))
7373
7474
75- cdef inline object get_value_at(ndarray arr, object loc):
75+ cdef inline Py_ssize_t validate_indexer(ndarray arr, object loc) except - 1 :
76+ """
77+ Cast the given indexer `loc` to an integer. If it is negative, i.e. a
78+ python-style indexing-from-the-end indexer, translate it to a
79+ from-the-front indexer. Raise if this is not possible.
80+
81+ Parameters
82+ ----------
83+ arr : ndarray
84+ loc : object
85+
86+ Returns
87+ -------
88+ idx : Py_ssize_t
89+
90+ Raises
91+ ------
92+ IndexError
93+ """
7694 cdef:
77- Py_ssize_t i, sz
95+ Py_ssize_t idx, size
7896 int casted
7997
8098 if is_float_object(loc):
8199 casted = int (loc)
82100 if casted == loc:
83101 loc = casted
84- i = < Py_ssize_t> loc
85- sz = cnp.PyArray_SIZE(arr)
86102
87- if i < 0 and sz > 0 :
88- i += sz
89- elif i >= sz or sz == 0 :
103+ idx = < Py_ssize_t> loc
104+ size = cnp.PyArray_SIZE(arr)
105+
106+ if idx < 0 and size > 0 :
107+ idx += size
108+ if idx >= size or size == 0 or idx < 0 :
90109 raise IndexError (' index out of bounds' )
91110
111+ return idx
112+
113+
114+ cdef inline object get_value_at(ndarray arr, object loc):
115+ cdef:
116+ Py_ssize_t i
117+
118+ i = validate_indexer(arr, loc)
92119 return get_value_1d(arr, i)
93120
94121
@@ -99,19 +126,9 @@ cdef inline set_value_at_unsafe(ndarray arr, object loc, object value):
99126 flag above the loop and then eschew the check on each iteration.
100127 """
101128 cdef:
102- Py_ssize_t i, sz
103- if is_float_object(loc):
104- casted = int (loc)
105- if casted == loc:
106- loc = casted
107- i = < Py_ssize_t> loc
108- sz = cnp.PyArray_SIZE(arr)
109-
110- if i < 0 :
111- i += sz
112- elif i >= sz:
113- raise IndexError (' index out of bounds' )
129+ Py_ssize_t i
114130
131+ i = validate_indexer(arr, loc)
115132 assign_value_1d(arr, i, value)
116133
117134
0 commit comments