8000 Merge pull request #27993 from charris/backport-27992 · numpy/numpy@42fd84c · GitHub
[go: up one dir, main page]

Skip to content

Commit 42fd84c

Browse files
authored
Merge pull request #27993 from charris/backport-27992
BUG: Fix segfault in stringdtype lexsort
2 parents 852ad5b + 0282fc8 commit 42fd84c

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

numpy/_core/src/multiarray/item_selection.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,8 +2014,7 @@ PyArray_LexSort(PyObject *sort_keys, int axis)
20142014
}
20152015
rcode = argsort(its[j]->dataptr,
20162016
(npy_intp *)rit->dataptr, N, mps[j]);
2017-
if (rcode < 0 || (PyDataType_REFCHK 10000 (PyArray_DESCR(mps[j]))
2018-
&& PyErr_Occurred())) {
2017+
if (rcode < 0 || (object && PyErr_Occurred())) {
20192018
goto fail;
20202019
}
20212020
PyArray_ITER_NEXT(its[j]);

numpy/_core/tests/test_multiarray.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5374,6 +5374,13 @@ def test_object(self): # gh-6312
53745374
u, v = np.array(u, dtype='object'), np.array(v, dtype='object')
53755375
assert_array_equal(idx, np.lexsort((u, v)))
53765376

5377+
def test_strings(self): # gh-27984
5378+
for dtype in "TU":
5379+
surnames = np.array(['Hertz', 'Galilei', 'Hertz'], dtype=dtype)
5380+
first_names = np.array(['Heinrich', 'Galileo', 'Gustav'], dtype=dtype)
5381+
assert_array_equal(np.lexsort((first_names, surnames)), [1, 2, 0])
5382+
5383+
53775384
def test_invalid_axis(self): # gh-7528
53785385
x = np.linspace(0., 1., 42*3).reshape(42, 3)
53795386
assert_raises(AxisError, np.lexsort, x, axis=2)

numpy/_core/tests/test_stringdtype.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,19 @@ def test_sort(dtype, strings):
415415

416416
def test_sort(strings, arr_sorted):
417417
arr = np.array(strings, dtype=dtype)
418-
np.random.default_rng().shuffle(arr)
419418
na_object = getattr(arr.dtype, "na_object", "")
419+
if na_object is None and None in strings:
420+
with pytest.raises(
421+
ValueError,
422+
match="Cannot compare null that is not a nan-like value",
423+
):
424+
np.argsort(arr)
425+
argsorted = None
426+
elif na_object is pd_NA or na_object != '':
427+
argsorted = None
428+
else:
429+
argsorted = np.argsort(arr)
430+
np.random.default_rng().shuffle(arr)
420431
if na_object is None and None in strings:
421432
with pytest.raises(
422433
ValueError,
@@ -426,6 +437,9 @@ def test_sort(strings, arr_sorted):
426437
else:
427438
arr.sort()
428439
assert np.array_equal(arr, arr_sorted, equal_nan=True)
440+
if argsorted is not None:
441+
assert np.array_equal(argsorted, np.argsort(strings))
442+
429443

430444
# make a copy so we don't mutate the lists in the fixture
431445
strings = strings.copy()

0 commit comments

Comments
 (0)
0