Skip to content

Commit 1c6cd01

Browse files
authored
BUG: read-only values in cython funcs (#37613)
1 parent cc9c646 commit 1c6cd01

File tree

8 files changed

+33
-7
lines changed

8 files changed

+33
-7
lines changed

doc/source/whatsnew/v1.2.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -399,11 +399,13 @@ Datetimelike
399399
- Bug in :meth:`TimedeltaIndex.sum` and :meth:`Series.sum` with ``timedelta64`` dtype on an empty index or series returning ``NaT`` instead of ``Timedelta(0)`` (:issue:`31751`)
400400
- Bug in :meth:`DatetimeArray.shift` incorrectly allowing ``fill_value`` with a mismatched timezone (:issue:`37299`)
401401
- Bug in adding a :class:`BusinessDay` with nonzero ``offset`` to a non-scalar other (:issue:`37457`)
402+
- Bug in :func:`to_datetime` with a read-only array incorrectly raising (:issue:`34857`)
402403

403404
Timedelta
404405
^^^^^^^^^
405406
- Bug in :class:`TimedeltaIndex`, :class:`Series`, and :class:`DataFrame` floor-division with ``timedelta64`` dtypes and ``NaT`` in the denominator (:issue:`35529`)
406407
- Bug in parsing of ISO 8601 durations in :class:`Timedelta`, :meth:`pd.to_datetime` (:issue:`37159`, fixes :issue:`29773` and :issue:`36204`)
408+
- Bug in :func:`to_timedelta` with a read-only array incorrectly raising (:issue:`34857`)
407409

408410
Timezones
409411
^^^^^^^^^

pandas/_libs/join.pyx

+1-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ ctypedef fused join_t:
268268

269269
@cython.wraparound(False)
270270
@cython.boundscheck(False)
271-
def left_join_indexer_unique(join_t[:] left, join_t[:] right):
271+
def left_join_indexer_unique(ndarray[join_t] left, ndarray[join_t] right):
272272
cdef:
273273
Py_ssize_t i, j, nleft, nright
274274
ndarray[int64_t] indexer

pandas/_libs/tslibs/strptime.pyx

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ from _thread import allocate_lock as _thread_allocate_lock
1212
import numpy as np
1313
import pytz
1414

15-
from numpy cimport int64_t
15+
from numpy cimport int64_t, ndarray
1616

1717
from pandas._libs.tslibs.nattype cimport (
1818
NPY_NAT,
@@ -51,7 +51,7 @@ cdef dict _parse_code_table = {'y': 0,
5151
'u': 22}
5252

5353

54-
def array_strptime(object[:] values, object fmt, bint exact=True, errors='raise'):
54+
def array_strptime(ndarray[object] values, object fmt, bint exact=True, errors='raise'):
5555
"""
5656
Calculates the datetime structs represented by the passed array of strings
5757

pandas/_libs/tslibs/timedeltas.pyx

+1-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ cdef convert_to_timedelta64(object ts, str unit):
227227

228228
@cython.boundscheck(False)
229229
@cython.wraparound(False)
230-
def array_to_timedelta64(object[:] values, str unit=None, str errors="raise"):
230+
def array_to_timedelta64(ndarray[object] values, str unit=None, str errors="raise"):
231231
"""
232232
Convert an ndarray to an array of timedeltas. If errors == 'coerce',
233233
coerce non-convertible objects to NaT. Otherwise, raise.

pandas/core/arrays/datetimelike.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1025,9 +1025,8 @@ def _addsub_object_array(self, other: np.ndarray, op):
10251025
result : same class as self
10261026
"""
10271027
assert op in [operator.add, operator.sub]
1028-
if len(other) == 1:
1028+
if len(other) == 1 and self.ndim == 1:
10291029
# If both 1D then broadcasting is unambiguous
1030-
# TODO(EA2D): require self.ndim == other.ndim here
10311030
return op(self, other[0])
10321031

10331032
warnings.warn(

pandas/tests/libs/test_join.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,14 @@ def test_cython_inner_join(self):
135135
tm.assert_numpy_array_equal(rs, exp_rs, check_dtype=False)
136136

137137

138-
def test_left_join_indexer_unique():
138+
@pytest.mark.parametrize("readonly", [True, False])
139+
def test_left_join_indexer_unique(readonly):
139140
a = np.array([1, 2, 3, 4, 5], dtype=np.int64)
140141
b = np.array([2, 2, 3, 4, 4], dtype=np.int64)
142+
if readonly:
143+
# GH#37312, GH#37264
144+
a.setflags(write=False)
145+
b.setflags(write=False)
141146

142147
result = libjoin.left_join_indexer_unique(b, a)
143148
expected = np.array([1, 1, 2, 3, 3], dtype=np.int64)

pandas/tests/tools/test_to_datetime.py

+10
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@
3636

3737

3838
class TestTimeConversionFormats:
39+
@pytest.mark.parametrize("readonly", [True, False])
40+
def test_to_datetime_readonly(self, readonly):
41+
# GH#34857
42+
arr = np.array([], dtype=object)
43+
if readonly:
44+
arr.setflags(write=False)
45+
result = to_datetime(arr)
46+
expected = to_datetime([])
47+
tm.assert_index_equal(result, expected)
48+
3949
@pytest.mark.parametrize("cache", [True, False])
4050
def test_to_datetime_format(self, cache):
4151
values = ["1/1/2000", "1/2/2000", "1/3/2000"]

pandas/tests/tools/test_to_timedelta.py

+10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99

1010

1111
class TestTimedeltas:
12+
@pytest.mark.parametrize("readonly", [True, False])
13+
def test_to_timedelta_readonly(self, readonly):
14+
# GH#34857
15+
arr = np.array([], dtype=object)
16+
if readonly:
17+
arr.setflags(write=False)
18+
result = to_timedelta(arr)
19+
expected = to_timedelta([])
20+
tm.assert_index_equal(result, expected)
21+
1222
def test_to_timedelta(self):
1323

1424
result = to_timedelta(["", ""])

0 commit comments

Comments
 (0)