Skip to content

Commit

Permalink
Bump min Python version to 3.7 & drop vendored singledispatchmethod
Browse files Browse the repository at this point in the history
  • Loading branch information
gsakkis committed Feb 18, 2023
1 parent 7c7d567 commit f18e0f0
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 84 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python: ['3.7', '3.8', '3.9', '3.10']
python: ['3.8', '3.9', '3.10']
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
- name: Upgrade pip
run: pip install --upgrade pip
- name: Run pre-commit hooks
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python == '3.9' }}
run: |
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@
"Natural Language :: English",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Physics",
"Topic :: Software Development :: Libraries",
Expand Down
36 changes: 0 additions & 36 deletions tiledb/segy/singledispatchmethod.py

This file was deleted.

49 changes: 27 additions & 22 deletions tiledb/segy/structured.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import itertools as it
from typing import List, Tuple, Union, cast
from functools import singledispatchmethod
from typing import List, Tuple, Union, cast, overload

import numpy as np
from segyio import TraceSortingFormat

import tiledb

from .singledispatchmethod import singledispatchmethod # type: ignore
from .types import Ellipsis, Index, NestedFieldList, cached_property, ellipsis
from .types import (
Ellipsis,
ExtendedIndex,
ExtendedIndices,
Index,
NestedFieldList,
cached_property,
)
from .unstructured import Header, Segy, TraceIndexer


class StructuredTraceIndexer(TraceIndexer):
@singledispatchmethod
def __getitem__(self, i: object) -> None:
raise TypeError(f"Cannot index by {i.__class__}")
def __getitem__(self, trace_index: Index) -> Tuple[ExtendedIndices, ExtendedIndex]:
if isinstance(trace_index, int):
return np.unravel_index(trace_index, self._shape), Ellipsis

@__getitem__.register(int)
@__getitem__.register(np.integer)
def _get_one(self, trace_index: int) -> Tuple[Tuple[int, ...], ellipsis]:
return np.unravel_index(trace_index, self._shape), Ellipsis

@__getitem__.register(slice)
def _get_many(self, trace_index: slice) -> Tuple[Tuple[List[int], ...], List[int]]:
# get indices in 1D (trace index) and 3D (fast-slow-offset indices)
raveled_indices = np.arange(len(self))[trace_index]
unraveled_indices = np.unravel_index(raveled_indices, self._shape)
Expand Down Expand Up @@ -55,20 +55,22 @@ def __init__(self, labels: np.ndarray):
self._sorter = labels.argsort()

@singledispatchmethod
def __getitem__(self, i: object) -> None:
def _get_index(self, i: Index) -> Union[int, List[int]]:
raise TypeError(f"Cannot index by {i.__class__}")

@__getitem__.register(int)
@__getitem__.register(np.integer)
def _get_one(self, label: int) -> int:
@overload
@_get_index.register(np.integer)
@_get_index.register
def __getitem__(self, label: int) -> int:
indices = np.flatnonzero(label == self._labels)
assert indices.size <= 1, indices
if indices.size == 0:
raise ValueError(f"{label} is not in labels")
return int(indices[0])

@__getitem__.register(slice)
def _get_many(self, label_slice: slice) -> List[int]:
@overload
@_get_index.register
def __getitem__(self, label_slice: slice) -> List[int]:
start, stop, step = label_slice.start, label_slice.stop, label_slice.step
increasing = step is None or step > 0
if start is None and increasing:
Expand All @@ -82,6 +84,9 @@ def _get_many(self, label_slice: slice) -> List[int]:
]
return list(indices[self._labels[indices] == label_range])

def __getitem__(self, i: Index) -> Union[int, List[int]]:
return self._get_index(i)


class Line:
def __init__(
Expand Down Expand Up @@ -111,9 +116,9 @@ def __getitem__(self, i: Union[Index, Tuple[Index, Index]]) -> np.ndarray:

_dims = property(lambda self: [dim.name for dim in self._tdb.schema.domain])

def _get_tdb_indices(self, labels: Index, offsets: Index) -> Tuple[Index, ...]:
def _get_tdb_indices(self, labels: Index, offsets: Index) -> ExtendedIndices:
dims = self._dims
composite_index = [slice(None)] * self._tdb.ndim
composite_index: List[ExtendedIndex] = [slice(None)] * self._tdb.ndim
composite_index[dims.index(self.name)] = self._label_indexer[labels]
composite_index[dims.index("offsets")] = self._offset_indexer[offsets]
return tuple(composite_index)
Expand Down Expand Up @@ -185,7 +190,7 @@ def __getitem__(self, t: Tuple[Index, ...]) -> np.ndarray:
offsets = self._default_offset

dims = tuple(dim.name for dim in self._tdb.schema.domain)
composite_index = [None] * 3
composite_index: List[ExtendedIndex] = [slice(None)] * 3
composite_index[dims.index("ilines")] = self._iline_indexer[ilines]
composite_index[dims.index("xlines")] = self._xline_indexer[xlines]
composite_index[dims.index("offsets")] = self._offset_indexer[offsets]
Expand Down
13 changes: 6 additions & 7 deletions tiledb/segy/tdbwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,14 @@
`a[np.ix_([1,3], [2,5])]` for a Numpy array.
"""

from typing import Dict, List, Tuple, Union
from typing import Dict, Union

import numpy as np
import wrapt

import tiledb

from .types import Ellipsis, ellipsis

ExtendedIndex = Union[int, slice, List[int], ellipsis]
ExtendedIndices = Union[ExtendedIndex, Tuple[ExtendedIndex, ...]]
from .types import Ellipsis, ExtendedIndex, ExtendedIndices


class SingleAttrArrayWrapper(wrapt.ObjectProxy):
Expand All @@ -37,7 +34,7 @@ def __init__(self, array: tiledb.Array, attr: str):
super().__init__(array)
self._self_attr = attr

def __getitem__(self, indices: ExtendedIndices) -> np.ndarray:
def __getitem__(self, indices: Union[ExtendedIndex, ExtendedIndices]) -> np.ndarray:
if not isinstance(indices, tuple):
indices = (indices,)
query = self.query(attrs=(self._self_attr,))
Expand All @@ -53,7 +50,9 @@ def __init__(self, array: tiledb.Array, *attrs: str):
super().__init__(array)
self._self_attrs = attrs

def __getitem__(self, indices: ExtendedIndices) -> Dict[str, np.ndarray]:
def __getitem__(
self, indices: Union[ExtendedIndex, ExtendedIndices]
) -> Dict[str, np.ndarray]:
if not isinstance(indices, tuple):
indices = (indices,)
query = self.query(attrs=self._self_attrs or None)
Expand Down
5 changes: 4 additions & 1 deletion tiledb/segy/types.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TYPE_CHECKING, Dict, List, Union
from typing import TYPE_CHECKING, Dict, List, Tuple, Union

# https://github.com/python/typing/issues/684#issuecomment-548203158
if TYPE_CHECKING: # pragma: nocover
Expand All @@ -15,5 +15,8 @@ class ellipsis(Enum):
cached_property = __import__("cached_property").cached_property

Index = Union[int, slice]
ExtendedIndex = Union[int, slice, List[int], ellipsis]
ExtendedIndices = Tuple[ExtendedIndex, ...]

Field = Dict[str, int]
NestedFieldList = Union[List[Field], List[List[Field]], List[List[List[Field]]]]
35 changes: 22 additions & 13 deletions tiledb/segy/unstructured.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import os
from functools import singledispatchmethod
from pathlib import PurePath
from types import TracebackType
from typing import List, Optional, Tuple, Type, Union, cast
from typing import List, Optional, Tuple, Type, Union, cast, overload

import numpy as np
from segyio import TraceSortingFormat

import tiledb

from .singledispatchmethod import singledispatchmethod # type: ignore
from .tdbwrapper import MultiAttrArrayWrapper, SingleAttrArrayWrapper
from .types import Ellipsis, Field, Index, cached_property, ellipsis
from .types import (
Ellipsis,
ExtendedIndex,
ExtendedIndices,
Field,
Index,
cached_property,
)


def ensure_slice(i: Index) -> slice:
Expand All @@ -24,9 +31,7 @@ def __init__(self, shape: Tuple[int, ...]):
def __len__(self) -> int:
return int(np.asarray(self._shape).prod())

def __getitem__(
self, trace_index: Index
) -> Tuple[Tuple[Index, ...], Union[List[int], ellipsis]]:
def __getitem__(self, trace_index: Index) -> Tuple[ExtendedIndices, ExtendedIndex]:
"""
Given a trace index, return a `(bounding_box, post_reshape_indices)` tuple where:
- `bounding_box` is a tuple of (int or slice) indices for each dimension in shape
Expand Down Expand Up @@ -68,22 +73,26 @@ def __getitem__(self, i: Union[Index, Tuple[Index, Index]]) -> np.ndarray:

class Header(TraceIndexable):
@singledispatchmethod
def __getitem__(self, i: object) -> None:
def _get_index(self, i: Index) -> Union[Field, List[Field]]:
raise TypeError(f"Cannot index by {i.__class__}")

@__getitem__.register(int)
@__getitem__.register(np.integer)
def _get_one(self, i: int) -> Field:
return cast(Field, self[i : i + 1][0])
@overload
@_get_index.register
def __getitem__(self, i: int) -> Field:
return self[i : i + 1][0]

@__getitem__.register(slice)
def _get_many(self, i: slice) -> List[Field]:
@overload
@_get_index.register
def __getitem__(self, i: slice) -> List[Field]:
bounding_box, post_reshape_indices = self._indexer[i]
header_arrays = self._tdb[bounding_box]
keys = header_arrays.keys()
columns = [header_arrays[key].reshape(-1)[post_reshape_indices] for key in keys]
return [dict(zip(keys, row)) for row in zip(*columns)]

def __getitem__(self, i: Index) -> Union[Field, List[Field]]:
return self._get_index(i)


class Attributes(TraceIndexable):
def __getitem__(self, i: Index) -> np.ndarray:
Expand Down

0 comments on commit f18e0f0

Please sign in to comment.