Skip to content

Commit 135b215

Browse files
jbrockmendelsimonjayhawkins
authored andcommitted
Backport PR #37613 on branch 1.1.x: BUG: read-only values in cython funcs
1 parent d601416 commit 135b215

File tree

8 files changed

+32
-7
lines changed

8 files changed

+32
-7
lines changed

doc/source/whatsnew/v1.1.5.rst

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Fixed regressions
2424
Bug fixes
2525
~~~~~~~~~
2626
- Bug in metadata propagation for ``groupby`` iterator (:issue:`37343`)
27+
- Bug in :func:`to_datetime` and :func:`to_timedelta` with a read-only array incorrectly raising (:issue:`34857`)
2728
-
2829

2930
.. ---------------------------------------------------------------------------

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
@@ -226,7 +226,7 @@ cdef convert_to_timedelta64(object ts, str unit):
226226

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

pandas/core/arrays/datetimelike.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1334,9 +1334,8 @@ def _addsub_object_array(self, other: np.ndarray, op):
13341334
result : same class as self
13351335
"""
13361336
assert op in [operator.add, operator.sub]
1337-
if len(other) == 1:
1337+
if len(other) == 1 and self.ndim == 1:
13381338
# If both 1D then broadcasting is unambiguous
1339-
# TODO(EA2D): require self.ndim == other.ndim here
13401339
return op(self, other[0])
13411340

13421341
warnings.warn(

pandas/tests/test_join.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,14 @@ def test_outer_join_indexer(self, dtype):
4343
tm.assert_numpy_array_equal(rindexer, exp)
4444

4545

46-
def test_left_join_indexer_unique():
46+
@pytest.mark.parametrize("readonly", [True, False])
47+
def test_left_join_indexer_unique(readonly):
4748
a = np.array([1, 2, 3, 4, 5], dtype=np.int64)
4849
b = np.array([2, 2, 3, 4, 4], dtype=np.int64)
50+
if readonly:
51+
# GH#37312, GH#37264
52+
a.setflags(write=False)
53+
b.setflags(write=False)
4954

5055
result = _join.left_join_indexer_unique(b, a)
5156
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)