Skip to content

Commit

Permalink
Add bool to supported types and improve type specification. (#141)
Browse files Browse the repository at this point in the history
This adds boolean to the supported sparse coordinate types and also
improves the type definition of coordinate types to ensure that the
values in each type are homogeneous:

    BadCoord = Union[int, str]
    BadCoords = Union[BadCoord, Sequence[BadCoord]]
    # ["this", 1] is bad, but is a valid as a BadCoords value

    GoodCoord = TypeVar("GoodCoord", int, str)
    GoodCoords = Union[GoodCoord, Sequence[GoodCoord]]
    # ["this", 1] is bad, and is *not* valid as a GoodCoords value
    # ["this", "that"] is a valid as a GoodCoords value
    # [1, 2] is valid as a GoodCoords value
  • Loading branch information
thetorpedodog authored Feb 24, 2023
1 parent b337106 commit 4027413
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 19 deletions.
44 changes: 25 additions & 19 deletions python-spec/src/somacore/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

import enum
from typing import Any, Mapping, Optional, Sequence, Union
from typing import Any, Mapping, Optional, Sequence, TypeVar, Union

import attrs
import numpy as np
Expand Down Expand Up @@ -110,36 +110,42 @@ class ResultOrder(enum.Enum):
ResultOrderStr = Union[ResultOrder, Literal["auto", "row-major", "column-major"]]
"""A ResultOrder, or the str representing it."""


DenseCoord = Union[None, int, types.Slice[int]]
# Coordinate types are specified as TypeVars instead of Unions to ensure that
# sequences and slices are homogeneous:
#
# BadCoord = Union[int, str]
# BadCoords = Union[BadCoord, Sequence[BadCoord]]
# # ["this", 1] is bad, but is a valid as a BadCoords value
#
# GoodCoord = TypeVar("GoodCoord", int, str)
# GoodCoords = Union[GoodCoord, Sequence[GoodCoord]]
# # ["this", 1] is bad, and is *not* valid as a GoodCoords value
# # ["this", "that"] is a valid as a GoodCoords value
# # [1, 2] is valid as a GoodCoords value

DenseCoord = TypeVar("DenseCoord", None, int, types.Slice[int])
"""A single coordinate range for reading dense data.
``None`` indicates the entire domain of a dimension; values of this type are
not ``Optional``, but may be ``None``.
"""


DenseNDCoords = Sequence[DenseCoord]
"""A sequence of ranges to read dense data."""

# TODO: Add support for non-integer types.
SparseCoord = TypeVar(
"SparseCoord", bytes, float, int, slice, str, np.datetime64, pa.TimestampType
)
"""Types that can be put into a single sparse coordinate."""

# NOTE: Keep this in sync with the types accepted in `_canonicalize_coord`
# in ./query/axis.py.
# https://github.com/single-cell-data/TileDB-SOMA/issues/960
SparseDFCoord = Union[
DenseCoord,
float,
np.datetime64,
pa.TimestampType,
Sequence[int],
Sequence[float],
Sequence[str],
Sequence[bytes],
Sequence[np.datetime64],
Sequence[pa.TimestampType],
types.Slice[float],
types.Slice[str],
types.Slice[bytes],
types.Slice[np.datetime64],
types.Slice[pa.TimestampType],
SparseCoord,
Sequence[SparseCoord],
types.Slice[SparseCoord],
pa.Array,
pa.ChunkedArray,
npt.NDArray[np.integer],
Expand Down
1 change: 1 addition & 0 deletions python-spec/src/somacore/query/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def _canonicalize_coord(coord: options.SparseDFCoord) -> options.SparseDFCoord:
if coord is None or isinstance(
coord,
(
bool,
bytes,
float,
int,
Expand Down
1 change: 1 addition & 0 deletions python-spec/testing/test_query_axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
(slice(np.datetime64(946684802, "s"), np.datetime64(946684803, "s")),),
),
(("string-coord", [b"lo", b"hi"]), ("string-coord", (b"lo", b"hi"))),
((slice(4, 5), True, None), (slice(4, 5), True, None)),
],
)
def test_canonicalization(coords: Any, want: Tuple[options.SparseDFCoord, ...]) -> None:
Expand Down

0 comments on commit 4027413

Please sign in to comment.