Skip to content

Commit

Permalink
BUG: fix a crash when retrieving rows from a multiple-index table
Browse files Browse the repository at this point in the history
  • Loading branch information
neutrinoceros committed Feb 10, 2024
1 parent b299eb5 commit 288186d
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 7 deletions.
21 changes: 16 additions & 5 deletions astropy/table/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,19 @@
c[1:2] -> reference
array.view(Column) -> no indices
"""
from __future__ import annotations

from copy import deepcopy
from typing import TYPE_CHECKING

import numpy as np

from .bst import MaxValue, MinValue
from .sorted_array import SortedArray

if TYPE_CHECKING:
from collections.abc import Iterable


class QueryError(ValueError):
"""
Expand Down Expand Up @@ -827,21 +832,27 @@ def __init__(self, table):
self.table = table
self.indices = table.indices

def _get_rows(self, item):
def _get_rows(
self,
item: int | Iterable[int] | slice | tuple[str, slice],
) -> list[np.int64]:
"""
Retrieve Table rows indexes by value slice.
"""
if len(self.indices) == 0:
raise ValueError("Can only use TableLoc for a table with indices")

if isinstance(item, tuple):
if (

Check warning on line 845 in astropy/table/index.py

View check run for this annotation

Codecov / codecov/patch

astropy/table/index.py#L845

Added line #L845 was not covered by tests
isinstance(item, tuple)
and len(item) == 2
and isinstance(item[0], str)
and isinstance(item[1], slice)
):
key, item = item
else:
key = self.table.primary_key

index = self.indices[key]
if len(index.columns) > 1:
raise ValueError("Cannot use .loc on multi-column indices")

if isinstance(item, slice):
# None signifies no upper/lower bound
Expand All @@ -854,7 +865,7 @@ def _get_rows(self, item):
# item should be a list or ndarray of values
rows = []
for key in item:
p = index.find((key,))
p = index.find(key if isinstance(key, tuple) else (key,))

Check warning on line 868 in astropy/table/index.py

View check run for this annotation

Codecov / codecov/patch

astropy/table/index.py#L868

Added line #L868 was not covered by tests
if len(p) == 0:
raise KeyError(f"No matches found for key {key}")
else:
Expand Down
3 changes: 1 addition & 2 deletions astropy/table/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -1023,8 +1023,7 @@ def indices(self):
def loc(self):
"""
Return a TableLoc object that can be used for retrieving
rows by index in a given data range. Note that both loc
and iloc work only with single-column indices.
rows by index in a given data range.
"""
return TableLoc(self)

Expand Down
11 changes: 11 additions & 0 deletions astropy/table/tests/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,17 @@ def test_table_loc_indices(self, main_col, table_types, engine):
for i, p in zip(t2, [1, 4, 2]): # same order as input list
assert i == p - 1

def test_multiple_index_loc(self, main_col, table_types):
# see https://github.com/astropy/astropy/issues/13176
if isinstance(main_col, Time):
pytest.skip()
self._setup(main_col, table_types)
t = self.t
t.add_index(["a", "b"])
t2 = t.loc[(1, 4.0)]
assert_col_equal(t2["a"], [1])
assert_col_equal(t2["b"], [4.0])

def test_invalid_search(self, main_col, table_types, engine):
# using .loc and .loc_indices with a value not present should raise an exception
self._setup(main_col, table_types)
Expand Down
1 change: 1 addition & 0 deletions docs/changes/table/15826.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a crash when retrieving rows from a multiple-index table.

0 comments on commit 288186d

Please sign in to comment.