diff --git a/python/neuroglancer/coordinate_space.py b/python/neuroglancer/coordinate_space.py index 4e14c4254..30d9a00ec 100644 --- a/python/neuroglancer/coordinate_space.py +++ b/python/neuroglancer/coordinate_space.py @@ -15,7 +15,7 @@ import re from collections.abc import Sequence -from typing import Any, NamedTuple, Optional, Union +from typing import Any, NamedTuple import numpy as np import numpy.typing @@ -166,7 +166,7 @@ class DimensionScale(NamedTuple): unit: str = "" """Units of `.scale`.""" - coordinate_array: Optional[CoordinateArray] = None + coordinate_array: CoordinateArray | None = None """Coordinate array for the dimension.""" @staticmethod @@ -208,7 +208,7 @@ class CoordinateSpace: Length is equal to `.rank`. """ - coordinate_arrays: tuple[Optional[CoordinateArray], ...] + coordinate_arrays: tuple[CoordinateArray | None, ...] """Coordinate array for each dimension. Length is equal to `.rank`. @@ -217,10 +217,10 @@ class CoordinateSpace: def __init__( self, json: Any = None, - names: Optional[Sequence[str]] = None, - scales: Optional[Sequence[float]] = None, - units: Optional[Union[str, Sequence[str]]] = None, - coordinate_arrays: Optional[Sequence[Optional[CoordinateArray]]] = None, + names: Sequence[str] | None = None, + scales: Sequence[float] | None = None, + units: str | Sequence[str] | None = None, + coordinate_arrays: Sequence[CoordinateArray | None] | None = None, ): """ Constructs a coordinate space. diff --git a/python/neuroglancer/equivalence_map.py b/python/neuroglancer/equivalence_map.py index 1615191cb..9a984c8c2 100644 --- a/python/neuroglancer/equivalence_map.py +++ b/python/neuroglancer/equivalence_map.py @@ -16,7 +16,6 @@ import collections import copy from collections.abc import ItemsView, Iterator, KeysView -from typing import Optional class EquivalenceMap: @@ -91,7 +90,7 @@ def clear(self): self._prev_next.clear() self._min_values.clear() - def union(self, *elements: int) -> Optional[int]: + def union(self, *elements: int) -> int | None: """Unions the equivalence classes containing the specified elements.""" if self._readonly: raise AttributeError diff --git a/python/neuroglancer/json_utils.py b/python/neuroglancer/json_utils.py index ce0b7fcdb..f4d9be0ec 100644 --- a/python/neuroglancer/json_utils.py +++ b/python/neuroglancer/json_utils.py @@ -36,7 +36,7 @@ def json_encoder_default(obj): return float(obj) elif isinstance(obj, np.ndarray): return list(obj) - elif isinstance(obj, (set, frozenset)): + elif isinstance(obj, set | frozenset): return list(obj) raise TypeError diff --git a/python/neuroglancer/json_wrappers.py b/python/neuroglancer/json_wrappers.py index 7c18dc252..e4574d4e9 100644 --- a/python/neuroglancer/json_wrappers.py +++ b/python/neuroglancer/json_wrappers.py @@ -18,16 +18,20 @@ import inspect import numbers import threading -from collections.abc import ItemsView, Iterable, Iterator, KeysView, ValuesView +from collections.abc import ( + Callable, + ItemsView, + Iterable, + Iterator, + KeysView, + ValuesView, +) from typing import ( Any, - Callable, ClassVar, Generic, Literal, - Optional, TypeVar, - Union, cast, overload, ) @@ -250,7 +254,7 @@ def modified_validator(value, **kwargs): modified_wrapper.supports_validation = modified_validator if default_value is None: - _map_type_annotation(modified_wrapper, wrapper, lambda t: Optional[t]) + _map_type_annotation(modified_wrapper, wrapper, lambda t: t | None) else: _map_type_annotation(modified_wrapper, wrapper, lambda t: t) @@ -310,13 +314,13 @@ def items(self) -> ItemsView[K, V]: return _MapItemsView(self) @overload - def get(self, key: K) -> Optional[V]: ... + def get(self, key: K) -> V | None: ... @overload def get(self, key: K, default: V) -> V: ... @overload - def get(self, key: K, default: T) -> Union[V, T]: ... + def get(self, key: K, default: T) -> V | T: ... def get(self, key: K, default=None): """Returns the mapped value, or the specified default.""" @@ -450,7 +454,7 @@ class _Map(Map): def typed_set(wrapped_type: Callable[[Any], T]): - def wrapper(x, _readonly=False) -> Union[set[T], frozenset[T]]: + def wrapper(x, _readonly=False) -> set[T] | frozenset[T]: set_type = frozenset if _readonly else set kwargs: dict[str, Any] = dict() if hasattr(wrapped_type, "supports_readonly"): @@ -490,7 +494,7 @@ class List(Generic[T]): def __init__(self, json_data=None, _readonly=False): if json_data is None: json_data = [] - if not isinstance(json_data, (list, tuple, np.ndarray)): + if not isinstance(json_data, list | tuple | np.ndarray): raise ValueError self._readonly = _readonly validator = type(self)._validator @@ -516,7 +520,7 @@ def __setitem__(self, key: int, value: T): ... @overload def __setitem__(self, key: slice, value: Iterable[T]): ... - def __setitem__(self, key: Union[int, slice], value: Union[T, Iterable[T]]): + def __setitem__(self, key: int | slice, value: T | Iterable[T]): """Assigns to the specified index or slice.""" if self._readonly: raise AttributeError @@ -575,18 +579,18 @@ class _List(List): def number_or_string(value): - if not isinstance(value, numbers.Real) and not isinstance(value, str): + if not isinstance(value, numbers.Real | str): raise TypeError return value -_set_type_annotation(number_or_string, Union[numbers.Real, str]) +_set_type_annotation(number_or_string, numbers.Real | str) def bool_or_string(value): - if not isinstance(value, (bool, str)): + if not isinstance(value, bool | str): raise TypeError return value -_set_type_annotation(bool_or_string, Union[bool, str]) +_set_type_annotation(bool_or_string, bool | str) diff --git a/python/neuroglancer/test_utils.py b/python/neuroglancer/test_utils.py index 3377bd95d..830c15f33 100644 --- a/python/neuroglancer/test_utils.py +++ b/python/neuroglancer/test_utils.py @@ -13,7 +13,8 @@ # limitations under the License. import time -from typing import Callable, TypeVar +from collections.abc import Callable +from typing import TypeVar T = TypeVar("T") diff --git a/python/neuroglancer/tool/screenshot.py b/python/neuroglancer/tool/screenshot.py index 01288f92c..923e78614 100755 --- a/python/neuroglancer/tool/screenshot.py +++ b/python/neuroglancer/tool/screenshot.py @@ -79,8 +79,8 @@ import os import threading import time -from collections.abc import Iterator -from typing import Callable, NamedTuple, Optional +from collections.abc import Callable, Iterator +from typing import NamedTuple import numpy as np import PIL @@ -293,8 +293,8 @@ def capture_screenshots_in_parallel( request_iter: Iterator[CaptureScreenshotRequest], refresh_browser_timeout: float, num_to_prefetch: int, - total_requests: Optional[int] = None, - buffer_size: Optional[int] = None, + total_requests: int | None = None, + buffer_size: int | None = None, ): if buffer_size is None: if total_requests is None: diff --git a/python/neuroglancer/trackable_state.py b/python/neuroglancer/trackable_state.py index 3649ea349..a9ccba22f 100644 --- a/python/neuroglancer/trackable_state.py +++ b/python/neuroglancer/trackable_state.py @@ -102,9 +102,9 @@ def transform_state_function(new_state): def set_state( self, - new_state: typing.Union[typing.Any, State], - generation: typing.Optional[Generation] = None, - existing_generation: typing.Optional[Generation] = None, + new_state: typing.Any | State, + generation: Generation | None = None, + existing_generation: Generation | None = None, ) -> Generation: """ Sets a new value. @@ -173,7 +173,7 @@ def txn(self, overwrite: bool = False, lock: bool = True): if lock: self._lock.acquire() try: - existing_generation: typing.Optional[Generation] + existing_generation: Generation | None new_state, existing_generation = self.state_and_generation new_state = copy.deepcopy(new_state) yield new_state diff --git a/python/neuroglancer/viewer_base.py b/python/neuroglancer/viewer_base.py index 3eaad1c9f..5f8fa45bb 100644 --- a/python/neuroglancer/viewer_base.py +++ b/python/neuroglancer/viewer_base.py @@ -19,7 +19,6 @@ import re import threading from concurrent.futures import Future -from typing import Optional import numpy as np @@ -190,7 +189,7 @@ def volume_info( self, layer: str, *, - dimensions: Optional[coordinate_space.CoordinateSpace] = None, + dimensions: coordinate_space.CoordinateSpace | None = None, ) -> "Future[ts.TensorStore]": request_id = make_random_token() future: Future[ts.TensorStore] = Future() @@ -217,7 +216,7 @@ def volume( self, layer: str, *, - dimensions: Optional[coordinate_space.CoordinateSpace] = None, + dimensions: coordinate_space.CoordinateSpace | None = None, ) -> "Future[ts.TensorStore]": future: Future[ts.TensorStore] = Future() @@ -377,7 +376,7 @@ def _transform_viewer_state(self, new_state): new_state = new_state.to_json() def encoder(x): - if isinstance(x, (local_volume.LocalVolume, skeleton.SkeletonSource)): + if isinstance(x, local_volume.LocalVolume | skeleton.SkeletonSource): return self.volume_manager.register_volume(x) return json_encoder_default(x) diff --git a/python/neuroglancer/viewer_config_state.py b/python/neuroglancer/viewer_config_state.py index 192b8dfde..5b1f07537 100644 --- a/python/neuroglancer/viewer_config_state.py +++ b/python/neuroglancer/viewer_config_state.py @@ -53,8 +53,8 @@ def export(obj): @export class SegmentIdMapEntry(typing.NamedTuple): key: int - value: typing.Optional[int] = None - label: typing.Optional[str] = None + value: int | None = None + label: str | None = None @export @@ -71,9 +71,7 @@ def layer_selected_value(x): return None -_set_type_annotation( - layer_selected_value, typing.Union[None, numbers.Number, SegmentIdMapEntry] -) +_set_type_annotation(layer_selected_value, None | numbers.Number | SegmentIdMapEntry) @export diff --git a/python/neuroglancer/viewer_state.py b/python/neuroglancer/viewer_state.py index 941a89c0b..cc596d749 100644 --- a/python/neuroglancer/viewer_state.py +++ b/python/neuroglancer/viewer_state.py @@ -462,7 +462,7 @@ class CoordinateSpaceTransform(JsonObjectWrapper): def data_source_url(x): - if isinstance(x, (local_volume.LocalVolume, skeleton.SkeletonSource)): + if isinstance(x, local_volume.LocalVolume | skeleton.SkeletonSource): return x if not isinstance(x, str): raise TypeError @@ -488,7 +488,7 @@ class LayerDataSource(JsonObjectWrapper): def __init__(self, json_data=None, *args, **kwargs): if isinstance(json_data, str) or isinstance( - json_data, (local_volume.LocalVolume, skeleton.SkeletonSource) + json_data, local_volume.LocalVolume | skeleton.SkeletonSource ): json_data = {"url": json_data} super().__init__(json_data, *args, **kwargs) @@ -514,13 +514,11 @@ class LayerDataSources(_LayerDataSourcesBase): def __init__(self, json_data=None, **kwargs): if isinstance( json_data, - ( - LayerDataSource, - str, - local_volume.LocalVolume, - skeleton.SkeletonSource, - dict, - ), + LayerDataSource + | str + | local_volume.LocalVolume + | skeleton.SkeletonSource + | dict, ): json_data = [json_data] elif isinstance(json_data, LayerDataSources): @@ -576,7 +574,7 @@ def _shader_control_parameters(v, _readonly=False): _set_type_annotation( _shader_control_parameters, - typing.Union[numbers.Number, str, InvlerpParameters, TransferFunctionParameters], + numbers.Number | str | InvlerpParameters | TransferFunctionParameters, ) @@ -751,10 +749,10 @@ def add(self, segment_id: int) -> None: self.setdefault(segment_id, True) @typing.overload - def get(self, segment_id: int) -> typing.Optional[bool]: ... + def get(self, segment_id: int) -> bool | None: ... @typing.overload - def get(self, segment_id: int, default: T) -> typing.Union[bool, T]: ... + def get(self, segment_id: int, default: T) -> bool | T: ... def get(self, segment_id: int, default=None): """Checks if a segment is visible. @@ -825,7 +823,7 @@ def update( # type: ignore[override] other: typing.Union[ "StarredSegments", collections.abc.MutableMapping[int, bool], - typing.Iterable[typing.Union[int, str, tuple[int, bool]]], + typing.Iterable[int | str | tuple[int, bool]], ], ): """Merges in additional starred segments.""" @@ -1608,7 +1606,7 @@ def layout_specification(x, _readonly=False): x = "4panel" if isinstance(x, str): x = {"type": str(x)} - if isinstance(x, (StackLayout, LayerGroupViewer, DataPanelLayout)): + if isinstance(x, StackLayout | LayerGroupViewer | DataPanelLayout): return type(x)(x.to_json(), _readonly=_readonly) if not isinstance(x, dict): raise ValueError diff --git a/python/neuroglancer/write_annotations.py b/python/neuroglancer/write_annotations.py index 8a204e0fc..a582a5fc7 100644 --- a/python/neuroglancer/write_annotations.py +++ b/python/neuroglancer/write_annotations.py @@ -20,7 +20,7 @@ import pathlib import struct from collections.abc import Sequence -from typing import Literal, NamedTuple, Optional, Union, cast +from typing import Literal, NamedTuple, cast import numpy as np @@ -33,9 +33,7 @@ class Annotation(NamedTuple): relationships: Sequence[Sequence[int]] -_PROPERTY_DTYPES: dict[ - str, tuple[Union[tuple[str], tuple[str, tuple[int, ...]]], int] -] = { +_PROPERTY_DTYPES: dict[str, tuple[tuple[str] | tuple[str, tuple[int, ...]], int]] = { "uint8": (("|u1",), 1), "uint16": (("