diff --git a/yt/_maintenance/backports.py b/yt/_maintenance/backports.py index 78577af3e43..afa4aa4551c 100644 --- a/yt/_maintenance/backports.py +++ b/yt/_maintenance/backports.py @@ -63,18 +63,3 @@ def _generate_next_value_(name, start, count, last_values): # noqa B902 Return the lower-cased version of the member name. """ return name.lower() - - -builtin_zip = zip -if sys.version_info >= (3, 10): - zip = builtin_zip -else: - # this function is deprecated in more_itertools - # because it is superseded by the standard library - from more_itertools import zip_equal - - def zip(*args, strict=False): - if strict: - return zip_equal(*args) - else: - return builtin_zip(*args) diff --git a/yt/_maintenance/deprecation.py b/yt/_maintenance/deprecation.py index 3d37a8f4969..6aeec520fae 100644 --- a/yt/_maintenance/deprecation.py +++ b/yt/_maintenance/deprecation.py @@ -1,7 +1,6 @@ import warnings from functools import wraps from types import FunctionType -from typing import Optional def issue_deprecation_warning( @@ -9,7 +8,7 @@ def issue_deprecation_warning( *, stacklevel: int, since: str, - removal: Optional[str] = None, + removal: str | None = None, ): """ Parameters diff --git a/yt/_typing.py b/yt/_typing.py index cac48fd408a..0aeff6d79fa 100644 --- a/yt/_typing.py +++ b/yt/_typing.py @@ -1,9 +1,9 @@ -from typing import Any, Optional, Union +from typing import Any, Optional import numpy as np import unyt as un -FieldDescT = tuple[str, tuple[str, list[str], Optional[str]]] +FieldDescT = tuple[str, tuple[str, list[str], str | None]] KnownFieldsT = tuple[FieldDescT, ...] ParticleType = str @@ -11,13 +11,13 @@ FieldName = str FieldKey = tuple[FieldType, FieldName] ImplicitFieldKey = FieldName -AnyFieldKey = Union[FieldKey, ImplicitFieldKey] -DomainDimensions = Union[tuple[int, ...], list[int], np.ndarray] +AnyFieldKey = FieldKey | ImplicitFieldKey +DomainDimensions = tuple[int, ...] | list[int] | np.ndarray ParticleCoordinateTuple = tuple[ str, # particle type tuple[np.ndarray, np.ndarray, np.ndarray], # xyz - Union[float, np.ndarray], # hsml + float | np.ndarray, # hsml ] # Geometry specific types @@ -25,10 +25,10 @@ AxisOrder = tuple[AxisName, AxisName, AxisName] # types that can be converted to un.Unit -Unit = Union[un.Unit, str] +Unit = un.Unit | str # types that can be converted to un.unyt_quantity -Quantity = Union[un.unyt_quantity, tuple[float, Unit]] +Quantity = un.unyt_quantity | tuple[float, Unit] # np.ndarray[...] syntax is runtime-valid from numpy 1.22, we quote it until our minimal # runtime requirement is bumped to, or beyond this version diff --git a/yt/data_objects/analyzer_objects.py b/yt/data_objects/analyzer_objects.py index b186ac1610a..feac64f44c8 100644 --- a/yt/data_objects/analyzer_objects.py +++ b/yt/data_objects/analyzer_objects.py @@ -1,11 +1,7 @@ import inspect -import sys from yt.utilities.object_registries import analysis_task_registry -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class AnalysisTask: def __init_subclass__(cls, *args, **kwargs): diff --git a/yt/data_objects/construction_data_containers.py b/yt/data_objects/construction_data_containers.py index 854f5033d20..cecb7463309 100644 --- a/yt/data_objects/construction_data_containers.py +++ b/yt/data_objects/construction_data_containers.py @@ -1,7 +1,6 @@ import fileinput import io import os -import sys import warnings import zipfile from functools import partial, wraps @@ -64,9 +63,6 @@ ) from yt.visualization.color_maps import get_colormap_lut -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class YTStreamline(YTSelectionContainer1D): """ diff --git a/yt/data_objects/data_containers.py b/yt/data_objects/data_containers.py index dfc6ebd4876..22977abec7a 100644 --- a/yt/data_objects/data_containers.py +++ b/yt/data_objects/data_containers.py @@ -1,5 +1,4 @@ import abc -import sys import weakref from collections import defaultdict from contextlib import contextmanager @@ -29,9 +28,6 @@ from yt.utilities.on_demand_imports import _firefly as firefly from yt.utilities.parameter_file_storage import ParameterFileStore -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - if TYPE_CHECKING: from yt.data_objects.static_output import Dataset diff --git a/yt/data_objects/derived_quantities.py b/yt/data_objects/derived_quantities.py index 8bc41c04749..2814873a0aa 100644 --- a/yt/data_objects/derived_quantities.py +++ b/yt/data_objects/derived_quantities.py @@ -1,5 +1,3 @@ -import sys - import numpy as np from yt.funcs import camelcase_to_underscore, iter_fields @@ -13,9 +11,6 @@ from yt.utilities.physical_constants import gravitational_constant_cgs from yt.utilities.physical_ratios import HUGE -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def get_position_fields(field, data): axis_names = [data.ds.coordinates.axis_name[num] for num in [0, 1, 2]] diff --git a/yt/data_objects/level_sets/tests/test_clump_finding.py b/yt/data_objects/level_sets/tests/test_clump_finding.py index bd7059f8c33..5b5b72e15bc 100644 --- a/yt/data_objects/level_sets/tests/test_clump_finding.py +++ b/yt/data_objects/level_sets/tests/test_clump_finding.py @@ -1,6 +1,5 @@ import os import shutil -import sys import tempfile import numpy as np @@ -13,9 +12,6 @@ from yt.testing import requires_file, requires_module from yt.utilities.answer_testing.framework import data_dir_load -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def test_clump_finding(): n_c = 8 diff --git a/yt/data_objects/profiles.py b/yt/data_objects/profiles.py index 5aac6b0b6d0..0b1b790785d 100644 --- a/yt/data_objects/profiles.py +++ b/yt/data_objects/profiles.py @@ -1,5 +1,3 @@ -import sys - import numpy as np from more_itertools import collapse @@ -25,9 +23,6 @@ parallel_objects, ) -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def _sanitize_min_max_units(amin, amax, finfo, registry): # returns a copy of amin and amax, converted to finfo's output units diff --git a/yt/data_objects/static_output.py b/yt/data_objects/static_output.py index dd5c4524742..bd367fa189c 100644 --- a/yt/data_objects/static_output.py +++ b/yt/data_objects/static_output.py @@ -13,7 +13,7 @@ from functools import cached_property from importlib.util import find_spec from stat import ST_CTIME -from typing import Any, Literal, Optional, Union +from typing import Any, Literal, Optional import numpy as np import unyt as un @@ -86,15 +86,13 @@ # to here, and then have it instantiate EnzoDatasets as appropriate. -_cached_datasets: MutableMapping[Union[int, str], "Dataset"] = ( - weakref.WeakValueDictionary() -) +_cached_datasets: MutableMapping[int | str, "Dataset"] = weakref.WeakValueDictionary() # we set this global to None as a place holder # its actual instantiation is delayed until after yt.__init__ # is completed because we need yt.config.ytcfg to be instantiated first -_ds_store: Optional[ParameterFileStore] = None +_ds_store: ParameterFileStore | None = None def _setup_ds_store(ytcfg: YTConfig) -> None: @@ -161,24 +159,24 @@ class Dataset(abc.ABC): default_field = ("gas", "density") fluid_types: tuple[FieldType, ...] = ("gas", "deposit", "index") particle_types: tuple[ParticleType, ...] = ("io",) # By default we have an 'all' - particle_types_raw: Optional[tuple[ParticleType, ...]] = ("io",) + particle_types_raw: tuple[ParticleType, ...] | None = ("io",) geometry: Geometry = Geometry.CARTESIAN coordinates = None storage_filename = None - particle_unions: Optional[dict[ParticleType, ParticleUnion]] = None - known_filters: Optional[dict[ParticleType, ParticleFilter]] = None + particle_unions: dict[ParticleType, ParticleUnion] | None = None + known_filters: dict[ParticleType, ParticleFilter] | None = None _index_class: type[Index] - field_units: Optional[dict[AnyFieldKey, Unit]] = None + field_units: dict[AnyFieldKey, Unit] | None = None derived_field_list = requires_index("derived_field_list") fields = requires_index("fields") - conversion_factors: Optional[dict[str, float]] = None + conversion_factors: dict[str, float] | None = None # _instantiated represents an instantiation time (since Epoch) # the default is a place holder sentinel, falsy value _instantiated: float = 0 _particle_type_counts = None _proj_type = "quad_proj" _ionization_label_format = "roman_numeral" - _determined_fields: Optional[dict[str, list[FieldKey]]] = None + _determined_fields: dict[str, list[FieldKey]] | None = None fields_detected = False # these are set in self._parse_parameter_file() @@ -233,8 +231,8 @@ def __init_subclass__(cls, *args, **kwargs): def __init__( self, filename: str, - dataset_type: Optional[str] = None, - units_override: Optional[dict[str, str]] = None, + dataset_type: str | None = None, + units_override: dict[str, str] | None = None, # valid unit_system values include all keys from unyt.unit_systems.unit_systems_registry + "code" unit_system: Literal[ "cgs", @@ -250,7 +248,7 @@ def __init__( "Any" ] = None, # Any used as a placeholder here *, - axis_order: Optional[AxisOrder] = None, + axis_order: AxisOrder | None = None, ) -> None: """ Base class for generating new output types. Principally consists of @@ -732,7 +730,7 @@ def setup_deprecated_fields(self): added.append(("gas", old_name)) self.field_info.find_dependencies(added) - def _setup_coordinate_handler(self, axis_order: Optional[AxisOrder]) -> None: + def _setup_coordinate_handler(self, axis_order: AxisOrder | None) -> None: # backward compatibility layer: # turning off type-checker on a per-line basis cls: type[CoordinateHandler] @@ -947,7 +945,7 @@ def _setup_particle_types(self, ptypes=None): def _get_field_info( self, - field: Union[FieldKey, ImplicitFieldKey, DerivedField], + field: FieldKey | ImplicitFieldKey | DerivedField, /, ) -> DerivedField: field_info, candidates = self._get_field_info_helper(field) @@ -1008,7 +1006,7 @@ def _are_ambiguous(candidates: list[FieldKey]) -> bool: def _get_field_info_helper( self, - field: Union[FieldKey, ImplicitFieldKey, DerivedField], + field: FieldKey | ImplicitFieldKey | DerivedField, /, ) -> tuple[DerivedField, list[FieldKey]]: self.index @@ -1280,8 +1278,8 @@ def _assign_unit_system( # is mks-like: i.e., it has a current with the same # dimensions as amperes. mks_system = False - mag_unit: Optional[unyt_quantity] = getattr(self, "magnetic_unit", None) - mag_dims: Optional[set[Symbol]] + mag_unit: unyt_quantity | None = getattr(self, "magnetic_unit", None) + mag_dims: set[Symbol] | None if mag_unit is not None: mag_dims = mag_unit.units.dimensions.free_symbols else: @@ -2057,9 +2055,9 @@ class ParticleFile: filename: str file_id: int - start: Optional[int] = None - end: Optional[int] = None - total_particles: Optional[defaultdict[str, int]] = None + start: int | None = None + end: int | None = None + total_particles: defaultdict[str, int] | None = None def __init__(self, ds, io, filename, file_id, range=None): self.ds = ds diff --git a/yt/data_objects/tests/test_covering_grid.py b/yt/data_objects/tests/test_covering_grid.py index ed59776409b..3e9013b450e 100644 --- a/yt/data_objects/tests/test_covering_grid.py +++ b/yt/data_objects/tests/test_covering_grid.py @@ -1,5 +1,3 @@ -import sys - import numpy as np from numpy.testing import assert_almost_equal, assert_array_equal, assert_equal @@ -13,10 +11,6 @@ ) from yt.units import kpc -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - - # cylindrical data for covering_grid test cyl_2d = "WDMerger_hdf5_chk_1000/WDMerger_hdf5_chk_1000.hdf5" cyl_3d = "MHD_Cyl3d_hdf5_plt_cnt_0100/MHD_Cyl3d_hdf5_plt_cnt_0100.hdf5" diff --git a/yt/data_objects/tests/test_derived_quantities.py b/yt/data_objects/tests/test_derived_quantities.py index 93e343282b9..35ac7283d42 100644 --- a/yt/data_objects/tests/test_derived_quantities.py +++ b/yt/data_objects/tests/test_derived_quantities.py @@ -1,5 +1,3 @@ -import sys - import numpy as np from numpy.testing import assert_almost_equal, assert_equal @@ -13,9 +11,6 @@ requires_file, ) -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def setup_module(): from yt.config import ytcfg diff --git a/yt/data_objects/time_series.py b/yt/data_objects/time_series.py index b642626e67b..75d5aabcd56 100644 --- a/yt/data_objects/time_series.py +++ b/yt/data_objects/time_series.py @@ -5,7 +5,6 @@ import weakref from abc import ABC, abstractmethod from functools import wraps -from typing import Optional import numpy as np from more_itertools import always_iterable @@ -147,7 +146,7 @@ class DatasetSeries: # this annotation should really be Optional[Type[Dataset]] # but we cannot import the yt.data_objects.static_output.Dataset # class here without creating a circular import for now - _dataset_cls: Optional[type] = None + _dataset_cls: type | None = None def __init_subclass__(cls, *args, **kwargs): super().__init_subclass__(*args, **kwargs) @@ -371,7 +370,7 @@ def from_output_log(cls, output_log, line_prefix="DATASET WRITTEN", parallel=Tru obj = cls(filenames, parallel=parallel) return obj - def _load(self, output_fn, *, hint: Optional[str] = None, **kwargs): + def _load(self, output_fn, *, hint: str | None = None, **kwargs): from yt.loaders import load if self._dataset_cls is not None: diff --git a/yt/fields/derived_field.py b/yt/fields/derived_field.py index cfb1c4d59bc..8fb8d0c7767 100644 --- a/yt/fields/derived_field.py +++ b/yt/fields/derived_field.py @@ -1,9 +1,8 @@ import contextlib import inspect import re -import sys from collections.abc import Iterable -from typing import Optional, Union +from typing import Optional from more_itertools import always_iterable @@ -26,9 +25,6 @@ NeedsProperty, ) -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def TranslationFunc(field_name): def _TranslationFunc(field, data): @@ -119,7 +115,7 @@ def __init__( name: FieldKey, sampling_type, function, - units: Optional[Union[str, bytes, Unit]] = None, + units: str | bytes | Unit | None = None, take_log=True, validators=None, vector_field=False, @@ -158,7 +154,7 @@ def __init__( self.validators = list(always_iterable(validators)) # handle units - self.units: Optional[Union[str, bytes, Unit]] + self.units: str | bytes | Unit | None if units in (None, "auto"): self.units = None elif isinstance(units, str): @@ -341,7 +337,7 @@ def is_alias_to(self, other: "DerivedField") -> bool: return self._shared_aliases_list is other._shared_aliases_list @property - def alias_name(self) -> Optional[FieldKey]: + def alias_name(self) -> FieldKey | None: if self.is_alias: return self._shared_aliases_list[0].name return None @@ -532,8 +528,8 @@ class ValidateParameter(FieldValidator): def __init__( self, - parameters: Union[str, Iterable[str]], - parameter_values: Optional[dict] = None, + parameters: str | Iterable[str], + parameter_values: dict | None = None, ): FieldValidator.__init__(self) self.parameters = list(always_iterable(parameters)) @@ -586,7 +582,7 @@ class ValidateProperty(FieldValidator): the required property or properties to require """ - def __init__(self, prop: Union[str, Iterable[str]]): + def __init__(self, prop: str | Iterable[str]): FieldValidator.__init__(self) self.prop = list(always_iterable(prop)) @@ -612,7 +608,7 @@ class ValidateSpatial(FieldValidator): """ - def __init__(self, ghost_zones: Optional[int] = 0, fields=None): + def __init__(self, ghost_zones: int | None = 0, fields=None): FieldValidator.__init__(self) self.ghost_zones = ghost_zones self.fields = fields diff --git a/yt/fields/field_detector.py b/yt/fields/field_detector.py index 978285042f8..58fb74cd5c4 100644 --- a/yt/fields/field_detector.py +++ b/yt/fields/field_detector.py @@ -1,5 +1,4 @@ from collections import defaultdict -from typing import Union import numpy as np @@ -102,7 +101,7 @@ def _reshape_vals(self, arr): return arr return arr.reshape(self.ActiveDimensions, order="C") - def __missing__(self, item: Union[tuple[str, str], str]): + def __missing__(self, item: tuple[str, str] | str): from yt.fields.derived_field import NullFunc if not isinstance(item, tuple): diff --git a/yt/fields/field_info_container.py b/yt/fields/field_info_container.py index 262cd373e5e..fc0693fe4fd 100644 --- a/yt/fields/field_info_container.py +++ b/yt/fields/field_info_container.py @@ -1,7 +1,6 @@ import sys from collections import UserDict from collections.abc import Callable -from typing import Optional from unyt.exceptions import UnitConversionError @@ -350,7 +349,7 @@ def add_field( function: Callable, sampling_type: str, *, - alias: Optional[DerivedField] = None, + alias: DerivedField | None = None, force_override: bool = False, **kwargs, ) -> None: @@ -407,7 +406,7 @@ def add_field( else: raise ValueError(f"Expected name to be a tuple[str, str], got {name}") - def load_all_plugins(self, ftype: Optional[str] = "gas") -> None: + def load_all_plugins(self, ftype: str | None = "gas") -> None: if ftype is None: return mylog.debug("Loading field plugins for field type: %s.", ftype) @@ -451,8 +450,8 @@ def alias( self, alias_name: FieldKey, original_name: FieldKey, - units: Optional[str] = None, - deprecate: Optional[tuple[str, Optional[str]]] = None, + units: str | None = None, + deprecate: tuple[str, str | None] | None = None, ): """ Alias one field to another field. diff --git a/yt/fields/magnetic_field.py b/yt/fields/magnetic_field.py index 8eab02ff3dd..81a4a767725 100644 --- a/yt/fields/magnetic_field.py +++ b/yt/fields/magnetic_field.py @@ -10,9 +10,6 @@ from .field_plugin_registry import register_field_plugin -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - if sys.version_info >= (3, 11): from typing import assert_never else: diff --git a/yt/fields/vector_operations.py b/yt/fields/vector_operations.py index 860cf076ea7..c8988539753 100644 --- a/yt/fields/vector_operations.py +++ b/yt/fields/vector_operations.py @@ -19,9 +19,6 @@ from .derived_field import NeedsParameter, ValidateParameter, ValidateSpatial -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - if sys.version_info >= (3, 11): from typing import assert_never else: diff --git a/yt/frontends/adaptahop/data_structures.py b/yt/frontends/adaptahop/data_structures.py index e8cb8535685..8407f0bcefc 100644 --- a/yt/frontends/adaptahop/data_structures.py +++ b/yt/frontends/adaptahop/data_structures.py @@ -9,7 +9,6 @@ import os import re from itertools import product -from typing import Optional import numpy as np @@ -56,8 +55,8 @@ class AdaptaHOPDataset(Dataset): # AdaptaHOP internally assumes 1Mpc == 3.0824cm _code_length_to_Mpc = (1.0 * Mpc).to_value("cm") / 3.08e24 - _header_attributes: Optional[ATTR_T] = None - _halo_attributes: Optional[ATTR_T] = None + _header_attributes: ATTR_T | None = None + _halo_attributes: ATTR_T | None = None def __init__( self, diff --git a/yt/frontends/adaptahop/definitions.py b/yt/frontends/adaptahop/definitions.py index a1178ba05c1..f0268d9a80d 100644 --- a/yt/frontends/adaptahop/definitions.py +++ b/yt/frontends/adaptahop/definitions.py @@ -5,11 +5,9 @@ """ -from typing import Union - from yt.funcs import mylog -ATTR_T = tuple[tuple[Union[tuple[str, ...], str], int, str], ...] +ATTR_T = tuple[tuple[tuple[str, ...] | str, int, str], ...] def HEADER_ATTRIBUTES(*, double: bool, longint: bool) -> ATTR_T: diff --git a/yt/frontends/adaptahop/io.py b/yt/frontends/adaptahop/io.py index 96e58da8566..4932d7e772f 100644 --- a/yt/frontends/adaptahop/io.py +++ b/yt/frontends/adaptahop/io.py @@ -8,7 +8,6 @@ from functools import partial from operator import attrgetter -from typing import Union import numpy as np @@ -194,7 +193,7 @@ def _todo_from_attributes(attributes: ATTR_T, halo_attributes: ATTR_T): # attributes. This is used to skip fields most of the fields when reading # the tree_brick files. iskip = 0 - todo: list[Union[int, list[tuple[Union[tuple[str, ...], str], int, str]]]] = [] + todo: list[int | list[tuple[tuple[str, ...] | str, int, str]]] = [] attributes = tuple(set(attributes)) diff --git a/yt/frontends/amrex/fields.py b/yt/frontends/amrex/fields.py index fbde2d2bb08..7128005d036 100644 --- a/yt/frontends/amrex/fields.py +++ b/yt/frontends/amrex/fields.py @@ -1,5 +1,5 @@ import re -import sys +from typing import TypeAlias import numpy as np @@ -8,11 +8,6 @@ from yt.units import YTQuantity from yt.utilities.physical_constants import amu_cgs, boltzmann_constant_cgs, c -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: - from typing_extensions import TypeAlias - rho_units = "code_mass / code_length**3" mom_units = "code_mass / (code_time * code_length**2)" eden_units = "code_mass / (code_time**2 * code_length)" # erg / cm^3 diff --git a/yt/frontends/amrvac/data_structures.py b/yt/frontends/amrvac/data_structures.py index 5b8d22ba547..7fb9787e84d 100644 --- a/yt/frontends/amrvac/data_structures.py +++ b/yt/frontends/amrvac/data_structures.py @@ -7,7 +7,6 @@ import os import struct -import sys import warnings import weakref from pathlib import Path @@ -27,9 +26,6 @@ from .fields import AMRVACFieldInfo from .io import read_amrvac_namelist -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def _parse_geometry(geometry_tag: str) -> Geometry: """Translate AMRVAC's geometry tag to yt's format. diff --git a/yt/frontends/amrvac/datfile_utils.py b/yt/frontends/amrvac/datfile_utils.py index 21436fd2d53..d3917e1580d 100644 --- a/yt/frontends/amrvac/datfile_utils.py +++ b/yt/frontends/amrvac/datfile_utils.py @@ -1,11 +1,7 @@ import struct -import sys import numpy as np -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - # Size of basic types (in bytes) SIZE_LOGICAL = 4 SIZE_INT = 4 diff --git a/yt/frontends/art/data_structures.py b/yt/frontends/art/data_structures.py index d13a2f77e7b..c47f447dc03 100644 --- a/yt/frontends/art/data_structures.py +++ b/yt/frontends/art/data_structures.py @@ -1,7 +1,6 @@ import glob import os import struct -import sys import weakref import numpy as np @@ -34,9 +33,6 @@ from yt.geometry.oct_geometry_handler import OctreeIndex from yt.geometry.particle_geometry_handler import ParticleIndex -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class ARTIndex(OctreeIndex): def __init__(self, ds, dataset_type="art"): diff --git a/yt/frontends/art/io.py b/yt/frontends/art/io.py index 13813677abd..e512b0e95fc 100644 --- a/yt/frontends/art/io.py +++ b/yt/frontends/art/io.py @@ -1,6 +1,5 @@ import os import os.path -import sys from collections import defaultdict from functools import partial @@ -17,9 +16,6 @@ from yt.utilities.io_handler import BaseIOHandler from yt.utilities.logger import ytLogger as mylog -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class IOHandlerART(BaseIOHandler): _dataset_type = "art" diff --git a/yt/frontends/artio/data_structures.py b/yt/frontends/artio/data_structures.py index e9acba4e683..9ade430fd8b 100644 --- a/yt/frontends/artio/data_structures.py +++ b/yt/frontends/artio/data_structures.py @@ -1,8 +1,6 @@ import os -import sys import weakref from collections import defaultdict -from typing import Optional import numpy as np @@ -22,9 +20,6 @@ from yt.geometry.geometry_handler import Index, YTDataChunk from yt.utilities.exceptions import YTParticleDepositionNotImplemented -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class ARTIOOctreeSubset(OctreeSubset): _domain_offset = 0 @@ -346,7 +341,7 @@ def _icoords_to_fcoords( self, icoords: np.ndarray, ires: np.ndarray, - axes: Optional[tuple[int, ...]] = None, + axes: tuple[int, ...] | None = None, ) -> tuple[np.ndarray, np.ndarray]: """ Accepts icoords and ires and returns appropriate fcoords and fwidth. diff --git a/yt/frontends/artio/definitions.py b/yt/frontends/artio/definitions.py index b054c5d8d35..d31afa6c16d 100644 --- a/yt/frontends/artio/definitions.py +++ b/yt/frontends/artio/definitions.py @@ -1,9 +1,3 @@ -import sys - -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - - yt_to_art = { "Density": "HVAR_GAS_DENSITY", "TotalEnergy": "HVAR_GAS_ENERGY", diff --git a/yt/frontends/athena/data_structures.py b/yt/frontends/athena/data_structures.py index 57e8058a6be..f72b897277e 100644 --- a/yt/frontends/athena/data_structures.py +++ b/yt/frontends/athena/data_structures.py @@ -1,6 +1,5 @@ import os import re -import sys import weakref import numpy as np @@ -18,9 +17,6 @@ from .fields import AthenaFieldInfo -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def chk23(strin): return strin.encode("utf-8") diff --git a/yt/frontends/athena_pp/data_structures.py b/yt/frontends/athena_pp/data_structures.py index 8c7bffd1fa6..43dee9b0fdf 100644 --- a/yt/frontends/athena_pp/data_structures.py +++ b/yt/frontends/athena_pp/data_structures.py @@ -1,5 +1,4 @@ import os -import sys import weakref import numpy as np @@ -16,9 +15,6 @@ from .fields import AthenaPPFieldInfo -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - geom_map = { "cartesian": "cartesian", "cylindrical": "cylindrical", diff --git a/yt/frontends/cf_radial/data_structures.py b/yt/frontends/cf_radial/data_structures.py index 1c1309510d0..a4e50c22f6c 100644 --- a/yt/frontends/cf_radial/data_structures.py +++ b/yt/frontends/cf_radial/data_structures.py @@ -8,7 +8,6 @@ import contextlib import os import weakref -from typing import Optional import numpy as np from unyt import unyt_array @@ -91,10 +90,10 @@ def __init__( dataset_type="cf_radial", storage_filename=None, storage_overwrite: bool = False, - grid_shape: Optional[tuple[int, int, int]] = None, - grid_limit_x: Optional[tuple[float, float]] = None, - grid_limit_y: Optional[tuple[float, float]] = None, - grid_limit_z: Optional[tuple[float, float]] = None, + grid_shape: tuple[int, int, int] | None = None, + grid_limit_x: tuple[float, float] | None = None, + grid_limit_y: tuple[float, float] | None = None, + grid_limit_z: tuple[float, float] | None = None, units_override=None, ): """ @@ -195,7 +194,7 @@ def __init__( self.refine_by = 2 # refinement factor between a grid and its subgrid @contextlib.contextmanager - def _handle(self, filename: Optional[str] = None): + def _handle(self, filename: str | None = None): if filename is None: if hasattr(self, "filename"): filename = self.filename @@ -206,7 +205,7 @@ def _handle(self, filename: Optional[str] = None): yield xrds def _validate_grid_dim( - self, radar, dim: str, grid_limit: Optional[tuple[float, float]] = None + self, radar, dim: str, grid_limit: tuple[float, float] | None = None ) -> tuple[float, float]: if grid_limit is None: if dim.lower() == "z": @@ -236,7 +235,7 @@ def _validate_grid_dim( return grid_limit def _validate_grid_shape( - self, grid_shape: Optional[tuple[int, int, int]] = None + self, grid_shape: tuple[int, int, int] | None = None ) -> tuple[int, int, int]: if grid_shape is None: grid_shape = (100, 100, 100) diff --git a/yt/frontends/chombo/io.py b/yt/frontends/chombo/io.py index 288761df702..7cadb72250a 100644 --- a/yt/frontends/chombo/io.py +++ b/yt/frontends/chombo/io.py @@ -1,5 +1,4 @@ import re -import sys import numpy as np @@ -7,9 +6,6 @@ from yt.utilities.io_handler import BaseIOHandler from yt.utilities.logger import ytLogger as mylog -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class IOHandlerChomboHDF5(BaseIOHandler): _dataset_type = "chombo_hdf5" diff --git a/yt/frontends/enzo/answer_testing_support.py b/yt/frontends/enzo/answer_testing_support.py index bba14f7db13..65730e64b3c 100644 --- a/yt/frontends/enzo/answer_testing_support.py +++ b/yt/frontends/enzo/answer_testing_support.py @@ -1,5 +1,4 @@ import os -import sys from functools import wraps import numpy as np @@ -16,9 +15,6 @@ temp_cwd, ) -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class AssertWrapper: """ diff --git a/yt/frontends/enzo/data_structures.py b/yt/frontends/enzo/data_structures.py index ec28a10c54a..acb7ea0c9f6 100644 --- a/yt/frontends/enzo/data_structures.py +++ b/yt/frontends/enzo/data_structures.py @@ -1,7 +1,6 @@ import os import re import string -import sys import time import weakref from collections import defaultdict @@ -22,9 +21,6 @@ from .fields import EnzoFieldInfo -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class EnzoGrid(AMRGridPatch): """ diff --git a/yt/frontends/enzo_e/misc.py b/yt/frontends/enzo_e/misc.py index c95de312cb3..9bb0868ecf3 100644 --- a/yt/frontends/enzo_e/misc.py +++ b/yt/frontends/enzo_e/misc.py @@ -1,11 +1,6 @@ -import sys - import numpy as np from more_itertools import always_iterable -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def bdecode(block): """ diff --git a/yt/frontends/exodus_ii/data_structures.py b/yt/frontends/exodus_ii/data_structures.py index 7ff0846557b..98b28b60d03 100644 --- a/yt/frontends/exodus_ii/data_structures.py +++ b/yt/frontends/exodus_ii/data_structures.py @@ -1,5 +1,3 @@ -import sys - import numpy as np from yt.data_objects.index_subobjects.unstructured_mesh import UnstructuredMesh @@ -13,9 +11,6 @@ from .fields import ExodusIIFieldInfo from .util import get_num_pseudo_dims, load_info_records, sanitize_string -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class ExodusIIUnstructuredMesh(UnstructuredMesh): _index_offset = 1 diff --git a/yt/frontends/exodus_ii/io.py b/yt/frontends/exodus_ii/io.py index ce8b32210a6..b4a560bbd67 100644 --- a/yt/frontends/exodus_ii/io.py +++ b/yt/frontends/exodus_ii/io.py @@ -1,13 +1,8 @@ -import sys - import numpy as np from yt.utilities.file_handler import NetCDF4FileHandler from yt.utilities.io_handler import BaseIOHandler -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class IOHandlerExodusII(BaseIOHandler): _particle_reader = False diff --git a/yt/frontends/flash/data_structures.py b/yt/frontends/flash/data_structures.py index 6456e229840..4a1a82f5330 100644 --- a/yt/frontends/flash/data_structures.py +++ b/yt/frontends/flash/data_structures.py @@ -1,5 +1,4 @@ import os -import sys import weakref import numpy as np @@ -16,9 +15,6 @@ from .fields import FLASHFieldInfo -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class FLASHGrid(AMRGridPatch): _id_offset = 1 diff --git a/yt/frontends/gadget/io.py b/yt/frontends/gadget/io.py index cc10d34842f..38c367e035c 100644 --- a/yt/frontends/gadget/io.py +++ b/yt/frontends/gadget/io.py @@ -1,5 +1,4 @@ import os -import sys from collections import defaultdict from functools import cached_property @@ -13,9 +12,6 @@ from .definitions import SNAP_FORMAT_2_OFFSET, gadget_hdf5_ptypes -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class IOHandlerGadgetHDF5(IOHandlerSPH): _dataset_type = "gadget_hdf5" diff --git a/yt/frontends/gadget/testing.py b/yt/frontends/gadget/testing.py index f37aa01ae9a..d2b1f4858ee 100644 --- a/yt/frontends/gadget/testing.py +++ b/yt/frontends/gadget/testing.py @@ -1,14 +1,9 @@ -import sys - import numpy as np from .data_structures import GadgetBinaryHeader, GadgetDataset from .definitions import gadget_field_specs, gadget_ptype_specs from .io import IOHandlerGadgetBinary -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - vector_fields = dict(IOHandlerGadgetBinary._vector_fields) block_ids = { diff --git a/yt/frontends/halo_catalog/tests/test_outputs.py b/yt/frontends/halo_catalog/tests/test_outputs.py index 3e56217ddb7..804a580c1c5 100644 --- a/yt/frontends/halo_catalog/tests/test_outputs.py +++ b/yt/frontends/halo_catalog/tests/test_outputs.py @@ -1,5 +1,3 @@ -import sys - import numpy as np from numpy.testing import assert_array_equal, assert_equal @@ -10,9 +8,6 @@ from yt.units.yt_array import YTArray, YTQuantity from yt.utilities.answer_testing.framework import data_dir_load -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def fake_halo_catalog(data): filename = "catalog.0.h5" diff --git a/yt/frontends/nc4_cm1/data_structures.py b/yt/frontends/nc4_cm1/data_structures.py index cce40425417..d8e0b78757b 100644 --- a/yt/frontends/nc4_cm1/data_structures.py +++ b/yt/frontends/nc4_cm1/data_structures.py @@ -1,7 +1,6 @@ import os import weakref from collections import OrderedDict -from typing import Optional import numpy as np @@ -90,7 +89,7 @@ def __init__( ) self.storage_filename = storage_filename - def _setup_coordinate_handler(self, axis_order: Optional[AxisOrder]) -> None: + def _setup_coordinate_handler(self, axis_order: AxisOrder | None) -> None: # ensure correct ordering of axes so plots aren't rotated (z should always be # on the vertical axis). super()._setup_coordinate_handler(axis_order) diff --git a/yt/frontends/open_pmd/data_structures.py b/yt/frontends/open_pmd/data_structures.py index c83120bf900..7b215a866ba 100644 --- a/yt/frontends/open_pmd/data_structures.py +++ b/yt/frontends/open_pmd/data_structures.py @@ -2,7 +2,6 @@ from operator import mul from os import listdir, path from re import match -from typing import Optional import numpy as np from packaging.version import Version @@ -34,8 +33,8 @@ class OpenPMDGrid(AMRGridPatch): __slots__ = ["_level_id"] # Every particle species and mesh might have different hdf5-indices and offsets - ftypes: Optional[list[str]] = [] - ptypes: Optional[list[str]] = [] + ftypes: list[str] | None = [] + ptypes: list[str] | None = [] findex = 0 foffset = 0 pindex = 0 diff --git a/yt/frontends/ramses/data_structures.py b/yt/frontends/ramses/data_structures.py index 851cf29b886..5b811cf07b2 100644 --- a/yt/frontends/ramses/data_structures.py +++ b/yt/frontends/ramses/data_structures.py @@ -4,7 +4,6 @@ from functools import cached_property from itertools import product from pathlib import Path -from typing import Optional import numpy as np @@ -110,7 +109,7 @@ def check_standard_files(folder, iout): @staticmethod def _match_output_and_group( path: Path, - ) -> tuple[Path, Optional[Path], Optional[str]]: + ) -> tuple[Path, Path | None, str | None]: # Make sure we work with a directory of the form `output_XXXXX` for p in (path, path.parent): match = OUTPUT_DIR_RE.match(p.name) @@ -134,11 +133,11 @@ def _match_output_and_group( @classmethod def test_with_folder_name( cls, output_dir: Path - ) -> tuple[bool, Optional[Path], Optional[Path], Optional[Path]]: + ) -> tuple[bool, Path | None, Path | None, Path | None]: output_dir, group_dir, iout = cls._match_output_and_group(output_dir) ok = output_dir.is_dir() and iout is not None - info_fname: Optional[Path] + info_fname: Path | None if ok: parent_dir = group_dir or output_dir @@ -152,7 +151,7 @@ def test_with_folder_name( @classmethod def test_with_standard_file( cls, filename: Path - ) -> tuple[bool, Optional[Path], Optional[Path], Optional[Path]]: + ) -> tuple[bool, Path | None, Path | None, Path | None]: output_dir, group_dir, iout = cls._match_output_and_group(filename.parent) ok = ( filename.is_file() @@ -160,7 +159,7 @@ def test_with_standard_file( and iout is not None ) - info_fname: Optional[Path] + info_fname: Path | None if ok: parent_dir = group_dir or output_dir diff --git a/yt/frontends/ramses/field_handlers.py b/yt/frontends/ramses/field_handlers.py index 1cb1203a78a..288b1580d6a 100644 --- a/yt/frontends/ramses/field_handlers.py +++ b/yt/frontends/ramses/field_handlers.py @@ -2,7 +2,6 @@ import glob import os from functools import cached_property -from typing import Optional from yt.config import ytcfg from yt.funcs import mylog @@ -142,14 +141,14 @@ class FieldFileHandler(abc.ABC, HandlerMixin): _file_type = "field" # These properties are static properties - ftype: Optional[str] = None # The name to give to the field type - fname: Optional[str] = None # The name of the file(s) + ftype: str | None = None # The name to give to the field type + fname: str | None = None # The name of the file(s) # The attributes of the header - attrs: Optional[tuple[tuple[str, int, str], ...]] = None + attrs: tuple[tuple[str, int, str], ...] | None = None known_fields = None # A list of tuple containing the field name and its type - config_field: Optional[str] = None # Name of the config section (if any) + config_field: str | None = None # Name of the config section (if any) - file_descriptor: Optional[str] = None # The name of the file descriptor (if any) + file_descriptor: str | None = None # The name of the file descriptor (if any) # These properties are computed dynamically field_offsets = None # Mapping from field to offset in file diff --git a/yt/frontends/ramses/hilbert.py b/yt/frontends/ramses/hilbert.py index 0b9ecb32f15..5f203c8f798 100644 --- a/yt/frontends/ramses/hilbert.py +++ b/yt/frontends/ramses/hilbert.py @@ -72,7 +72,7 @@ def get_intersecting_cpus( region: YTRegion, LE: Optional["np.ndarray[Any, np.dtype[np.float64]]"] = None, dx: float = 1.0, - dx_cond: Optional[float] = None, + dx_cond: float | None = None, factor: float = 4.0, bound_keys: Optional["np.ndarray[Any, np.dtype[np.float64]]"] = None, ) -> set[int]: diff --git a/yt/frontends/ramses/particle_handlers.py b/yt/frontends/ramses/particle_handlers.py index 7cfe3ffad12..2b42186583c 100644 --- a/yt/frontends/ramses/particle_handlers.py +++ b/yt/frontends/ramses/particle_handlers.py @@ -1,8 +1,9 @@ import abc import os import struct +from collections.abc import Callable from itertools import chain, count -from typing import TYPE_CHECKING, Any, Callable, Optional +from typing import TYPE_CHECKING, Any import numpy as np @@ -53,7 +54,7 @@ class ParticleFileHandler(abc.ABC, HandlerMixin): fname: str # The name of the file descriptor (if any) - file_descriptor: Optional[str] = None + file_descriptor: str | None = None # The attributes of the header attrs: tuple[tuple[str, int, str], ...] @@ -68,7 +69,7 @@ class ParticleFileHandler(abc.ABC, HandlerMixin): ] # Name of the config section (if any) - config_field: Optional[str] = None + config_field: str | None = None ## These properties are computed dynamically # Mapping from field to offset in file diff --git a/yt/frontends/ramses/tests/test_hilbert.py b/yt/frontends/ramses/tests/test_hilbert.py index c4a04cc91e8..86219cf5e99 100644 --- a/yt/frontends/ramses/tests/test_hilbert.py +++ b/yt/frontends/ramses/tests/test_hilbert.py @@ -1,5 +1,3 @@ -import sys - import numpy as np from numpy.testing import assert_equal @@ -7,9 +5,6 @@ from yt.frontends.ramses.hilbert import get_cpu_list_cuboid, hilbert3d from yt.testing import requires_file -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def test_hilbert3d(): # 8 different cases, checked against RAMSES' own implementation diff --git a/yt/frontends/rockstar/definitions.py b/yt/frontends/rockstar/definitions.py index 578f29b77e6..21655b88060 100644 --- a/yt/frontends/rockstar/definitions.py +++ b/yt/frontends/rockstar/definitions.py @@ -1,4 +1,4 @@ -from typing import Any, Union +from typing import Any import numpy as np @@ -28,7 +28,7 @@ KNOWN_REVISIONS: list[int] = [0, 1, 2] # using typing.Any here in lieu of numpy.typing.DTypeLike (should be backported for numpy < 1.20) -HaloDataType = Union[tuple[str, Any], tuple[str, Any, tuple[int, int]]] +HaloDataType = tuple[str, Any] | tuple[str, Any, tuple[int, int]] halo_dt: list[HaloDataType] = [ ("particle_identifier", np.int64), ("particle_position_x", np.float32), diff --git a/yt/frontends/stream/data_structures.py b/yt/frontends/stream/data_structures.py index 3f077377a4a..10faa73cf6e 100644 --- a/yt/frontends/stream/data_structures.py +++ b/yt/frontends/stream/data_structures.py @@ -1,5 +1,4 @@ import os -import sys import time import uuid import weakref @@ -7,7 +6,6 @@ from functools import cached_property from itertools import chain, product, repeat from numbers import Number as numeric_type -from typing import Optional import numpy as np from more_itertools import always_iterable @@ -47,9 +45,6 @@ from .definitions import process_data, set_particle_types from .fields import StreamFieldInfo -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class StreamGrid(AMRGridPatch): """ @@ -337,7 +332,7 @@ def __init__( unit_system="cgs", default_species_fields=None, *, - axis_order: Optional[AxisOrder] = None, + axis_order: AxisOrder | None = None, ): self.fluid_types += ("stream",) self.geometry = Geometry(geometry) @@ -553,7 +548,7 @@ def __init__( unit_system="cgs", default_species_fields=None, *, - axis_order: Optional[AxisOrder] = None, + axis_order: AxisOrder | None = None, ): super().__init__( stream_handler, diff --git a/yt/frontends/stream/definitions.py b/yt/frontends/stream/definitions.py index ae0df1f87ec..b5c1b19fa0c 100644 --- a/yt/frontends/stream/definitions.py +++ b/yt/frontends/stream/definitions.py @@ -1,4 +1,3 @@ -import sys from collections import defaultdict import numpy as np @@ -14,9 +13,6 @@ from .fields import StreamFieldInfo -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def assign_particle_data(ds, pdata, bbox): """ diff --git a/yt/frontends/tipsy/data_structures.py b/yt/frontends/tipsy/data_structures.py index 7050bd4ac9d..cba6744e7d7 100644 --- a/yt/frontends/tipsy/data_structures.py +++ b/yt/frontends/tipsy/data_structures.py @@ -1,7 +1,6 @@ import glob import os import struct -import sys import numpy as np @@ -13,9 +12,6 @@ from .fields import TipsyFieldInfo -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class TipsyFile(ParticleFile): def __init__(self, ds, io, filename, file_id, range=None): diff --git a/yt/frontends/tipsy/io.py b/yt/frontends/tipsy/io.py index 044932fa586..1c9b55ba645 100644 --- a/yt/frontends/tipsy/io.py +++ b/yt/frontends/tipsy/io.py @@ -1,7 +1,6 @@ import glob import os import struct -import sys import numpy as np @@ -10,9 +9,6 @@ from yt.utilities.lib.particle_kdtree_tools import generate_smoothing_length from yt.utilities.logger import ytLogger as mylog -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class IOHandlerTipsyBinary(IOHandlerSPH): _dataset_type = "tipsy" diff --git a/yt/frontends/ytdata/data_structures.py b/yt/frontends/ytdata/data_structures.py index 46009b4a61e..17c12614662 100644 --- a/yt/frontends/ytdata/data_structures.py +++ b/yt/frontends/ytdata/data_structures.py @@ -1,5 +1,4 @@ import os -import sys import weakref from collections import defaultdict from functools import cached_property @@ -34,9 +33,6 @@ from .fields import YTDataContainerFieldInfo, YTGridFieldInfo -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - _grid_data_containers = ["arbitrary_grid", "covering_grid", "smoothed_covering_grid"] _set_attrs = {"periodicity": "_periodicity"} diff --git a/yt/funcs.py b/yt/funcs.py index fa0b89abaaf..b94d745099e 100644 --- a/yt/funcs.py +++ b/yt/funcs.py @@ -17,7 +17,7 @@ from copy import deepcopy from functools import lru_cache, wraps from numbers import Number as numeric_type -from typing import Any, Optional +from typing import Any import numpy as np from more_itertools import always_iterable, collapse, first @@ -1086,7 +1086,7 @@ def array_like_field(data, x, field): return data.ds.quan(x, units) -def _full_type_name(obj: object = None, /, *, cls: Optional[type] = None) -> str: +def _full_type_name(obj: object = None, /, *, cls: type | None = None) -> str: if cls is not None and obj is not None: raise TypeError("_full_type_name takes an object or a class, but not both") if cls is None: @@ -1224,7 +1224,7 @@ def validate_center(center): ) -def parse_center_array(center, ds, axis: Optional[int] = None): +def parse_center_array(center, ds, axis: int | None = None): known_shortnames = {"m": "max", "c": "center", "l": "left", "r": "right"} valid_single_str_values = ("center", "left", "right") valid_field_loc_str_values = ("min", "max") diff --git a/yt/geometry/coordinates/coordinate_handler.py b/yt/geometry/coordinates/coordinate_handler.py index 5cda09f4180..159c4d0e028 100644 --- a/yt/geometry/coordinates/coordinate_handler.py +++ b/yt/geometry/coordinates/coordinate_handler.py @@ -2,7 +2,7 @@ import weakref from functools import cached_property from numbers import Number -from typing import Any, Literal, Optional, overload +from typing import Any, Literal, overload import numpy as np @@ -134,7 +134,7 @@ class CoordinateHandler(abc.ABC): name: str _default_axis_order: AxisOrder - def __init__(self, ds, ordering: Optional[AxisOrder] = None): + def __init__(self, ds, ordering: AxisOrder | None = None): self.ds = weakref.proxy(ds) if ordering is not None: self.axis_order = ordering diff --git a/yt/geometry/geometry_handler.py b/yt/geometry/geometry_handler.py index 3270849ec90..c795fbf44af 100644 --- a/yt/geometry/geometry_handler.py +++ b/yt/geometry/geometry_handler.py @@ -1,7 +1,6 @@ import abc import os import weakref -from typing import Optional import numpy as np @@ -54,7 +53,7 @@ def _icoords_to_fcoords( self, icoords: np.ndarray, ires: np.ndarray, - axes: Optional[tuple[int, ...]] = None, + axes: tuple[int, ...] | None = None, ) -> tuple[np.ndarray, np.ndarray]: # What's the use of raising NotImplementedError for this, when it's an # abstract base class? Well, only *some* of the subclasses have it -- diff --git a/yt/geometry/grid_geometry_handler.py b/yt/geometry/grid_geometry_handler.py index c92cbc05263..da69dcab24a 100644 --- a/yt/geometry/grid_geometry_handler.py +++ b/yt/geometry/grid_geometry_handler.py @@ -1,7 +1,6 @@ import abc import weakref from collections import defaultdict -from typing import Optional import numpy as np @@ -452,7 +451,7 @@ def _icoords_to_fcoords( self, icoords: np.ndarray, ires: np.ndarray, - axes: Optional[tuple[int, ...]] = None, + axes: tuple[int, ...] | None = None, ) -> tuple[np.ndarray, np.ndarray]: """ Accepts icoords and ires and returns appropriate fcoords and fwidth. diff --git a/yt/geometry/oct_geometry_handler.py b/yt/geometry/oct_geometry_handler.py index cdc8ef0ba13..c5ab386898d 100644 --- a/yt/geometry/oct_geometry_handler.py +++ b/yt/geometry/oct_geometry_handler.py @@ -1,5 +1,3 @@ -from typing import Optional - import numpy as np from yt.fields.field_detector import FieldDetector @@ -123,7 +121,7 @@ def _icoords_to_fcoords( self, icoords: np.ndarray, ires: np.ndarray, - axes: Optional[tuple[int, ...]] = None, + axes: tuple[int, ...] | None = None, ) -> tuple[np.ndarray, np.ndarray]: """ Accepts icoords and ires and returns appropriate fcoords and fwidth. diff --git a/yt/geometry/tests/test_grid_container.py b/yt/geometry/tests/test_grid_container.py index 23a45725eac..f2f8f97ed91 100644 --- a/yt/geometry/tests/test_grid_container.py +++ b/yt/geometry/tests/test_grid_container.py @@ -1,14 +1,10 @@ import random -import sys import numpy as np from numpy.testing import assert_equal, assert_raises from yt.loaders import load_amr_grids -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def setup_test_ds(): """Prepare setup specific environment""" diff --git a/yt/loaders.py b/yt/loaders.py index 7fc2b6370c6..c78c49658ed 100644 --- a/yt/loaders.py +++ b/yt/loaders.py @@ -10,7 +10,7 @@ import types import warnings from pathlib import Path -from typing import TYPE_CHECKING, Any, Optional, Union, cast +from typing import TYPE_CHECKING, Any, Union, cast from urllib.parse import urlsplit import numpy as np @@ -44,9 +44,6 @@ parallel_root_only_then_broadcast, ) -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - if TYPE_CHECKING: from multiprocessing.connection import Connection @@ -55,9 +52,7 @@ # FUTURE: embedded warnings need to have their stacklevel decremented when this decorator is removed @future_positional_only({0: "fn"}, since="4.2") -def load( - fn: Union[str, "os.PathLike[str]"], *args, hint: Optional[str] = None, **kwargs -): +def load(fn: Union[str, "os.PathLike[str]"], *args, hint: str | None = None, **kwargs): """ Load a Dataset or DatasetSeries object. The data format is automatically discovered, and the exact return type is the @@ -114,10 +109,7 @@ def load( if not fn.startswith("http"): fn = str(lookup_on_disk_data(fn)) - if sys.version_info >= (3, 10): - external_frontends = entry_points(group="yt.frontends") - else: - external_frontends = entry_points().get("yt.frontends", []) + external_frontends = entry_points(group="yt.frontends") # Ensure that external frontends are loaded for entrypoint in external_frontends: @@ -192,8 +184,8 @@ def load_simulation(fn, simulation_type, find_outputs=False): def _sanitize_axis_order_args( - geometry: Union[str, tuple[str, AxisOrder]], axis_order: Optional[AxisOrder] -) -> tuple[str, Optional[AxisOrder]]: + geometry: str | tuple[str, AxisOrder], axis_order: AxisOrder | None +) -> tuple[str, AxisOrder | None]: # this entire function should be removed at the end of its deprecation cycle geometry_str: str if isinstance(geometry, tuple): @@ -225,7 +217,7 @@ def load_uniform_grid( unit_system="cgs", default_species_fields=None, *, - axis_order: Optional[AxisOrder] = None, + axis_order: AxisOrder | None = None, cell_widths=None, parameters=None, dataset_name: str = "UniformGridData", @@ -341,9 +333,7 @@ def load_uniform_grid( if number_of_particles > 0: particle_types = set_particle_types(data) # Used much further below. - pdata: dict[Union[str, FieldKey], Any] = { - "number_of_particles": number_of_particles - } + pdata: dict[str | FieldKey, Any] = {"number_of_particles": number_of_particles} for key in list(data.keys()): if len(data[key].shape) == 1 or key[0] == "io": field: FieldKey @@ -475,7 +465,7 @@ def load_amr_grids( *, parameters=None, dataset_name: str = "AMRGridData", - axis_order: Optional[AxisOrder] = None, + axis_order: AxisOrder | None = None, ): r"""Load a set of grids of data into yt as a :class:`~yt.frontends.stream.data_structures.StreamHandler`. @@ -711,7 +701,7 @@ def load_particles( data_source=None, default_species_fields=None, *, - axis_order: Optional[AxisOrder] = None, + axis_order: AxisOrder | None = None, parameters=None, dataset_name: str = "ParticleData", ): @@ -905,7 +895,7 @@ def load_hexahedral_mesh( geometry="cartesian", unit_system="cgs", *, - axis_order: Optional[AxisOrder] = None, + axis_order: AxisOrder | None = None, parameters=None, dataset_name: str = "HexahedralMeshData", ): @@ -1245,7 +1235,7 @@ def load_unstructured_mesh( geometry="cartesian", unit_system="cgs", *, - axis_order: Optional[AxisOrder] = None, + axis_order: AxisOrder | None = None, parameters=None, dataset_name: str = "UnstructuredMeshData", ): @@ -1492,7 +1482,7 @@ def flatten(l): # --- Loader for yt sample datasets --- @parallel_root_only_then_broadcast def _get_sample_data( - fn: Optional[str] = None, *, progressbar: bool = True, timeout=None, **kwargs + fn: str | None = None, *, progressbar: bool = True, timeout=None, **kwargs ): # this isolates all the filename management and downloading so that it # can be restricted to a single process if running in parallel. Returns @@ -1633,7 +1623,7 @@ def safe_extract(tar, path=".", members=None, *, numeric_owner=False): def load_sample( - fn: Optional[str] = None, *, progressbar: bool = True, timeout=None, **kwargs + fn: str | None = None, *, progressbar: bool = True, timeout=None, **kwargs ): r""" Load sample data with yt. @@ -1719,9 +1709,9 @@ def _mount_helper( # --- Loader for tar-based datasets --- def load_archive( - fn: Union[str, Path], + fn: str | Path, path: str, - ratarmount_kwa: Optional[dict] = None, + ratarmount_kwa: dict | None = None, mount_timeout: float = 1.0, *args, **kwargs, @@ -1824,11 +1814,11 @@ def del_callback(self): def load_hdf5_file( fn: Union[str, "os.PathLike[str]"], - root_node: Optional[str] = "/", - fields: Optional[list[str]] = None, - bbox: Optional[np.ndarray] = None, + root_node: str | None = "/", + fields: list[str] | None = None, + bbox: np.ndarray | None = None, nchunks: int = 0, - dataset_arguments: Optional[dict] = None, + dataset_arguments: dict | None = None, ): """ Create a (grid-based) yt dataset given the path to an hdf5 file. diff --git a/yt/testing.py b/yt/testing.py index 699d93f509a..1e116265f03 100644 --- a/yt/testing.py +++ b/yt/testing.py @@ -23,9 +23,6 @@ from yt.loaders import load from yt.units.yt_array import YTArray, YTQuantity -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - ANSWER_TEST_TAG = "answer_test" diff --git a/yt/tests/test_external_frontends.py b/yt/tests/test_external_frontends.py index 1413b846b2c..6dbe32a77db 100644 --- a/yt/tests/test_external_frontends.py +++ b/yt/tests/test_external_frontends.py @@ -1,5 +1,4 @@ import importlib.metadata -import sys import pytest @@ -35,10 +34,7 @@ def _is_valid(cls, filename, *args, **kwargs): @pytest.fixture() def mock_external_frontend(monkeypatch): def mock_entry_points(group=None): - if sys.version_info >= (3, 10): - return [MockEntryPoint] - else: - return {"yt.frontends": [MockEntryPoint]} + return [MockEntryPoint] monkeypatch.setattr(importlib.metadata, "entry_points", mock_entry_points) assert "ExtDataset" not in output_type_registry diff --git a/yt/utilities/answer_testing/framework.py b/yt/utilities/answer_testing/framework.py index 0421ef0d728..6abd1dc366d 100644 --- a/yt/utilities/answer_testing/framework.py +++ b/yt/utilities/answer_testing/framework.py @@ -15,7 +15,6 @@ import warnings import zlib from collections import defaultdict -from typing import Optional import numpy as np from matplotlib import image as mpimg @@ -47,10 +46,6 @@ profile_plotter as profile_plotter, ) -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - - mylog = logging.getLogger("nose.plugins.answer-testing") run_big_data = False @@ -887,12 +882,12 @@ def __init__( ds_fn: str, plot_field: str, plot_axis: str, - attr_name: Optional[str] = None, - attr_args: Optional[tuple] = None, - decimals: Optional[int] = 12, - plot_type: Optional[str] = "SlicePlot", - callback_id: Optional[str] = "", - callback_runners: Optional[tuple] = None, + attr_name: str | None = None, + attr_args: tuple | None = None, + decimals: int | None = 12, + plot_type: str | None = "SlicePlot", + callback_id: str | None = "", + callback_runners: tuple | None = None, ): super().__init__(ds_fn) self.plot_type = plot_type diff --git a/yt/utilities/command_line.py b/yt/utilities/command_line.py index caa32bbc50e..459406d4d0a 100644 --- a/yt/utilities/command_line.py +++ b/yt/utilities/command_line.py @@ -5,7 +5,7 @@ import pprint import sys import textwrap -from typing import Any, Optional, Union +from typing import Any import numpy as np from more_itertools import always_iterable @@ -185,12 +185,12 @@ def __init__(cls, name, b, d): class YTCommand(metaclass=YTCommandSubtype): - args: tuple[Union[str, dict[str, Any]], ...] = () - name: Optional[Union[str, list[str]]] = None + args: tuple[str | dict[str, Any], ...] = () + name: str | list[str] | None = None description: str = "" aliases = () ndatasets: int = 1 - subparser: Optional[str] = None + subparser: str | None = None @classmethod def run(cls, args): @@ -1223,7 +1223,7 @@ def load_config(self, args) -> None: local_arg_exists = hasattr(args, "local") global_arg_exists = hasattr(args, "global") - config_file: Optional[str] = None + config_file: str | None = None if getattr(args, "local", False): config_file = local_config_file elif getattr(args, "global", False): diff --git a/yt/utilities/lib/tests/test_fill_region.py b/yt/utilities/lib/tests/test_fill_region.py index 967987c0f86..29264a434d4 100644 --- a/yt/utilities/lib/tests/test_fill_region.py +++ b/yt/utilities/lib/tests/test_fill_region.py @@ -1,13 +1,8 @@ -import sys - import numpy as np from numpy.testing import assert_equal from yt.utilities.lib.misc_utilities import fill_region -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - NDIM = 32 diff --git a/yt/utilities/logger.py b/yt/utilities/logger.py index 87acf7437dd..affb38c198d 100644 --- a/yt/utilities/logger.py +++ b/yt/utilities/logger.py @@ -1,12 +1,11 @@ import logging import sys from collections.abc import Callable -from typing import Optional from yt.utilities.configure import YTConfig, configuration_callbacks -_yt_sh: Optional[logging.StreamHandler] = None -_original_emitter: Optional[Callable[[logging.LogRecord], None]] = None +_yt_sh: logging.StreamHandler | None = None +_original_emitter: Callable[[logging.LogRecord], None] | None = None def set_log_level(level): diff --git a/yt/utilities/object_registries.py b/yt/utilities/object_registries.py index 6fa31e47f3a..5a28c150a89 100644 --- a/yt/utilities/object_registries.py +++ b/yt/utilities/object_registries.py @@ -4,8 +4,6 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from typing import Union - from yt.data_objects.analyzer_objects import AnalysisTask from yt.data_objects.data_containers import YTDataContainer from yt.data_objects.derived_quantities import DerivedQuantity @@ -19,4 +17,4 @@ simulation_time_series_registry: dict[str, type["DatasetSeries"]] = {} # TODO: split into 2 registries to avoid a typing.Union -data_object_registry: dict[str, "Union[type[YTDataContainer], type[Camera]]"] = {} +data_object_registry: dict[str, "type[YTDataContainer] | type[Camera]"] = {} diff --git a/yt/utilities/on_demand_imports.py b/yt/utilities/on_demand_imports.py index 839617f4a5d..dd42d4b945d 100644 --- a/yt/utilities/on_demand_imports.py +++ b/yt/utilities/on_demand_imports.py @@ -1,7 +1,6 @@ import sys from functools import wraps from importlib.util import find_spec -from typing import Optional class NotAModule: @@ -11,7 +10,7 @@ class NotAModule: package installed. """ - def __init__(self, pkg_name, exc: Optional[BaseException] = None): + def __init__(self, pkg_name, exc: BaseException | None = None): self.pkg_name = pkg_name self._original_exception = exc error_note = ( @@ -172,7 +171,7 @@ class NotCartopy(NotAModule): for cartopy imports. """ - def __init__(self, pkg_name, exc: Optional[BaseException] = None): + def __init__(self, pkg_name, exc: BaseException | None = None): super().__init__(pkg_name, exc) if any(s in sys.version for s in ("Anaconda", "Continuum")): # the conda-based installs of cartopy don't have issues with the diff --git a/yt/utilities/sdf.py b/yt/utilities/sdf.py index 47083281f83..acf7e1a0ba6 100644 --- a/yt/utilities/sdf.py +++ b/yt/utilities/sdf.py @@ -1,5 +1,4 @@ import os -import sys from collections import UserDict from io import StringIO @@ -7,9 +6,6 @@ from yt.funcs import mylog -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def get_thingking_deps(): try: diff --git a/yt/utilities/tests/test_chemical_formulas.py b/yt/utilities/tests/test_chemical_formulas.py index 7b5b9330632..88351b6b342 100644 --- a/yt/utilities/tests/test_chemical_formulas.py +++ b/yt/utilities/tests/test_chemical_formulas.py @@ -1,13 +1,8 @@ -import sys - from numpy.testing import assert_allclose, assert_equal from yt.utilities.chemical_formulas import ChemicalFormula, compute_mu from yt.utilities.periodic_table import periodic_table -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - _molecules = ( ("H2O_p1", (("H", 2), ("O", 1)), 1), ("H2O_m1", (("H", 2), ("O", 1)), -1), diff --git a/yt/utilities/tests/test_interpolators.py b/yt/utilities/tests/test_interpolators.py index aa2fff54662..c989e832ad8 100644 --- a/yt/utilities/tests/test_interpolators.py +++ b/yt/utilities/tests/test_interpolators.py @@ -1,5 +1,3 @@ -import sys - import numpy as np from numpy.testing import assert_array_almost_equal, assert_array_equal @@ -7,9 +5,6 @@ from yt.testing import fake_random_ds from yt.utilities.lib.interpolators import ghost_zone_interpolate -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def test_linear_interpolator_1d(): random_data = np.random.random(64) diff --git a/yt/visualization/_commons.py b/yt/visualization/_commons.py index 3deaa5bfc8a..85f478669c9 100644 --- a/yt/visualization/_commons.py +++ b/yt/visualization/_commons.py @@ -1,8 +1,7 @@ import os -import sys import warnings from functools import wraps -from typing import TYPE_CHECKING, Optional, TypeVar +from typing import TYPE_CHECKING, TypeVar import matplotlib as mpl from matplotlib.ticker import SymmetricalLogLocator @@ -10,9 +9,6 @@ from yt.config import ytcfg -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - if TYPE_CHECKING: from matplotlib.backend_bases import FigureCanvasBase @@ -68,7 +64,7 @@ def get_canvas_class(suffix: str) -> type["FigureCanvasBase"]: ) -def validate_image_name(filename, suffix: Optional[str] = None) -> str: +def validate_image_name(filename, suffix: str | None = None) -> str: """ Build a valid image filename with a specified extension (default to png). The suffix parameter is ignored if the input filename has a valid extension already. diff --git a/yt/visualization/_handlers.py b/yt/visualization/_handlers.py index fd4b381a767..b1e72fef1d0 100644 --- a/yt/visualization/_handlers.py +++ b/yt/visualization/_handlers.py @@ -1,7 +1,6 @@ -import sys import weakref from numbers import Real -from typing import TYPE_CHECKING, Any, Literal, Optional, Union +from typing import TYPE_CHECKING, Any, Literal, Optional, TypeAlias, Union import matplotlib as mpl import numpy as np @@ -13,15 +12,10 @@ from yt.config import ytcfg from yt.funcs import get_brewer_cmap, is_sequence, mylog -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: - from typing_extensions import TypeAlias - if TYPE_CHECKING: # RGBColorType, RGBAColorType and ColorType are backported from matplotlib 3.8.0 - RGBColorType = Union[tuple[float, float, float], str] - RGBAColorType = Union[ + RGBColorType = tuple[float, float, float] | str + RGBAColorType = Union[ # noqa: UP007 str, # "none" or "#RRGGBBAA"/"#RGBA" hex strings tuple[float, float, float, float], # 2 tuple (color, alpha) representations, not infinitely recursive @@ -31,10 +25,10 @@ tuple[tuple[float, float, float, float], float], ] - ColorType = Union[RGBColorType, RGBAColorType] + ColorType = RGBColorType | RGBAColorType # this type alias is unique to the present module - ColormapInput: TypeAlias = Union[Colormap, str, None] + ColormapInput: TypeAlias = Colormap | str | None class NormHandler: @@ -78,12 +72,12 @@ def __init__( data_source, *, display_units: un.Unit, - vmin: Optional[un.unyt_quantity] = None, - vmax: Optional[un.unyt_quantity] = None, - dynamic_range: Optional[float] = None, - norm_type: Optional[type[Normalize]] = None, - norm: Optional[Normalize] = None, - linthresh: Optional[float] = None, + vmin: un.unyt_quantity | None = None, + vmax: un.unyt_quantity | None = None, + dynamic_range: float | None = None, + norm_type: type[Normalize] | None = None, + norm: Normalize | None = None, + linthresh: float | None = None, ): self.data_source = weakref.proxy(data_source) self.ds = data_source.ds # should already be a weakref proxy @@ -156,9 +150,7 @@ def display_units(self) -> un.Unit: def display_units(self, newval: Unit) -> None: self._display_units = un.Unit(newval, registry=self.ds.unit_registry) - def _set_quan_attr( - self, attr: str, newval: Optional[Union[Quantity, float]] - ) -> None: + def _set_quan_attr(self, attr: str, newval: Quantity | float | None) -> None: if newval is None: setattr(self, attr, None) else: @@ -173,11 +165,11 @@ def _set_quan_attr( setattr(self, attr, quan) @property - def vmin(self) -> Optional[Union[un.unyt_quantity, Literal["min"]]]: + def vmin(self) -> un.unyt_quantity | Literal["min"] | None: return self._vmin @vmin.setter - def vmin(self, newval: Optional[Union[Quantity, float, Literal["min"]]]) -> None: + def vmin(self, newval: Quantity | float | Literal["min"] | None) -> None: self._reset_norm() if newval == "min": self._vmin = "min" @@ -185,11 +177,11 @@ def vmin(self, newval: Optional[Union[Quantity, float, Literal["min"]]]) -> None self._set_quan_attr("_vmin", newval) @property - def vmax(self) -> Optional[Union[un.unyt_quantity, Literal["max"]]]: + def vmax(self) -> un.unyt_quantity | Literal["max"] | None: return self._vmax @vmax.setter - def vmax(self, newval: Optional[Union[Quantity, float, Literal["max"]]]) -> None: + def vmax(self, newval: Quantity | float | Literal["max"] | None) -> None: self._reset_norm() if newval == "max": self._vmax = "max" @@ -197,11 +189,11 @@ def vmax(self, newval: Optional[Union[Quantity, float, Literal["max"]]]) -> None self._set_quan_attr("_vmax", newval) @property - def dynamic_range(self) -> Optional[float]: + def dynamic_range(self) -> float | None: return self._dynamic_range @dynamic_range.setter - def dynamic_range(self, newval: Optional[float]) -> None: + def dynamic_range(self, newval: float | None) -> None: if newval is None: return @@ -222,7 +214,7 @@ def dynamic_range(self, newval: Optional[float]) -> None: self._dynamic_range = newval def get_dynamic_range( - self, dvmin: Optional[float], dvmax: Optional[float] + self, dvmin: float | None, dvmax: float | None ) -> tuple[float, float]: if self.dynamic_range is None: raise RuntimeError( @@ -253,11 +245,11 @@ def get_dynamic_range( ) @property - def norm_type(self) -> Optional[type[Normalize]]: + def norm_type(self) -> type[Normalize] | None: return self._norm_type @norm_type.setter - def norm_type(self, newval: Optional[type[Normalize]]) -> None: + def norm_type(self, newval: type[Normalize] | None) -> None: if not ( newval is None or (isinstance(newval, type) and issubclass(newval, Normalize)) @@ -272,7 +264,7 @@ def norm_type(self, newval: Optional[type[Normalize]]) -> None: self._norm_type = newval @property - def norm(self) -> Optional[Normalize]: + def norm(self) -> Normalize | None: return self._norm @norm.setter @@ -286,11 +278,11 @@ def norm(self, newval: Normalize) -> None: self._norm = newval @property - def linthresh(self) -> Optional[float]: + def linthresh(self) -> float | None: return self._linthresh @linthresh.setter - def linthresh(self, newval: Optional[Union[Quantity, float]]) -> None: + def linthresh(self, newval: Quantity | float | None) -> None: self._reset_norm() self._set_quan_attr("_linthresh", newval) if self._linthresh is not None and self._linthresh <= 0: @@ -425,13 +417,13 @@ def __init__( draw_cbar: bool = True, draw_minorticks: bool = True, cmap: "ColormapInput" = None, - background_color: Optional[str] = None, + background_color: str | None = None, ): self._draw_cbar = draw_cbar self._draw_minorticks = draw_minorticks - self._cmap: Optional[Colormap] = None + self._cmap: Colormap | None = None self._set_cmap(cmap) - self._background_color: Optional[ColorType] = background_color + self._background_color: ColorType | None = background_color @property def draw_cbar(self) -> bool: diff --git a/yt/visualization/base_plot_types.py b/yt/visualization/base_plot_types.py index 377e316be91..e925a74afb8 100644 --- a/yt/visualization/base_plot_types.py +++ b/yt/visualization/base_plot_types.py @@ -2,7 +2,7 @@ import warnings from abc import ABC from io import BytesIO -from typing import TYPE_CHECKING, Optional, TypedDict, Union +from typing import TYPE_CHECKING, Optional, TypedDict import matplotlib import numpy as np @@ -247,7 +247,7 @@ def __init__( ): """Initialize ImagePlotMPL class object""" - self._transform: Optional[Transform] + self._transform: Transform | None setdefaultattr(self, "_transform", None) self.colorbar_handler = colorbar_handler @@ -272,7 +272,7 @@ def __init__( self.cax = cax def _setup_layout_constraints( - self, figure_size: Union[tuple[float, float], float], fontsize: float + self, figure_size: tuple[float, float] | float, fontsize: float ): # Setup base layout attributes # derived classes need to call this before super().__init__ diff --git a/yt/visualization/color_maps.py b/yt/visualization/color_maps.py index c4ba1d9c2ab..669fe71a79c 100644 --- a/yt/visualization/color_maps.py +++ b/yt/visualization/color_maps.py @@ -1,5 +1,3 @@ -from typing import Union - import cmyt # noqa: F401 import matplotlib as mpl import numpy as np @@ -74,7 +72,7 @@ def register_yt_colormaps_from_cmyt(): mylog.warning("cannot register colormap '%s' (naming collision)", k) -def get_colormap_lut(cmap_id: Union[tuple[str, str], str]): +def get_colormap_lut(cmap_id: tuple[str, str] | str): # "lut" stands for "lookup table". This function provides a consistent and # reusable accessor to a hidden (and by default, uninitialized) attribute # (`_lut`) in registered colormaps, from matplotlib or palettable. diff --git a/yt/visualization/fits_image.py b/yt/visualization/fits_image.py index c942033c886..d74ea55a239 100644 --- a/yt/visualization/fits_image.py +++ b/yt/visualization/fits_image.py @@ -25,9 +25,6 @@ ) from yt.visualization.volume_rendering.off_axis_projection import off_axis_projection -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class UnitfulHDU: def __init__(self, hdu): diff --git a/yt/visualization/fixed_resolution.py b/yt/visualization/fixed_resolution.py index d2da6a29e10..d108fc48ab6 100644 --- a/yt/visualization/fixed_resolution.py +++ b/yt/visualization/fixed_resolution.py @@ -1,7 +1,7 @@ import sys import weakref from functools import partial -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING import numpy as np @@ -116,7 +116,7 @@ def __init__( antialias=True, periodic=False, *, - filters: Optional[list["FixedResolutionBufferFilter"]] = None, + filters: list["FixedResolutionBufferFilter"] | None = None, ): self.data_source = data_source self.ds = data_source.ds diff --git a/yt/visualization/geo_plot_utils.py b/yt/visualization/geo_plot_utils.py index c7bd8197c0f..9de3fc80a0f 100644 --- a/yt/visualization/geo_plot_utils.py +++ b/yt/visualization/geo_plot_utils.py @@ -1,5 +1,5 @@ from types import FunctionType -from typing import Any, Optional +from typing import Any valid_transforms: dict[str, FunctionType] = {} @@ -43,7 +43,7 @@ def _func(*args, **kwargs): return _func -def get_mpl_transform(mpl_proj) -> Optional[FunctionType]: +def get_mpl_transform(mpl_proj) -> FunctionType | None: r"""This returns an instantiated transform function given a transform function name and arguments. @@ -70,7 +70,7 @@ def get_mpl_transform(mpl_proj) -> Optional[FunctionType]: # check to see if mpl_proj is a string or tuple, and construct args and # kwargs to pass to cartopy function based on that. - key: Optional[str] = None + key: str | None = None args: tuple = () kwargs: dict[str, Any] = {} if isinstance(mpl_proj, str): diff --git a/yt/visualization/line_plot.py b/yt/visualization/line_plot.py index b57a6c5018a..f63bb413d63 100644 --- a/yt/visualization/line_plot.py +++ b/yt/visualization/line_plot.py @@ -1,5 +1,4 @@ from collections import defaultdict -from typing import Optional import numpy as np from matplotlib.colors import LogNorm, Normalize, SymLogNorm @@ -163,7 +162,7 @@ def __init__( end_point, npoints, figure_size=None, - fontsize: Optional[float] = None, + fontsize: float | None = None, field_labels=None, ): """ diff --git a/yt/visualization/plot_container.py b/yt/visualization/plot_container.py index c8327a2b559..0a3304a9782 100644 --- a/yt/visualization/plot_container.py +++ b/yt/visualization/plot_container.py @@ -4,7 +4,7 @@ import warnings from collections import defaultdict from functools import wraps -from typing import Any, Final, Literal, Optional, Union +from typing import Any, Final, Literal import matplotlib from matplotlib.colors import LogNorm, Normalize, SymLogNorm @@ -114,13 +114,13 @@ class PlotContainer(abc.ABC): """A container for generic plots""" _plot_dict_type: type[PlotDictionary] = PlotDictionary - _plot_type: Optional[str] = None + _plot_type: str | None = None _plot_valid = False _default_figure_size = tuple(matplotlib.rcParams["figure.figsize"]) _default_font_size = 14.0 - def __init__(self, data_source, figure_size=None, fontsize: Optional[float] = None): + def __init__(self, data_source, figure_size=None, fontsize: float | None = None): from matplotlib.font_manager import FontProperties self.data_source = data_source @@ -145,10 +145,10 @@ def __init__(self, data_source, figure_size=None, fontsize: Optional[float] = No def set_log( self, field, - log: Optional[bool] = None, + log: bool | None = None, *, - linthresh: Optional[Union[float, Quantity, Literal["auto"]]] = None, - symlog_auto: Optional[bool] = None, # deprecated + linthresh: float | Quantity | Literal["auto"] | None = None, + symlog_auto: bool | None = None, # deprecated ): """set a field to log, linear, or symlog. @@ -501,9 +501,9 @@ def set_figure_size(self, size): @validate_plot def save( self, - name: Optional[Union[str, list[str], tuple[str, ...]]] = None, - suffix: Optional[str] = None, - mpl_kwargs: Optional[dict[str, Any]] = None, + name: str | list[str] | tuple[str, ...] | None = None, + suffix: str | None = None, + mpl_kwargs: dict[str, Any] | None = None, ): """saves the plot to disk. @@ -980,9 +980,9 @@ def set_background_color(self, field, color=None): def set_zlim( self, field, - zmin: Union[float, Quantity, Literal["min"], Unset] = UNSET, - zmax: Union[float, Quantity, Literal["max"], Unset] = UNSET, - dynamic_range: Optional[float] = None, + zmin: float | Quantity | Literal["min"] | Unset = UNSET, + zmax: float | Quantity | Literal["max"] | Unset = UNSET, + dynamic_range: float | None = None, ): """set the scale of the colormap diff --git a/yt/visualization/plot_modifications.py b/yt/visualization/plot_modifications.py index 1b4ced9e318..55ffc6e56a9 100644 --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -5,7 +5,7 @@ from abc import ABC, abstractmethod from functools import update_wrapper from numbers import Integral, Number -from typing import Any, Optional, Union +from typing import Any, TypeGuard import matplotlib import numpy as np @@ -46,13 +46,6 @@ from yt.visualization.image_writer import apply_colormap from yt.visualization.plot_window import PWViewerMPL -if sys.version_info >= (3, 10): - from typing import TypeGuard -else: - from typing_extensions import TypeGuard - - from yt._maintenance.backports import zip - if sys.version_info >= (3, 11): from typing import assert_never else: @@ -87,7 +80,7 @@ class PlotCallback(ABC): # "figure" this is disregarded. If "force" is included in the tuple, it # will *not* check whether or not the coord_system is in axis or figure, # and will only look at the geometries. - _supported_geometries: Optional[tuple[str, ...]] = None + _supported_geometries: tuple[str, ...] | None = None _incompatible_plot_types: tuple[str, ...] = () def __init_subclass__(cls, *args, **kwargs): @@ -440,7 +433,7 @@ class VelocityCallback(PlotCallback): def __init__( self, - factor: Union[tuple[int, int], int] = 16, + factor: tuple[int, int] | int = 16, *, scale=None, scale_units=None, @@ -583,7 +576,7 @@ class MagFieldCallback(PlotCallback): def __init__( self, - factor: Union[tuple[int, int], int] = 16, + factor: tuple[int, int] | int = 16, *, scale=None, scale_units=None, @@ -697,7 +690,7 @@ def __init__( field_y, field_c=None, *, - factor: Union[tuple[int, int], int] = 16, + factor: tuple[int, int] | int = 16, scale=None, scale_units=None, normalize=False, @@ -836,7 +829,7 @@ def __init__( field_y, field_c=None, *, - factor: Union[tuple[int, int], int] = 16, + factor: tuple[int, int] | int = 16, scale=None, scale_units=None, normalize=False, @@ -940,14 +933,14 @@ def __init__( field: AnyFieldKey, levels: int = 5, *, - factor: Union[tuple[int, int], int] = 4, - clim: Optional[tuple[float, float]] = None, + factor: tuple[int, int] | int = 4, + clim: tuple[float, float] | None = None, label: bool = False, - take_log: Optional[bool] = None, - data_source: Optional[YTDataContainer] = None, - plot_args: Optional[dict[str, Any]] = None, - text_args: Optional[dict[str, Any]] = None, - ncont: Optional[int] = None, # deprecated + take_log: bool | None = None, + data_source: YTDataContainer | None = None, + plot_args: dict[str, Any] | None = None, + text_args: dict[str, Any] | None = None, + ncont: int | None = None, # deprecated ) -> None: if ncont is not None: issue_deprecation_warning( @@ -1052,13 +1045,13 @@ def __call__(self, plot) -> None: if take_log: zi = np.log10(zi) - clim: Optional[tuple[float, float]] + clim: tuple[float, float] | None if take_log and self.clim is not None: clim = np.log10(self.clim[0]), np.log10(self.clim[1]) else: clim = self.clim - levels: Union[np.ndarray, int] + levels: np.ndarray | int if clim is not None: levels = np.linspace(clim[0], clim[1], self.levels) else: @@ -1317,11 +1310,11 @@ def __init__( field_x: AnyFieldKey, field_y: AnyFieldKey, *, - linewidth: Union[float, AnyFieldKey] = 1.0, + linewidth: float | AnyFieldKey = 1.0, linewidth_upscaling: float = 1.0, - color: Optional[Union[_ColorType, FieldKey]] = None, - color_threshold: Union[float, unyt_quantity] = float("-inf"), - factor: Union[tuple[int, int], int] = 16, + color: _ColorType | FieldKey | None = None, + color_threshold: float | unyt_quantity = float("-inf"), + factor: tuple[int, int] | int = 16, field_color=None, # deprecated display_threshold=None, # deprecated plot_args=None, # deprecated @@ -1529,7 +1522,7 @@ def __init__( p2, *, coord_system="data", - plot_args: Optional[dict[str, Any]] = None, + plot_args: dict[str, Any] | None = None, **kwargs, ): self.p1 = p1 @@ -1810,7 +1803,7 @@ def __init__( head_length=0.01, starting_pos=None, coord_system="data", - plot_args: Optional[dict[str, Any]] = None, # deprecated + plot_args: dict[str, Any] | None = None, # deprecated **kwargs, ): self.pos = pos diff --git a/yt/visualization/plot_window.py b/yt/visualization/plot_window.py index c67a3c61252..41b3e3aeae8 100644 --- a/yt/visualization/plot_window.py +++ b/yt/visualization/plot_window.py @@ -2,7 +2,7 @@ import sys from collections import defaultdict from numbers import Number -from typing import Optional, Union +from typing import Union import matplotlib import numpy as np @@ -55,9 +55,6 @@ invalidate_plot, ) -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - if sys.version_info >= (3, 11): from typing import assert_never else: @@ -210,7 +207,7 @@ def __init__( fields = list(iter_fields(fields)) self.override_fields = list(set(fields).intersection(set(skip))) self.fields = [f for f in fields if f not in skip] - self._frb: Optional[FixedResolutionBuffer] = None + self._frb: FixedResolutionBuffer | None = None super().__init__(data_source, window_size, fontsize) self._set_window(bounds) # this automatically updates the data and plot @@ -327,7 +324,7 @@ def _recreate_frb(self): # At this point the frb has the valid bounds, size, aliasing, etc. if old_fields is not None: # Restore the old fields - for key, units in zip(old_fields, old_units): + for key, units in zip(old_fields, old_units, strict=False): self._frb.render(key) equiv = self._equivalencies[key] if equiv[0] is None: @@ -850,8 +847,8 @@ class PWViewerMPL(PlotWindow): """Viewer using matplotlib as a backend via the WindowPlotMPL.""" _current_field = None - _frb_generator: Optional[type[FixedResolutionBuffer]] = None - _plot_type: Optional[str] = None + _frb_generator: type[FixedResolutionBuffer] | None = None + _plot_type: str | None = None def __init__(self, *args, **kwargs) -> None: if self._frb_generator is None: @@ -1245,7 +1242,7 @@ def setup_callbacks(self): ) @invalidate_plot - def clear_annotations(self, index: Optional[int] = None): + def clear_annotations(self, index: int | None = None): """ Clear callbacks from the plot. If index is not set, clear all callbacks. If index is set, clear that index (ie 0 is the first one @@ -1380,7 +1377,7 @@ class NormalPlot: """ @staticmethod - def sanitize_normal_vector(ds, normal) -> Union[str, np.ndarray]: + def sanitize_normal_vector(ds, normal) -> str | np.ndarray: """Return the name of a cartesian axis whener possible, or a 3-element 1D ndarray of float64 in any other valid case. Fail with a descriptive error message otherwise. diff --git a/yt/visualization/profile_plotter.py b/yt/visualization/profile_plotter.py index afaecea03cc..d22244b4f9c 100644 --- a/yt/visualization/profile_plotter.py +++ b/yt/visualization/profile_plotter.py @@ -2,7 +2,7 @@ import os from collections.abc import Iterable from functools import wraps -from typing import Any, Optional, Union +from typing import Any import matplotlib import numpy as np @@ -270,9 +270,9 @@ def _get_axrect(self): @validate_plot def save( self, - name: Optional[str] = None, - suffix: Optional[str] = None, - mpl_kwargs: Optional[dict[str, Any]] = None, + name: str | None = None, + suffix: str | None = None, + mpl_kwargs: dict[str, Any] | None = None, ): r""" Saves a 1d profile plot. @@ -293,7 +293,7 @@ def save( # Mypy is hardly convinced that we have a `profiles` attribute # at this stage, so we're lasily going to deactivate it locally unique = set(self.plots.values()) - iters: Iterable[tuple[Union[int, FieldKey], PlotMPL]] + iters: Iterable[tuple[int | FieldKey, PlotMPL]] if len(unique) < len(self.plots): iters = enumerate(sorted(unique)) else: @@ -1222,9 +1222,7 @@ def annotate_text(self, xpos=0.0, ypos=0.0, text=None, **text_kwargs): return self @validate_plot - def save( - self, name: Optional[str] = None, suffix: Optional[str] = None, mpl_kwargs=None - ): + def save(self, name: str | None = None, suffix: str | None = None, mpl_kwargs=None): r""" Saves a 2d profile plot. diff --git a/yt/visualization/tests/test_offaxisprojection.py b/yt/visualization/tests/test_offaxisprojection.py index cea6c11fdc8..5ddf412d667 100644 --- a/yt/visualization/tests/test_offaxisprojection.py +++ b/yt/visualization/tests/test_offaxisprojection.py @@ -1,7 +1,6 @@ import itertools as it import os import shutil -import sys import tempfile import unittest @@ -18,9 +17,6 @@ from yt.visualization.image_writer import write_projection from yt.visualization.volume_rendering.api import off_axis_projection -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - # TODO: replace this with pytest.mark.parametrize def expand_keywords(keywords, full=False): diff --git a/yt/visualization/tests/test_particle_plot.py b/yt/visualization/tests/test_particle_plot.py index 3243dd20e80..62c7403400c 100644 --- a/yt/visualization/tests/test_particle_plot.py +++ b/yt/visualization/tests/test_particle_plot.py @@ -1,6 +1,5 @@ import os import shutil -import sys import tempfile import unittest from unittest import mock @@ -22,9 +21,6 @@ from yt.visualization.api import ParticlePhasePlot, ParticlePlot, ParticleProjectionPlot from yt.visualization.tests.test_plotwindow import ATTR_ARGS, WIDTH_SPECS -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def setup_module(): """Test specific setup.""" diff --git a/yt/visualization/tests/test_plotwindow.py b/yt/visualization/tests/test_plotwindow.py index b229dae8e4b..3306bf042b0 100644 --- a/yt/visualization/tests/test_plotwindow.py +++ b/yt/visualization/tests/test_plotwindow.py @@ -1,6 +1,5 @@ import os import shutil -import sys import tempfile import unittest from collections import OrderedDict @@ -44,9 +43,6 @@ plot_2d, ) -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def setup_module(): """Test specific setup.""" diff --git a/yt/visualization/volume_rendering/old_camera.py b/yt/visualization/volume_rendering/old_camera.py index 7e7117f7204..f8ff70abd99 100644 --- a/yt/visualization/volume_rendering/old_camera.py +++ b/yt/visualization/volume_rendering/old_camera.py @@ -1,4 +1,3 @@ -import sys from copy import deepcopy import numpy as np @@ -35,9 +34,6 @@ from .transfer_functions import ProjectionTransferFunction -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - def get_corners(le, re): return np.array( diff --git a/yt/visualization/volume_rendering/render_source.py b/yt/visualization/volume_rendering/render_source.py index 85d122fd5f1..062c417fead 100644 --- a/yt/visualization/volume_rendering/render_source.py +++ b/yt/visualization/volume_rendering/render_source.py @@ -2,7 +2,7 @@ import warnings from functools import wraps from types import ModuleType -from typing import Literal, Optional, Union +from typing import Literal import numpy as np @@ -39,7 +39,7 @@ ) from .zbuffer_array import ZBuffer -OptionalModule = Union[ModuleType, NotAModule] +OptionalModule = ModuleType | NotAModule mesh_traversal: OptionalModule = NotAModule("pyembree") mesh_construction: OptionalModule = NotAModule("pyembree") @@ -144,7 +144,7 @@ class RenderSource(ParallelAnalysisInterface, abc.ABC): """ - volume_method: Optional[str] = None + volume_method: str | None = None def __init__(self): super().__init__() diff --git a/yt/visualization/volume_rendering/scene.py b/yt/visualization/volume_rendering/scene.py index ae30153a42d..0e11fe53b18 100644 --- a/yt/visualization/volume_rendering/scene.py +++ b/yt/visualization/volume_rendering/scene.py @@ -1,6 +1,5 @@ import functools from collections import OrderedDict -from typing import Optional, Union import numpy as np @@ -271,8 +270,8 @@ def _setup_save(self, fname, render) -> str: def save( self, - fname: Optional[str] = None, - sigma_clip: Optional[float] = None, + fname: str | None = None, + sigma_clip: float | None = None, render: bool = True, ): r"""Saves a rendered image of the Scene to disk. @@ -361,15 +360,15 @@ def save( def save_annotated( self, - fname: Optional[str] = None, - label_fmt: Optional[str] = None, + fname: str | None = None, + label_fmt: str | None = None, text_annotate=None, dpi: int = 100, - sigma_clip: Optional[float] = None, + sigma_clip: float | None = None, render: bool = True, - tf_rect: Optional[list[float]] = None, + tf_rect: list[float] | None = None, *, - label_fontsize: Union[float, str] = 10, + label_fontsize: float | str = 10, ): r"""Saves the most recently rendered image of the Scene to disk, including an image of the transfer function and and user-defined diff --git a/yt/visualization/volume_rendering/transfer_functions.py b/yt/visualization/volume_rendering/transfer_functions.py index 5c0a4e58e82..ee0efa01e80 100644 --- a/yt/visualization/volume_rendering/transfer_functions.py +++ b/yt/visualization/volume_rendering/transfer_functions.py @@ -1,14 +1,9 @@ -import sys - import numpy as np from more_itertools import always_iterable from yt.funcs import mylog from yt.utilities.physical_constants import clight, hcgs, kboltz -if sys.version_info < (3, 10): - from yt._maintenance.backports import zip - class TransferFunction: r"""A transfer function governs the transmission of emission and