Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nion/data/Core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2067,7 +2067,7 @@ def function_element_data_no_copy(data_and_metadata: DataAndMetadata._DataAndMet
if data_and_metadata.is_sequence:
# next dimension is treated as a sequence index, which may be time or just a sequence index
sequence_index = min(max(sequence_index, 0), dimensional_shape[next_dimension])
data_slice = typing.cast(DataAndMetadata._SliceKeyType, (sequence_index, ...))
data_slice = (sequence_index, ...)
result = DataAndMetadata.function_data_slice(data_and_metadata, DataAndMetadata.key_to_list(data_slice))
modified = True
next_dimension += 1
Expand Down
31 changes: 17 additions & 14 deletions nion/data/DataAndMetadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

# standard libraries
import base64
import collections.abc
import copy
import datetime
import gettext
import logging
import numbers
import pickle
import threading
import types
import typing
import warnings

Expand All @@ -31,10 +33,9 @@
_ImageDataType = numpy.typing.NDArray[typing.Any]
_ScalarDataType = typing.Union[int, float, complex]
_InternalCalibrationListType = typing.Tuple[Calibration.Calibration, ...]
# NOTE: typing.Any is only required when numpy < 1.21. once that requirement is removed (anaconda), switch this back.
_SliceKeyElementType = typing.Any # typing.Union[slice, int, ellipsis, None]
_SliceKeyType = typing.Tuple[_SliceKeyElementType, ...]
_SliceDictKeyType = typing.Sequence[typing.Dict[str, typing.Any]]
_SliceKeyElementType = slice | int | numpy.int32 | numpy.int64 | types.EllipsisType | None
_SliceKeyType = tuple[_SliceKeyElementType, ...]
_SliceDictKeyType = typing.Sequence[typing.Dict[str, typing.Any] | _SliceKeyElementType]


class DataDescriptor:
Expand Down Expand Up @@ -1086,8 +1087,8 @@ def extract_data(evaluated_input: typing.Any) -> typing.Any:
return evaluated_input


def key_to_list(key: typing.Union[_SliceKeyType, _SliceKeyElementType]) -> typing.List[typing.Dict[str, typing.Any]]:
if not isinstance(key, tuple):
def key_to_list(key: _SliceKeyType | _SliceKeyElementType) -> typing.List[typing.Dict[str, typing.Any]]:
if not isinstance(key, collections.abc.Sequence):
key = (key,)
l = list()
for k in key:
Expand All @@ -1113,22 +1114,24 @@ def key_to_list(key: typing.Union[_SliceKeyType, _SliceKeyElementType]) -> typin


def list_to_key(l: _SliceDictKeyType) -> _SliceKeyType:
key: typing.List[_SliceKeyElementType] = list()
key = list[_SliceKeyElementType]()
for d in l:
if isinstance(d, (slice, type(Ellipsis))):
key.append(d)
elif d is None:
key.append(None)
elif isinstance(d, numbers.Integral):
key.append(int(d))
elif "index" in d:
key.append(int(d.get("index", 0)))
elif d.get("ellipses", False):
key.append(typing.cast(None, Ellipsis)) # some confusion about ellipsis https://bugs.python.org/issue41810
elif d.get("newaxis", False):
key.append(None)
else:
key.append(slice(d.get("start"), d.get("stop"), d.get("step")))
assert isinstance(d, dict)
if "index" in d:
key.append(int(d.get("index", 0)))
elif d.get("ellipses", False):
key.append(Ellipsis)
elif d.get("newaxis", False):
key.append(None)
else:
key.append(slice(d.get("start"), d.get("stop"), d.get("step")))
if len(key) == 1:
return (key[0],)
return tuple(key)
Expand Down