diff --git a/openmc/bounding_box.py b/openmc/bounding_box.py index 6e58ca8ba02..5f3d3a6cfdb 100644 --- a/openmc/bounding_box.py +++ b/openmc/bounding_box.py @@ -1,5 +1,5 @@ from __future__ import annotations -from typing import Iterable +from collections.abc import Iterable import numpy as np diff --git a/openmc/checkvalue.py b/openmc/checkvalue.py index 42df3e5efbe..4fa205b14f7 100644 --- a/openmc/checkvalue.py +++ b/openmc/checkvalue.py @@ -1,12 +1,11 @@ import copy import os -import typing # required to prevent typing.Union namespace overwriting Union from collections.abc import Iterable import numpy as np # Type for arguments that accept file paths -PathLike = typing.Union[str, os.PathLike] +PathLike = str | os.PathLike def check_type(name, value, expected_type, expected_iter_type=None, *, none_ok=False): diff --git a/openmc/data/data.py b/openmc/data/data.py index 7caf31e26ee..d94d6aaaa39 100644 --- a/openmc/data/data.py +++ b/openmc/data/data.py @@ -5,7 +5,6 @@ from pathlib import Path from math import sqrt, log from warnings import warn -from typing import Dict # Isotopic abundances from Meija J, Coplen T B, et al, "Isotopic compositions # of the elements 2013 (IUPAC Technical Report)", Pure. Appl. Chem. 88 (3), @@ -283,13 +282,13 @@ NEUTRON_MASS = 1.00866491595 # Used in atomic_mass function as a cache -_ATOMIC_MASS: Dict[str, float] = {} +_ATOMIC_MASS: dict[str, float] = {} # Regex for GNDS nuclide names (used in zam function) _GNDS_NAME_RE = re.compile(r'([A-Zn][a-z]*)(\d+)((?:_[em]\d+)?)') # Used in half_life function as a cache -_HALF_LIFE: Dict[str, float] = {} +_HALF_LIFE: dict[str, float] = {} _LOG_TWO = log(2.0) def atomic_mass(isotope): diff --git a/openmc/data/decay.py b/openmc/data/decay.py index be3dab77abf..66acb2212d8 100644 --- a/openmc/data/decay.py +++ b/openmc/data/decay.py @@ -2,7 +2,6 @@ from io import StringIO from math import log import re -from typing import Optional from warnings import warn import numpy as np @@ -579,7 +578,7 @@ def sources(self): _DECAY_PHOTON_ENERGY = {} -def decay_photon_energy(nuclide: str) -> Optional[Univariate]: +def decay_photon_energy(nuclide: str) -> Univariate | None: """Get photon energy distribution resulting from the decay of a nuclide This function relies on data stored in a depletion chain. Before calling it diff --git a/openmc/deplete/coupled_operator.py b/openmc/deplete/coupled_operator.py index acdcf467c57..17af935f4a2 100644 --- a/openmc/deplete/coupled_operator.py +++ b/openmc/deplete/coupled_operator.py @@ -10,7 +10,6 @@ import copy from warnings import warn -from typing import Optional import numpy as np from uncertainties import ufloat @@ -34,7 +33,7 @@ __all__ = ["CoupledOperator", "Operator", "OperatorResult"] -def _find_cross_sections(model: Optional[str] = None): +def _find_cross_sections(model: str | None = None): """Determine cross sections to use for depletion Parameters diff --git a/openmc/deplete/independent_operator.py b/openmc/deplete/independent_operator.py index 250b94deb42..759abde1308 100644 --- a/openmc/deplete/independent_operator.py +++ b/openmc/deplete/independent_operator.py @@ -8,7 +8,6 @@ from __future__ import annotations from collections.abc import Iterable import copy -from typing import List, Set import numpy as np from uncertainties import ufloat @@ -279,7 +278,7 @@ def _load_previous_results(self): new_res = res_obj.distribute(self.local_mats, mat_indexes) self.prev_res.append(new_res) - def _get_nuclides_with_data(self, cross_sections: List[MicroXS]) -> Set[str]: + def _get_nuclides_with_data(self, cross_sections: list[MicroXS]) -> set[str]: """Finds nuclides with cross section data""" return set(cross_sections[0].nuclides) diff --git a/openmc/deplete/microxs.py b/openmc/deplete/microxs.py index b2ae9f6c7f1..39753529b2f 100644 --- a/openmc/deplete/microxs.py +++ b/openmc/deplete/microxs.py @@ -5,8 +5,8 @@ """ from __future__ import annotations +from collections.abc import Iterable, Sequence from tempfile import TemporaryDirectory -from typing import List, Tuple, Iterable, Optional, Union, Sequence import pandas as pd import numpy as np @@ -27,7 +27,7 @@ _valid_rxns.append('damage-energy') -def _resolve_chain_file_path(chain_file: str): +def _resolve_chain_file_path(chain_file: str | None): if chain_file is None: chain_file = openmc.config.get('chain_file') if 'chain_file' not in openmc.config: @@ -41,12 +41,12 @@ def _resolve_chain_file_path(chain_file: str): def get_microxs_and_flux( model: openmc.Model, domains, - nuclides: Optional[Iterable[str]] = None, - reactions: Optional[Iterable[str]] = None, - energies: Optional[Union[Iterable[float], str]] = None, - chain_file: Optional[PathLike] = None, + nuclides: Iterable[str] | None = None, + reactions: Iterable[str] | None = None, + energies: Iterable[float] | str | None = None, + chain_file: PathLike | None = None, run_kwargs=None - ) -> Tuple[List[np.ndarray], List[MicroXS]]: + ) -> tuple[list[np.ndarray], list[MicroXS]]: """Generate a microscopic cross sections and flux from a Model .. versionadded:: 0.14.0 @@ -183,7 +183,7 @@ class MicroXS: :data:`openmc.deplete.chain.REACTIONS` """ - def __init__(self, data: np.ndarray, nuclides: List[str], reactions: List[str]): + def __init__(self, data: np.ndarray, nuclides: list[str], reactions: list[str]): # Validate inputs if data.shape[:2] != (len(nuclides), len(reactions)): raise ValueError( @@ -205,12 +205,12 @@ def __init__(self, data: np.ndarray, nuclides: List[str], reactions: List[str]): @classmethod def from_multigroup_flux( cls, - energies: Union[Sequence[float], str], + energies: Sequence[float] | str, multigroup_flux: Sequence[float], - chain_file: Optional[PathLike] = None, + chain_file: PathLike | None = None, temperature: float = 293.6, - nuclides: Optional[Sequence[str]] = None, - reactions: Optional[Sequence[str]] = None, + nuclides: Sequence[str] | None = None, + reactions: Sequence[str] | None = None, **init_kwargs: dict, ) -> MicroXS: """Generated microscopic cross sections from a known flux. diff --git a/openmc/deplete/openmc_operator.py b/openmc/deplete/openmc_operator.py index 75f0925c4e7..c0ff568bc27 100644 --- a/openmc/deplete/openmc_operator.py +++ b/openmc/deplete/openmc_operator.py @@ -7,7 +7,6 @@ from abc import abstractmethod from warnings import warn -from typing import List, Tuple, Dict import numpy as np @@ -185,7 +184,7 @@ def _differentiate_burnable_mats(self): """Assign distribmats for each burnable material""" pass - def _get_burnable_mats(self) -> Tuple[List[str], Dict[str, float], List[str]]: + def _get_burnable_mats(self) -> tuple[list[str], dict[str, float], list[str]]: """Determine depletable materials, volumes, and nuclides Returns diff --git a/openmc/deplete/reaction_rates.py b/openmc/deplete/reaction_rates.py index 4aaf829a9a5..714d9048b47 100644 --- a/openmc/deplete/reaction_rates.py +++ b/openmc/deplete/reaction_rates.py @@ -2,7 +2,6 @@ An ndarray to store reaction rates with string, integer, or slice indexing. """ -from typing import Dict import numpy as np @@ -53,9 +52,9 @@ class ReactionRates(np.ndarray): # the __array_finalize__ method (discussed here: # https://docs.scipy.org/doc/numpy/user/basics.subclassing.html) - index_mat: Dict[str, int] - index_nuc: Dict[str, int] - index_rx: Dict[str, int] + index_mat: dict[str, int] + index_nuc: dict[str, int] + index_rx: dict[str, int] def __new__(cls, local_mats, nuclides, reactions, from_results=False): # Create appropriately-sized zeroed-out ndarray diff --git a/openmc/deplete/results.py b/openmc/deplete/results.py index 2e537a1b735..f897a88422c 100644 --- a/openmc/deplete/results.py +++ b/openmc/deplete/results.py @@ -1,8 +1,7 @@ import numbers import bisect import math -import typing # required to prevent typing.Union namespace overwriting Union -from typing import Iterable, Optional, Tuple, List +from collections.abc import Iterable from warnings import warn import h5py @@ -97,11 +96,11 @@ def from_hdf5(cls, filename: PathLike): def get_activity( self, - mat: typing.Union[Material, str], + mat: Material | str, units: str = "Bq/cm3", by_nuclide: bool = False, - volume: Optional[float] = None - ) -> Tuple[np.ndarray, typing.Union[np.ndarray, List[dict]]]: + volume: float | None = None + ) -> tuple[np.ndarray, np.ndarray | list[dict]]: """Get activity of material over time. .. versionadded:: 0.14.0 @@ -152,11 +151,11 @@ def get_activity( def get_atoms( self, - mat: typing.Union[Material, str], + mat: Material | str, nuc: str, nuc_units: str = "atoms", time_units: str = "s" - ) -> Tuple[np.ndarray, np.ndarray]: + ) -> tuple[np.ndarray, np.ndarray]: """Get number of nuclides over time from a single material Parameters @@ -215,11 +214,11 @@ def get_atoms( def get_decay_heat( self, - mat: typing.Union[Material, str], + mat: Material | str, units: str = "W", by_nuclide: bool = False, - volume: Optional[float] = None - ) -> Tuple[np.ndarray, typing.Union[np.ndarray, List[dict]]]: + volume: float | None = None + ) -> tuple[np.ndarray, np.ndarray | list[dict]]: """Get decay heat of material over time. .. versionadded:: 0.14.0 @@ -242,7 +241,7 @@ def get_decay_heat( ------- times : numpy.ndarray Array of times in [s] - decay_heat : numpy.ndarray or List[dict] + decay_heat : numpy.ndarray or list[dict] Array of total decay heat values if by_nuclide = False (default) or list of dictionaries of decay heat values by nuclide if by_nuclide = True. @@ -270,11 +269,11 @@ def get_decay_heat( return times, decay_heat def get_mass(self, - mat: typing.Union[Material, str], + mat: Material | str, nuc: str, mass_units: str = "g", time_units: str = "s" - ) -> Tuple[np.ndarray, np.ndarray]: + ) -> tuple[np.ndarray, np.ndarray]: """Get mass of nuclides over time from a single material .. versionadded:: 0.14.0 @@ -324,10 +323,10 @@ def get_mass(self, def get_reaction_rate( self, - mat: typing.Union[Material, str], + mat: Material | str, nuc: str, rx: str - ) -> Tuple[np.ndarray, np.ndarray]: + ) -> tuple[np.ndarray, np.ndarray]: """Get reaction rate in a single material/nuclide over time Parameters @@ -364,7 +363,7 @@ def get_reaction_rate( return times, rates - def get_keff(self, time_units: str = 's') -> Tuple[np.ndarray, np.ndarray]: + def get_keff(self, time_units: str = 's') -> tuple[np.ndarray, np.ndarray]: """Evaluates the eigenvalue from a results list. .. versionadded:: 0.13.1 @@ -400,7 +399,7 @@ def get_keff(self, time_units: str = 's') -> Tuple[np.ndarray, np.ndarray]: times = _get_time_as(times, time_units) return times, eigenvalues - def get_eigenvalue(self, time_units: str = 's') -> Tuple[np.ndarray, np.ndarray]: + def get_eigenvalue(self, time_units: str = 's') -> tuple[np.ndarray, np.ndarray]: warn("The get_eigenvalue(...) function has been renamed get_keff and " "will be removed in a future version of OpenMC.", FutureWarning) return self.get_keff(time_units) @@ -526,7 +525,7 @@ def get_step_where( def export_to_materials( self, burnup_index: int, - nuc_with_data: Optional[Iterable[str]] = None, + nuc_with_data: Iterable[str] | None = None, path: PathLike = 'materials.xml' ) -> Materials: """Return openmc.Materials object based on results at a given step diff --git a/openmc/geometry.py b/openmc/geometry.py index e37a69c73d2..6cce4c18c70 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -1,6 +1,5 @@ from __future__ import annotations import os -import typing from collections import defaultdict from copy import deepcopy from collections.abc import Iterable @@ -41,7 +40,7 @@ class Geometry: def __init__( self, - root: openmc.UniverseBase | typing.Iterable[openmc.Cell] | None = None, + root: openmc.UniverseBase | Iterable[openmc.Cell] | None = None, merge_surfaces: bool = False, surface_precision: int = 10 ): @@ -267,7 +266,7 @@ def get_universe(univ_id): def from_xml( cls, path: PathLike = 'geometry.xml', - materials: typing.Optional[typing.Union[PathLike, 'openmc.Materials']] = 'materials.xml' + materials: PathLike | 'openmc.Materials' | None = 'materials.xml' ) -> Geometry: """Generate geometry from XML file @@ -316,7 +315,7 @@ def find(self, point) -> list: """ return self.root_universe.find(point) - def get_instances(self, paths) -> typing.Union[int, typing.List[int]]: + def get_instances(self, paths) -> int | list[int]: """Return the instance number(s) for a cell/material in a geometry path. The instance numbers are used as indices into distributed @@ -363,7 +362,7 @@ def get_instances(self, paths) -> typing.Union[int, typing.List[int]]: return indices if return_list else indices[0] - def get_all_cells(self) -> typing.Dict[int, openmc.Cell]: + def get_all_cells(self) -> dict[int, openmc.Cell]: """Return all cells in the geometry. Returns @@ -377,7 +376,7 @@ def get_all_cells(self) -> typing.Dict[int, openmc.Cell]: else: return {} - def get_all_universes(self) -> typing.Dict[int, openmc.Universe]: + def get_all_universes(self) -> dict[int, openmc.Universe]: """Return all universes in the geometry. Returns @@ -392,7 +391,7 @@ def get_all_universes(self) -> typing.Dict[int, openmc.Universe]: universes.update(self.root_universe.get_all_universes()) return universes - def get_all_nuclides(self) -> typing.List[str]: + def get_all_nuclides(self) -> list[str]: """Return all nuclides within the geometry. Returns @@ -406,7 +405,7 @@ def get_all_nuclides(self) -> typing.List[str]: all_nuclides |= set(material.get_nuclides()) return sorted(all_nuclides) - def get_all_materials(self) -> typing.Dict[int, openmc.Material]: + def get_all_materials(self) -> dict[int, openmc.Material]: """Return all materials within the geometry. Returns @@ -421,7 +420,7 @@ def get_all_materials(self) -> typing.Dict[int, openmc.Material]: else: return {} - def get_all_material_cells(self) -> typing.Dict[int, openmc.Cell]: + def get_all_material_cells(self) -> dict[int, openmc.Cell]: """Return all cells filled by a material Returns @@ -440,7 +439,7 @@ def get_all_material_cells(self) -> typing.Dict[int, openmc.Cell]: return material_cells - def get_all_material_universes(self) -> typing.Dict[int, openmc.Universe]: + def get_all_material_universes(self) -> dict[int, openmc.Universe]: """Return all universes having at least one material-filled cell. This method can be used to find universes that have at least one cell @@ -463,7 +462,7 @@ def get_all_material_universes(self) -> typing.Dict[int, openmc.Universe]: return material_universes - def get_all_lattices(self) -> typing.Dict[int, openmc.Lattice]: + def get_all_lattices(self) -> dict[int, openmc.Lattice]: """Return all lattices defined Returns @@ -481,7 +480,7 @@ def get_all_lattices(self) -> typing.Dict[int, openmc.Lattice]: return lattices - def get_all_surfaces(self) -> typing.Dict[int, openmc.Surface]: + def get_all_surfaces(self) -> dict[int, openmc.Surface]: """ Return all surfaces used in the geometry @@ -517,7 +516,7 @@ def _get_domains_by_name(self, name, case_sensitive, matching, domain_type) -> l def get_materials_by_name( self, name, case_sensitive=False, matching=False - ) -> typing.List[openmc.Material]: + ) -> list[openmc.Material]: """Return a list of materials with matching names. Parameters @@ -540,7 +539,7 @@ def get_materials_by_name( def get_cells_by_name( self, name, case_sensitive=False, matching=False - ) -> typing.List[openmc.Cell]: + ) -> list[openmc.Cell]: """Return a list of cells with matching names. Parameters @@ -563,7 +562,7 @@ def get_cells_by_name( def get_surfaces_by_name( self, name, case_sensitive=False, matching=False - ) -> typing.List[openmc.Surface]: + ) -> list[openmc.Surface]: """Return a list of surfaces with matching names. .. versionadded:: 0.13.3 @@ -588,7 +587,7 @@ def get_surfaces_by_name( def get_cells_by_fill_name( self, name, case_sensitive=False, matching=False - ) -> typing.List[openmc.Cell]: + ) -> list[openmc.Cell]: """Return a list of cells with fills with matching names. Parameters @@ -635,7 +634,7 @@ def get_cells_by_fill_name( def get_universes_by_name( self, name, case_sensitive=False, matching=False - ) -> typing.List[openmc.Universe]: + ) -> list[openmc.Universe]: """Return a list of universes with matching names. Parameters @@ -658,7 +657,7 @@ def get_universes_by_name( def get_lattices_by_name( self, name, case_sensitive=False, matching=False - ) -> typing.List[openmc.Lattice]: + ) -> list[openmc.Lattice]: """Return a list of lattices with matching names. Parameters @@ -679,7 +678,7 @@ def get_lattices_by_name( """ return self._get_domains_by_name(name, case_sensitive, matching, 'lattice') - def remove_redundant_surfaces(self) -> typing.Dict[int, openmc.Surface]: + def remove_redundant_surfaces(self) -> dict[int, openmc.Surface]: """Remove and return all of the redundant surfaces. Uses surface_precision attribute of Geometry instance for rounding and diff --git a/openmc/lib/mesh.py b/openmc/lib/mesh.py index 3546112b54d..78566d449a6 100644 --- a/openmc/lib/mesh.py +++ b/openmc/lib/mesh.py @@ -1,8 +1,7 @@ -from collections.abc import Mapping +from collections.abc import Mapping, Sequence from ctypes import (c_int, c_int32, c_char_p, c_double, POINTER, Structure, create_string_buffer, c_uint64, c_size_t) from random import getrandbits -from typing import Optional, List, Tuple, Sequence from weakref import WeakValueDictionary import numpy as np @@ -170,8 +169,8 @@ def volumes(self) -> np.ndarray: def material_volumes( self, n_samples: int = 10_000, - prn_seed: Optional[int] = None - ) -> List[List[Tuple[Material, float]]]: + prn_seed: int | None = None + ) -> list[list[tuple[Material, float]]]: """Determine volume of materials in each mesh element .. versionadded:: 0.15.0 diff --git a/openmc/material.py b/openmc/material.py index 4b871b77d60..5b958c75a68 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -5,9 +5,7 @@ from numbers import Real from pathlib import Path import re -import typing # imported separately as py3.8 requires typing.Iterable import warnings -from typing import Optional, List, Union, Dict import lxml.etree as ET import numpy as np @@ -161,11 +159,11 @@ def __repr__(self) -> str: return string @property - def name(self) -> Optional[str]: + def name(self) -> str | None: return self._name @name.setter - def name(self, name: Optional[str]): + def name(self, name: str | None): if name is not None: cv.check_type(f'name for Material ID="{self._id}"', name, str) @@ -174,17 +172,17 @@ def name(self, name: Optional[str]): self._name = '' @property - def temperature(self) -> Optional[float]: + def temperature(self) -> float | None: return self._temperature @temperature.setter - def temperature(self, temperature: Optional[Real]): + def temperature(self, temperature: Real | None): cv.check_type(f'Temperature for Material ID="{self._id}"', temperature, (Real, type(None))) self._temperature = temperature @property - def density(self) -> Optional[float]: + def density(self) -> float | None: return self._density @property @@ -202,7 +200,7 @@ def depletable(self, depletable: bool): self._depletable = depletable @property - def paths(self) -> List[str]: + def paths(self) -> list[str]: if self._paths is None: raise ValueError('Material instance paths have not been determined. ' 'Call the Geometry.determine_paths() method.') @@ -217,15 +215,15 @@ def num_instances(self) -> int: return self._num_instances @property - def nuclides(self) -> List[namedtuple]: + def nuclides(self) -> list[namedtuple]: return self._nuclides @property - def isotropic(self) -> List[str]: + def isotropic(self) -> list[str]: return self._isotropic @isotropic.setter - def isotropic(self, isotropic: typing.Iterable[str]): + def isotropic(self, isotropic: Iterable[str]): cv.check_iterable_type('Isotropic scattering nuclides', isotropic, str) self._isotropic = list(isotropic) @@ -248,7 +246,7 @@ def average_molar_mass(self) -> float: return mass / moles @property - def volume(self) -> Optional[float]: + def volume(self) -> float | None: return self._volume @volume.setter @@ -258,7 +256,7 @@ def volume(self, volume: Real): self._volume = volume @property - def ncrystal_cfg(self) -> Optional[str]: + def ncrystal_cfg(self) -> str | None: return self._ncrystal_cfg @property @@ -274,7 +272,7 @@ def fissionable_mass(self) -> float: return density*self.volume @property - def decay_photon_energy(self) -> Optional[Univariate]: + def decay_photon_energy(self) -> Univariate | None: warnings.warn( "The 'decay_photon_energy' property has been replaced by the " "get_decay_photon_energy() method and will be removed in a future " @@ -285,8 +283,8 @@ def get_decay_photon_energy( self, clip_tolerance: float = 1e-6, units: str = 'Bq', - volume: Optional[float] = None - ) -> Optional[Univariate]: + volume: float | None = None + ) -> Univariate | None: r"""Return energy distribution of decay photons from unstable nuclides. .. versionadded:: 0.14.0 @@ -471,7 +469,7 @@ def add_volume_information(self, volume_calc): else: raise ValueError(f'No volume information found for material ID={self.id}.') - def set_density(self, units: str, density: Optional[float] = None): + def set_density(self, units: str, density: float | None = None): """Set the density of the material Parameters @@ -685,10 +683,10 @@ def remove_macroscopic(self, macroscopic: str): self._macroscopic = None def add_element(self, element: str, percent: float, percent_type: str = 'ao', - enrichment: Optional[float] = None, - enrichment_target: Optional[str] = None, - enrichment_type: Optional[str] = None, - cross_sections: Optional[str] = None): + enrichment: float | None = None, + enrichment_target: str | None = None, + enrichment_type: str | None = None, + cross_sections: str | None = None): """Add a natural element to the material Parameters @@ -799,9 +797,9 @@ def add_element(self, element: str, percent: float, percent_type: str = 'ao', self.add_nuclide(*nuclide) def add_elements_from_formula(self, formula: str, percent_type: str = 'ao', - enrichment: Optional[float] = None, - enrichment_target: Optional[str] = None, - enrichment_type: Optional[str] = None): + enrichment: float | None = None, + enrichment_target: str | None = None, + enrichment_type: str | None = None): """Add a elements from a chemical formula to the material. .. versionadded:: 0.12 @@ -930,7 +928,7 @@ def add_s_alpha_beta(self, name: str, fraction: float = 1.0): def make_isotropic_in_lab(self): self.isotropic = [x.name for x in self._nuclides] - def get_elements(self) -> List[str]: + def get_elements(self) -> list[str]: """Returns all elements in the material .. versionadded:: 0.12 @@ -944,7 +942,7 @@ def get_elements(self) -> List[str]: return sorted({re.split(r'(\d+)', i)[0] for i in self.get_nuclides()}) - def get_nuclides(self, element: Optional[str] = None) -> List[str]: + def get_nuclides(self, element: str | None = None) -> list[str]: """Returns a list of all nuclides in the material, if the element argument is specified then just nuclides of that element are returned. @@ -974,7 +972,7 @@ def get_nuclides(self, element: Optional[str] = None) -> List[str]: return matching_nuclides - def get_nuclide_densities(self) -> Dict[str, tuple]: + def get_nuclide_densities(self) -> dict[str, tuple]: """Returns all nuclides in the material and their densities Returns @@ -992,7 +990,7 @@ def get_nuclide_densities(self) -> Dict[str, tuple]: return nuclides - def get_nuclide_atom_densities(self, nuclide: Optional[str] = None) -> Dict[str, float]: + def get_nuclide_atom_densities(self, nuclide: str | None = None) -> dict[str, float]: """Returns one or all nuclides in the material and their atomic densities in units of atom/b-cm @@ -1078,7 +1076,7 @@ def get_nuclide_atom_densities(self, nuclide: Optional[str] = None) -> Dict[str, return nuclides def get_activity(self, units: str = 'Bq/cm3', by_nuclide: bool = False, - volume: Optional[float] = None) -> Union[Dict[str, float], float]: + volume: float | None = None) -> dict[str, float] | float: """Returns the activity of the material or for each nuclide in the material in units of [Bq], [Bq/g] or [Bq/cm3]. @@ -1101,7 +1099,7 @@ def get_activity(self, units: str = 'Bq/cm3', by_nuclide: bool = False, Returns ------- - typing.Union[dict, float] + Union[dict, float] If by_nuclide is True then a dictionary whose keys are nuclide names and values are activity is returned. Otherwise the activity of the material is returned as a float. @@ -1125,7 +1123,7 @@ def get_activity(self, units: str = 'Bq/cm3', by_nuclide: bool = False, return activity if by_nuclide else sum(activity.values()) def get_decay_heat(self, units: str = 'W', by_nuclide: bool = False, - volume: Optional[float] = None) -> Union[Dict[str, float], float]: + volume: float | None = None) -> dict[str, float] | float: """Returns the decay heat of the material or for each nuclide in the material in units of [W], [W/g] or [W/cm3]. @@ -1173,7 +1171,7 @@ def get_decay_heat(self, units: str = 'W', by_nuclide: bool = False, return decayheat if by_nuclide else sum(decayheat.values()) - def get_nuclide_atoms(self, volume: Optional[float] = None) -> Dict[str, float]: + def get_nuclide_atoms(self, volume: float | None = None) -> dict[str, float]: """Return number of atoms of each nuclide in the material .. versionadded:: 0.13.1 @@ -1202,7 +1200,7 @@ def get_nuclide_atoms(self, volume: Optional[float] = None) -> Dict[str, float]: atoms[nuclide] = 1.0e24 * atom_per_bcm * volume return atoms - def get_mass_density(self, nuclide: Optional[str] = None) -> float: + def get_mass_density(self, nuclide: str | None = None) -> float: """Return mass density of one or all nuclides Parameters @@ -1224,7 +1222,7 @@ def get_mass_density(self, nuclide: Optional[str] = None) -> float: mass_density += density_i return mass_density - def get_mass(self, nuclide: Optional[str] = None, volume: Optional[float] = None) -> float: + def get_mass(self, nuclide: str | None = None, volume: float | None = None) -> float: """Return mass of one or all nuclides. Note that this method requires that the :attr:`Material.volume` has @@ -1254,7 +1252,7 @@ def get_mass(self, nuclide: Optional[str] = None, volume: Optional[float] = None raise ValueError("Volume must be set in order to determine mass.") return volume*self.get_mass_density(nuclide) - def clone(self, memo: Optional[dict] = None) -> Material: + def clone(self, memo: dict | None = None) -> Material: """Create a copy of this material with a new unique ID. Parameters @@ -1311,8 +1309,8 @@ def _get_macroscopic_xml(self, macroscopic: str) -> ET.Element: return xml_element def _get_nuclides_xml( - self, nuclides: typing.Iterable[NuclideTuple], - nuclides_to_ignore: Optional[typing.Iterable[str]] = None)-> List[ET.Element]: + self, nuclides: Iterable[NuclideTuple], + nuclides_to_ignore: Iterable[str] | None = None)-> list[ET.Element]: xml_elements = [] # Remove any nuclides to ignore from the XML export @@ -1324,7 +1322,7 @@ def _get_nuclides_xml( return xml_elements def to_xml_element( - self, nuclides_to_ignore: Optional[typing.Iterable[str]] = None) -> ET.Element: + self, nuclides_to_ignore: Iterable[str] | None = None) -> ET.Element: """Return XML representation of the material Parameters @@ -1398,8 +1396,8 @@ def to_xml_element( return element @classmethod - def mix_materials(cls, materials, fracs: typing.Iterable[float], - percent_type: str = 'ao', name: Optional[str] = None) -> Material: + def mix_materials(cls, materials, fracs: Iterable[float], + percent_type: str = 'ao', name: str | None = None) -> Material: """Mix materials together based on atom, weight, or volume fractions .. versionadded:: 0.12 @@ -1596,7 +1594,7 @@ def __init__(self, materials=None): self += materials @property - def cross_sections(self) -> Optional[Path]: + def cross_sections(self) -> Path | None: return self._cross_sections @cross_sections.setter @@ -1686,7 +1684,7 @@ def _write_xml(self, file, header=True, level=0, spaces_per_level=2, file.write(indentation) def export_to_xml(self, path: PathLike = 'materials.xml', - nuclides_to_ignore: Optional[typing.Iterable[str]] = None): + nuclides_to_ignore: Iterable[str] | None = None): """Export material collection to an XML file. Parameters diff --git a/openmc/mesh.py b/openmc/mesh.py index ee58ec3b8c3..85af6a009c9 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -1,14 +1,12 @@ from __future__ import annotations -import typing import warnings from abc import ABC, abstractmethod -from collections.abc import Iterable +from collections.abc import Iterable, Sequence from functools import wraps from math import pi, sqrt, atan2 from numbers import Integral, Real from pathlib import Path import tempfile -from typing import Optional, Sequence, Tuple, List import h5py import lxml.etree as ET @@ -49,7 +47,7 @@ class MeshBase(IDManagerMixin, ABC): next_id = 1 used_ids = set() - def __init__(self, mesh_id: Optional[int] = None, name: str = ''): + def __init__(self, mesh_id: int | None = None, name: str = ''): # Initialize Mesh class attributes self.id = mesh_id self.name = name @@ -151,10 +149,10 @@ def get_homogenized_materials( self, model: openmc.Model, n_samples: int = 10_000, - prn_seed: Optional[int] = None, + prn_seed: int | None = None, include_void: bool = True, **kwargs - ) -> List[openmc.Material]: + ) -> list[openmc.Material]: """Generate homogenized materials over each element in a mesh. .. versionadded:: 0.15.0 @@ -393,7 +391,7 @@ def num_mesh_cells(self): def write_data_to_vtk(self, filename: PathLike, - datasets: Optional[dict] = None, + datasets: dict | None = None, volume_normalization: bool = True, curvilinear: bool = False): """Creates a VTK object of the mesh @@ -642,7 +640,7 @@ class RegularMesh(StructuredMesh): """ - def __init__(self, mesh_id: Optional[int] = None, name: str = ''): + def __init__(self, mesh_id: int | None = None, name: str = ''): super().__init__(mesh_id, name) self._dimension = None @@ -655,7 +653,7 @@ def dimension(self): return tuple(self._dimension) @dimension.setter - def dimension(self, dimension: typing.Iterable[int]): + def dimension(self, dimension: Iterable[int]): cv.check_type('mesh dimension', dimension, Iterable, Integral) cv.check_length('mesh dimension', dimension, 1, 3) self._dimension = dimension @@ -672,7 +670,7 @@ def lower_left(self): return self._lower_left @lower_left.setter - def lower_left(self, lower_left: typing.Iterable[Real]): + def lower_left(self, lower_left: Iterable[Real]): cv.check_type('mesh lower_left', lower_left, Iterable, Real) cv.check_length('mesh lower_left', lower_left, 1, 3) self._lower_left = lower_left @@ -692,7 +690,7 @@ def upper_right(self): return [l + w * d for l, w, d in zip(ls, ws, dims)] @upper_right.setter - def upper_right(self, upper_right: typing.Iterable[Real]): + def upper_right(self, upper_right: Iterable[Real]): cv.check_type('mesh upper_right', upper_right, Iterable, Real) cv.check_length('mesh upper_right', upper_right, 1, 3) self._upper_right = upper_right @@ -716,7 +714,7 @@ def width(self): return [(u - l) / d for u, l, d in zip(us, ls, dims)] @width.setter - def width(self, width: typing.Iterable[Real]): + def width(self, width: Iterable[Real]): cv.check_type('mesh width', width, Iterable, Real) cv.check_length('mesh width', width, 1, 3) self._width = width @@ -815,7 +813,7 @@ def from_rect_lattice( cls, lattice: 'openmc.RectLattice', division: int = 1, - mesh_id: Optional[int] = None, + mesh_id: int | None = None, name: str = '' ): """Create mesh from an existing rectangular lattice @@ -853,9 +851,9 @@ def from_rect_lattice( @classmethod def from_domain( cls, - domain: typing.Union['openmc.Cell', 'openmc.Region', 'openmc.Universe', 'openmc.Geometry'], + domain: 'openmc.Cell' | 'openmc.Region' | 'openmc.Universe' | 'openmc.Geometry', dimension: Sequence[int] = (10, 10, 10), - mesh_id: Optional[int] = None, + mesh_id: int | None = None, name: str = '' ): """Create mesh from an existing openmc cell, region, universe or @@ -962,7 +960,7 @@ def from_xml_element(cls, elem: ET.Element): return mesh - def build_cells(self, bc: Optional[str] = None): + def build_cells(self, bc: str | None = None): """Generates a lattice of universes with the same dimensionality as the mesh object. The individual cells/universes produced will not have material definitions applied and so downstream code @@ -1363,7 +1361,7 @@ def __init__( z_grid: Sequence[float], phi_grid: Sequence[float] = (0, 2*pi), origin: Sequence[float] = (0., 0., 0.), - mesh_id: Optional[int] = None, + mesh_id: int | None = None, name: str = '', ): super().__init__(mesh_id, name) @@ -1484,7 +1482,7 @@ def __repr__(self): def get_indices_at_coords( self, coords: Sequence[float] - ) -> Tuple[int, int, int]: + ) -> tuple[int, int, int]: """Finds the index of the mesh voxel at the specified x,y,z coordinates. .. versionadded:: 0.15.0 @@ -1496,7 +1494,7 @@ def get_indices_at_coords( Returns ------- - Tuple[int, int, int] + tuple[int, int, int] The r, phi, z indices """ @@ -1562,9 +1560,9 @@ def from_hdf5(cls, group: h5py.Group): @classmethod def from_domain( cls, - domain: typing.Union['openmc.Cell', 'openmc.Region', 'openmc.Universe', 'openmc.Geometry'], + domain: 'openmc.Cell' | 'openmc.Region' | 'openmc.Universe' | 'openmc.Geometry', dimension: Sequence[int] = (10, 10, 10), - mesh_id: Optional[int] = None, + mesh_id: int | None = None, phi_grid_bounds: Sequence[float] = (0.0, 2*pi), name: str = '' ): @@ -1813,7 +1811,7 @@ def __init__( phi_grid: Sequence[float] = (0, 2*pi), theta_grid: Sequence[float] = (0, pi), origin: Sequence[float] = (0., 0., 0.), - mesh_id: Optional[int] = None, + mesh_id: int | None = None, name: str = '', ): super().__init__(mesh_id, name) @@ -2139,9 +2137,9 @@ class UnstructuredMesh(MeshBase): _LINEAR_TET = 0 _LINEAR_HEX = 1 - def __init__(self, filename: PathLike, library: str, mesh_id: Optional[int] = None, + def __init__(self, filename: PathLike, library: str, mesh_id: int | None = None, name: str = '', length_multiplier: float = 1.0, - options: Optional[str] = None): + options: str | None = None): super().__init__(mesh_id, name) self.filename = filename self._volumes = None @@ -2173,11 +2171,11 @@ def library(self, lib: str): self._library = lib @property - def options(self) -> Optional[str]: + def options(self) -> str | None: return self._options @options.setter - def options(self, options: Optional[str]): + def options(self, options: str | None): cv.check_type('options', options, (str, type(None))) self._options = options @@ -2215,7 +2213,7 @@ def volumes(self): return self._volumes @volumes.setter - def volumes(self, volumes: typing.Iterable[Real]): + def volumes(self, volumes: Iterable[Real]): cv.check_type("Unstructured mesh volumes", volumes, Iterable, Real) self._volumes = volumes @@ -2353,8 +2351,8 @@ def write_vtk_mesh(self, **kwargs): def write_data_to_vtk( self, - filename: Optional[PathLike] = None, - datasets: Optional[dict] = None, + filename: PathLike | None = None, + datasets: dict | None = None, volume_normalization: bool = True ): """Map data to unstructured VTK mesh elements. diff --git a/openmc/model/model.py b/openmc/model/model.py index 2160c97e6cc..2ea579ab7df 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -6,7 +6,6 @@ from numbers import Integral from tempfile import NamedTemporaryFile import warnings -from typing import Optional, Dict import h5py import lxml.etree as ET @@ -83,7 +82,7 @@ def __init__(self, geometry=None, materials=None, settings=None, self.plots = plots @property - def geometry(self) -> Optional[openmc.Geometry]: + def geometry(self) -> openmc.Geometry | None: return self._geometry @geometry.setter @@ -92,7 +91,7 @@ def geometry(self, geometry): self._geometry = geometry @property - def materials(self) -> Optional[openmc.Materials]: + def materials(self) -> openmc.Materials | None: return self._materials @materials.setter @@ -106,7 +105,7 @@ def materials(self, materials): self._materials.append(mat) @property - def settings(self) -> Optional[openmc.Settings]: + def settings(self) -> openmc.Settings | None: return self._settings @settings.setter @@ -115,7 +114,7 @@ def settings(self, settings): self._settings = settings @property - def tallies(self) -> Optional[openmc.Tallies]: + def tallies(self) -> openmc.Tallies | None: return self._tallies @tallies.setter @@ -129,7 +128,7 @@ def tallies(self, tallies): self._tallies.append(tally) @property - def plots(self) -> Optional[openmc.Plots]: + def plots(self) -> openmc.Plots | None: return self._plots @plots.setter @@ -169,7 +168,7 @@ def _cells_by_id(self) -> dict: @property @lru_cache(maxsize=None) - def _cells_by_name(self) -> Dict[int, openmc.Cell]: + def _cells_by_name(self) -> dict[int, openmc.Cell]: # Get the names maps, but since names are not unique, store a set for # each name key. In this way when the user requests a change by a name, # the change will be applied to all of the same name. @@ -182,7 +181,7 @@ def _cells_by_name(self) -> Dict[int, openmc.Cell]: @property @lru_cache(maxsize=None) - def _materials_by_name(self) -> Dict[int, openmc.Material]: + def _materials_by_name(self) -> dict[int, openmc.Material]: if self.materials is None: mats = self.geometry.get_all_materials().values() else: diff --git a/openmc/model/surface_composite.py b/openmc/model/surface_composite.py index 2945f73b71e..29411fe4608 100644 --- a/openmc/model/surface_composite.py +++ b/openmc/model/surface_composite.py @@ -1,12 +1,11 @@ from abc import ABC, abstractmethod -from collections.abc import Iterable +from collections.abc import Iterable, Sequence from copy import copy from functools import partial from math import sqrt, pi, sin, cos, isclose from numbers import Real import warnings import operator -from typing import Sequence import numpy as np from scipy.spatial import ConvexHull, Delaunay diff --git a/openmc/plots.py b/openmc/plots.py index 0d9dca30e79..7532d9d5cb1 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -1,7 +1,6 @@ from collections.abc import Iterable, Mapping from numbers import Integral, Real from pathlib import Path -from typing import Optional import h5py import lxml.etree as ET @@ -942,7 +941,7 @@ def to_ipython_image(self, openmc_exec='openmc', cwd='.'): # Return produced image return _get_plot_image(self, cwd) - def to_vtk(self, output: Optional[PathLike] = None, + def to_vtk(self, output: PathLike | None = None, openmc_exec: str = 'openmc', cwd: str = '.'): """Render plot as an voxel image diff --git a/openmc/settings.py b/openmc/settings.py index 8076625818a..ce97f138f24 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -4,8 +4,6 @@ from math import ceil from numbers import Integral, Real from pathlib import Path -import typing # required to prevent typing.Union namespace overwriting Union -from typing import Optional import lxml.etree as ET @@ -514,7 +512,7 @@ def max_order(self) -> int: return self._max_order @max_order.setter - def max_order(self, max_order: Optional[int]): + def max_order(self, max_order: int | None): if max_order is not None: cv.check_type('maximum scattering order', max_order, Integral) cv.check_greater_than('maximum scattering order', max_order, 0, @@ -522,11 +520,11 @@ def max_order(self, max_order: Optional[int]): self._max_order = max_order @property - def source(self) -> typing.List[SourceBase]: + def source(self) -> list[SourceBase]: return self._source @source.setter - def source(self, source: typing.Union[SourceBase, typing.Iterable[SourceBase]]): + def source(self, source: SourceBase | Iterable[SourceBase]): if not isinstance(source, MutableSequence): source = [source] self._source = cv.CheckedList(SourceBase, 'source distributions', source) @@ -804,7 +802,7 @@ def temperature(self, temperature: dict): self._temperature = temperature @property - def trace(self) -> typing.Iterable: + def trace(self) -> Iterable: return self._trace @trace.setter @@ -817,11 +815,11 @@ def trace(self, trace: Iterable): self._trace = trace @property - def track(self) -> typing.Iterable[typing.Iterable[int]]: + def track(self) -> Iterable[Iterable[int]]: return self._track @track.setter - def track(self, track: typing.Iterable[typing.Iterable[int]]): + def track(self, track: Iterable[Iterable[int]]): cv.check_type('track', track, Sequence) for t in track: if len(t) != 3: @@ -904,12 +902,12 @@ def resonance_scattering(self, res: dict): self._resonance_scattering = res @property - def volume_calculations(self) -> typing.List[VolumeCalculation]: + def volume_calculations(self) -> list[VolumeCalculation]: return self._volume_calculations @volume_calculations.setter def volume_calculations( - self, vol_calcs: typing.Union[VolumeCalculation, typing.Iterable[VolumeCalculation]] + self, vol_calcs: VolumeCalculation | Iterable[VolumeCalculation] ): if not isinstance(vol_calcs, MutableSequence): vol_calcs = [vol_calcs] @@ -1003,11 +1001,11 @@ def write_initial_source(self, value: bool): self._write_initial_source = value @property - def weight_windows(self) -> typing.List[WeightWindows]: + def weight_windows(self) -> list[WeightWindows]: return self._weight_windows @weight_windows.setter - def weight_windows(self, value: typing.Union[WeightWindows, typing.Iterable[WeightWindows]]): + def weight_windows(self, value: WeightWindows | Iterable[WeightWindows]): if not isinstance(value, MutableSequence): value = [value] self._weight_windows = cv.CheckedList(WeightWindows, 'weight windows', value) @@ -1056,7 +1054,7 @@ def max_tracks(self, value: int): self._max_tracks = value @property - def weight_windows_file(self) -> Optional[PathLike]: + def weight_windows_file(self) -> PathLike | None: return self._weight_windows_file @weight_windows_file.setter @@ -1065,7 +1063,7 @@ def weight_windows_file(self, value: PathLike): self._weight_windows_file = value @property - def weight_window_generators(self) -> typing.List[WeightWindowGenerator]: + def weight_window_generators(self) -> list[WeightWindowGenerator]: return self._weight_window_generators @weight_window_generators.setter diff --git a/openmc/source.py b/openmc/source.py index 51ed74de3c6..e35e62f5fca 100644 --- a/openmc/source.py +++ b/openmc/source.py @@ -1,12 +1,10 @@ from __future__ import annotations from abc import ABC, abstractmethod -from collections.abc import Iterable +from collections.abc import Iterable, Sequence from enum import IntEnum from numbers import Real import warnings -import typing # imported separately as py3.8 requires typing.Iterable -# also required to prevent typing.Union namespace overwriting Union -from typing import Optional, Sequence, Dict, Any +from typing import Any import lxml.etree as ET import numpy as np @@ -57,8 +55,8 @@ class SourceBase(ABC): def __init__( self, - strength: Optional[float] = 1.0, - constraints: Optional[Dict[str, Any]] = None + strength: float | None = 1.0, + constraints: dict[str, Any] | None = None ): self.strength = strength self.constraints = constraints @@ -75,11 +73,11 @@ def strength(self, strength): self._strength = strength @property - def constraints(self) -> Dict[str, Any]: + def constraints(self) -> dict[str, Any]: return self._constraints @constraints.setter - def constraints(self, constraints: Optional[Dict[str, Any]]): + def constraints(self, constraints: dict[str, Any] | None): self._constraints = {} if constraints is None: return @@ -200,7 +198,7 @@ def from_xml_element(cls, elem: ET.Element, meshes=None) -> SourceBase: raise ValueError(f'Source type {source_type} is not recognized') @staticmethod - def _get_constraints(elem: ET.Element) -> Dict[str, Any]: + def _get_constraints(elem: ET.Element) -> dict[str, Any]: # Find element containing constraints constraints_elem = elem.find("constraints") elem = constraints_elem if constraints_elem is not None else elem @@ -308,14 +306,14 @@ class IndependentSource(SourceBase): def __init__( self, - space: Optional[openmc.stats.Spatial] = None, - angle: Optional[openmc.stats.UnitSphere] = None, - energy: Optional[openmc.stats.Univariate] = None, - time: Optional[openmc.stats.Univariate] = None, + space: openmc.stats.Spatial | None = None, + angle: openmc.stats.UnitSphere | None = None, + energy: openmc.stats.Univariate | None = None, + time: openmc.stats.Univariate | None = None, strength: float = 1.0, particle: str = 'neutron', - domains: Optional[Sequence[typing.Union[openmc.Cell, openmc.Material, openmc.Universe]]] = None, - constraints: Optional[Dict[str, Any]] = None + domains: Sequence[openmc.Cell | openmc.Material | openmc.Universe] | None = None, + constraints: dict[str, Any] | None = None ): if domains is not None: warnings.warn("The 'domains' arguments has been replaced by the " @@ -528,7 +526,7 @@ def __init__( self, mesh: MeshBase, sources: Sequence[SourceBase], - constraints: Optional[Dict[str, Any]] = None, + constraints: dict[str, Any] | None = None, ): super().__init__(strength=None, constraints=constraints) self.mesh = mesh @@ -702,10 +700,10 @@ class CompiledSource(SourceBase): """ def __init__( self, - library: Optional[str] = None, - parameters: Optional[str] = None, + library: str | None = None, + parameters: str | None = None, strength: float = 1.0, - constraints: Optional[Dict[str, Any]] = None + constraints: dict[str, Any] | None = None ) -> None: super().__init__(strength=strength, constraints=constraints) @@ -829,9 +827,9 @@ class FileSource(SourceBase): def __init__( self, - path: Optional[PathLike] = None, + path: PathLike | None = None, strength: float = 1.0, - constraints: Optional[Dict[str, Any]] = None + constraints: dict[str, Any] | None = None ): super().__init__(strength=strength, constraints=constraints) self._path = None @@ -966,8 +964,8 @@ class SourceParticle: """ def __init__( self, - r: typing.Iterable[float] = (0., 0., 0.), - u: typing.Iterable[float] = (0., 0., 1.), + r: Iterable[float] = (0., 0., 0.), + u: Iterable[float] = (0., 0., 1.), E: float = 1.0e6, time: float = 0.0, wgt: float = 1.0, @@ -1003,7 +1001,7 @@ def to_tuple(self) -> tuple: def write_source_file( - source_particles: typing.Iterable[SourceParticle], + source_particles: Iterable[SourceParticle], filename: PathLike, **kwargs ): """Write a source file using a collection of source particles @@ -1046,7 +1044,7 @@ def write_source_file( fh.create_dataset('source_bank', data=arr, dtype=source_dtype) -def read_source_file(filename: PathLike) -> typing.List[SourceParticle]: +def read_source_file(filename: PathLike) -> list[SourceParticle]: """Read a source file and return a list of source particles. .. versionadded:: 0.15.0 diff --git a/openmc/stats/multivariate.py b/openmc/stats/multivariate.py index ce9740ad212..06c65896f49 100644 --- a/openmc/stats/multivariate.py +++ b/openmc/stats/multivariate.py @@ -1,7 +1,6 @@ from __future__ import annotations -import typing from abc import ABC, abstractmethod -from collections.abc import Iterable +from collections.abc import Iterable, Sequence from math import cos, pi from numbers import Real from warnings import warn @@ -9,6 +8,7 @@ import lxml.etree as ET import numpy as np +import openmc import openmc.checkvalue as cv from .._xml import get_text from ..mesh import MeshBase @@ -212,7 +212,7 @@ class Monodirectional(UnitSphere): """ - def __init__(self, reference_uvw: typing.Sequence[float] = [1., 0., 0.]): + def __init__(self, reference_uvw: Sequence[float] = [1., 0., 0.]): super().__init__(reference_uvw) def to_xml_element(self): @@ -789,8 +789,8 @@ class Box(Spatial): def __init__( self, - lower_left: typing.Sequence[float], - upper_right: typing.Sequence[float], + lower_left: Sequence[float], + upper_right: Sequence[float], only_fissionable: bool = False ): self.lower_left = lower_left @@ -889,7 +889,7 @@ class Point(Spatial): """ - def __init__(self, xyz: typing.Sequence[float] = (0., 0., 0.)): + def __init__(self, xyz: Sequence[float] = (0., 0., 0.)): self.xyz = xyz @property @@ -939,9 +939,9 @@ def from_xml_element(cls, elem: ET.Element): def spherical_uniform( r_outer: float, r_inner: float = 0.0, - thetas: typing.Sequence[float] = (0., pi), - phis: typing.Sequence[float] = (0., 2*pi), - origin: typing.Sequence[float] = (0., 0., 0.) + thetas: Sequence[float] = (0., pi), + phis: Sequence[float] = (0., 2*pi), + origin: Sequence[float] = (0., 0., 0.) ): """Return a uniform spatial distribution over a spherical shell. diff --git a/openmc/stats/univariate.py b/openmc/stats/univariate.py index 4069c5a9e11..2d93b1f1b5d 100644 --- a/openmc/stats/univariate.py +++ b/openmc/stats/univariate.py @@ -1,9 +1,8 @@ from __future__ import annotations import math -import typing from abc import ABC, abstractmethod from collections import defaultdict -from collections.abc import Iterable +from collections.abc import Iterable, Sequence from copy import deepcopy from numbers import Real from warnings import warn @@ -68,7 +67,7 @@ def from_xml_element(cls, elem): return Mixture.from_xml_element(elem) @abstractmethod - def sample(n_samples: int = 1, seed: typing.Optional[int] = None): + def sample(n_samples: int = 1, seed: int | None = None): """Sample the univariate distribution Parameters @@ -210,8 +209,8 @@ def from_xml_element(cls, elem: ET.Element): @classmethod def merge( cls, - dists: typing.Sequence[Discrete], - probs: typing.Sequence[int] + dists: Sequence[Discrete], + probs: Sequence[int] ): """Merge multiple discrete distributions into a single distribution @@ -859,8 +858,8 @@ class Tabular(Univariate): def __init__( self, - x: typing.Sequence[float], - p: typing.Sequence[float], + x: Sequence[float], + p: Sequence[float], interpolation: str = 'linear-linear', ignore_negative: bool = False ): @@ -958,7 +957,7 @@ def normalize(self): """Normalize the probabilities stored on the distribution""" self._p /= self.cdf().max() - def sample(self, n_samples: int = 1, seed: typing.Optional[int] = None): + def sample(self, n_samples: int = 1, seed: int | None = None): rng = np.random.RandomState(seed) xi = rng.random(n_samples) @@ -1100,7 +1099,7 @@ class Legendre(Univariate): """ - def __init__(self, coefficients: typing.Sequence[float]): + def __init__(self, coefficients: Sequence[float]): self.coefficients = coefficients self._legendre_poly = None @@ -1156,8 +1155,8 @@ class Mixture(Univariate): def __init__( self, - probability: typing.Sequence[float], - distribution: typing.Sequence[Univariate] + probability: Sequence[float], + distribution: Sequence[Univariate] ): self.probability = probability self.distribution = distribution @@ -1319,8 +1318,8 @@ def clip(self, tolerance: float = 1e-6, inplace: bool = False) -> Mixture: def combine_distributions( - dists: typing.Sequence[Univariate], - probs: typing.Sequence[float] + dists: Sequence[Univariate], + probs: Sequence[float] ): """Combine distributions with specified probabilities diff --git a/openmc/utility_funcs.py b/openmc/utility_funcs.py index 4eb307c9303..3dff45380c1 100644 --- a/openmc/utility_funcs.py +++ b/openmc/utility_funcs.py @@ -2,12 +2,11 @@ import os from pathlib import Path from tempfile import TemporaryDirectory -from typing import Optional from .checkvalue import PathLike @contextmanager -def change_directory(working_dir: Optional[PathLike] = None, *, tmpdir: bool = False): +def change_directory(working_dir: PathLike | None = None, *, tmpdir: bool = False): """Context manager for executing in a provided working directory Parameters diff --git a/openmc/weight_windows.py b/openmc/weight_windows.py index 96f1db89282..a10fd2a6510 100644 --- a/openmc/weight_windows.py +++ b/openmc/weight_windows.py @@ -1,6 +1,6 @@ from __future__ import annotations from numbers import Real, Integral -from typing import Iterable, List, Optional, Dict, Sequence +from collections.abc import Iterable, Sequence import warnings import lxml.etree as ET @@ -110,15 +110,15 @@ def __init__( self, mesh: MeshBase, lower_ww_bounds: Iterable[float], - upper_ww_bounds: Optional[Iterable[float]] = None, - upper_bound_ratio: Optional[float] = None, - energy_bounds: Optional[Iterable[Real]] = None, + upper_ww_bounds: Iterable[float] | None = None, + upper_bound_ratio: float | None = None, + energy_bounds: Iterable[Real] | None = None, particle_type: str = 'neutron', survival_ratio: float = 3, - max_lower_bound_ratio: Optional[float] = None, + max_lower_bound_ratio: float | None = None, max_split: int = 10, weight_cutoff: float = 1.e-38, - id: Optional[int] = None + id: int | None = None ): self.mesh = mesh self.id = id @@ -353,7 +353,7 @@ def to_xml_element(self) -> ET.Element: return element @classmethod - def from_xml_element(cls, elem: ET.Element, meshes: Dict[int, MeshBase]) -> WeightWindows: + def from_xml_element(cls, elem: ET.Element, meshes: dict[int, MeshBase]) -> WeightWindows: """Generate weight window settings from an XML element Parameters @@ -407,7 +407,7 @@ def from_xml_element(cls, elem: ET.Element, meshes: Dict[int, MeshBase]) -> Weig ) @classmethod - def from_hdf5(cls, group: h5py.Group, meshes: Dict[int, MeshBase]) -> WeightWindows: + def from_hdf5(cls, group: h5py.Group, meshes: dict[int, MeshBase]) -> WeightWindows: """Create weight windows from HDF5 group Parameters @@ -457,7 +457,7 @@ def from_hdf5(cls, group: h5py.Group, meshes: Dict[int, MeshBase]) -> WeightWind ) -def wwinp_to_wws(path: PathLike) -> List[WeightWindows]: +def wwinp_to_wws(path: PathLike) -> list[WeightWindows]: """Create WeightWindows instances from a wwinp file .. versionadded:: 0.13.1 @@ -698,7 +698,7 @@ class WeightWindowGenerator: def __init__( self, mesh: openmc.MeshBase, - energy_bounds: Optional[Sequence[float]] = None, + energy_bounds: Sequence[float] | None = None, particle_type: str = 'neutron', method: str = 'magic', max_realizations: int = 1,